link

package
v0.8.67 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 19, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package link is the inter-island exchange broker — Lane 5, Phase 2 of docs/inter-island-exchange-spec.md. Cross-island is deny-all by default (containment); an info channel exists ONLY as an explicit, operator-granted, directional A→B grant on a named topic. The daemon is the only broker: there is no island↔island socket, every message flows through dejimad, and every grant/message/denial is ledgered.

This package owns only the authorization: the persisted Grant store. Delivery is NOT here — a granted cross-island message is delivered into the *recipient agent's ordinary mailbox* (internal/mailbox), stamped with daemon-controlled provenance, so there is a single durable inbox and a single audit surface. The HTTP gate in internal/api enforces "an island may only send AS itself, and only on a granted channel" — agents request, never self-approve. Action delegation (one island causing another to *act*) is the separate, harder-gated Phase 3 and is NOT here: a Phase-2 grant moves info, never actions.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ActionRequest

type ActionRequest struct {
	ID        string    `json:"id"`
	From      string    `json:"from"`                 // source island
	FromAgent string    `json:"from_agent"`           // source agent (self-reported within A)
	FromLabel string    `json:"from_label,omitempty"` // sender display label, daemon-stamped from A's roster (display-only; falls back to from_agent)
	To        string    `json:"to"`                   // destination island
	ToAgent   string    `json:"to_agent"`             // destination agent
	ToLabel   string    `json:"to_label,omitempty"`   // recipient display label, daemon-stamped from B's roster (display-only; falls back to to_agent)
	Topic     string    `json:"topic"`                // the granted channel
	Action    string    `json:"action"`               // named, typed action exposed by B
	Tier      Tier      `json:"tier,omitempty"`       // risk class (benign/mutating/destructive)
	Params    string    `json:"params,omitempty"`
	CreatedAt time.Time `json:"created_at"`
}

ActionRequest is a requested cross-island action invocation: source island From (agent FromAgent) asking destination island To (agent ToAgent) to run the named, typed Action with Params, over the granted channel Topic. It is the action-tier analog of a link message — but an action is a NAMED operation B exposed, never free text.

type Grant

type Grant struct {
	From      string    `json:"from"`
	To        string    `json:"to"`
	Topic     string    `json:"topic"`
	Actions   []string  `json:"actions,omitempty"`
	CreatedAt time.Time `json:"created_at"`
}

Grant is an operator-authorized, directional info channel from island From to island To on a named Topic. Actions is reserved for Phase 3 (the per-action allowlist); in Phase 2 a grant is info-only and Actions is empty. The grant is island→island — the target *agent* is a delivery address chosen per message, not part of the grant (the island is the security boundary the operator grants).

func (Grant) Key

func (g Grant) Key() string

Key is this grant's unique identity (from, to, topic).

type Queue

type Queue struct {
	// contains filtered or unexported fields
}

Queue holds action requests awaiting operator approval. It is IN-MEMORY by design: a daemon restart drops every pending request so nothing ever auto-executes after a restart (fail-closed); a TTL expires stale requests while the daemon runs. Concurrency-safe.

func NewQueue

func NewQueue(ttl time.Duration) *Queue

NewQueue returns an approval queue whose entries expire after ttl.

func (*Queue) Add

func (q *Queue) Add(r ActionRequest) ActionRequest

Add enqueues a pending request, assigning an ID + CreatedAt, and returns it.

func (*Queue) List

func (q *Queue) List() []ActionRequest

List returns the non-expired pending requests, oldest first, pruning expired ones as it goes.

func (*Queue) Take

func (q *Queue) Take(id string) (ActionRequest, bool)

Take removes and returns a pending request by id for approval/denial. ok is false when the id is unknown OR has expired (an expired request is never actionable — fail-closed). Expired entries are pruned on access.

type Store

type Store struct {
	Grants map[string]Grant `json:"grants"`
}

Store is the per-daemon set of link grants. Operator-only and deny-all: a channel that isn't in the store does not exist. Concurrency-safe; persisted atomically (mirrors internal/githubid).

func Load

func Load() (*Store, error)

Load returns a consistent snapshot of the store (empty when none exists yet).

func Update

func Update(fn func(*Store) error) (*Store, error)

Update runs fn against the store under a process-wide lock and persists the result atomically. Use it for every read-modify-write.

func (*Store) Allowed

func (s *Store) Allowed(from, to, topic string) (Grant, bool)

Allowed reports whether a from→to message on topic is authorized, returning the matching grant. Default-deny: no grant ⇒ (Grant{}, false).

func (*Store) Grant

func (s *Store) Grant(g Grant) Grant

Grant adds or replaces a grant (keyed by from/to/topic), stamping CreatedAt.

func (*Store) List

func (s *Store) List() []Grant

List returns every grant, sorted by from/to/topic.

func (*Store) Revoke

func (s *Store) Revoke(from, to, topic string) bool

Revoke removes a grant. Returns false when no such grant exists.

type Tier added in v0.6.0

type Tier string

Tier is the risk class of a cross-island action, the basis of the action gate's safety posture (docs/action-gate-spec.md §"Risk tiers"):

  • TierBenign — read/peek/status; safe to auto-approve by policy.
  • TierMutating — write/dispatch/build; gated (policy or human).
  • TierDestructive— delete/purge/irreversible; ALWAYS explicit human approval, never silently auto-approvable. This is the wipe-the-drive backstop.
const (
	TierBenign      Tier = "benign"
	TierMutating    Tier = "mutating"
	TierDestructive Tier = "destructive"
)

func ClassifyTier added in v0.6.0

func ClassifyTier(action string) Tier

ClassifyTier maps an action name to a risk tier, conservatively. It is a heuristic floor (a destination may later declare tiers explicitly); the safety model does not rest on it alone — the default posture is prompt-everything, so nothing auto-approves without an operator rule, and destructive is excluded from rules regardless.

func (Tier) AutoApprovable added in v0.6.0

func (t Tier) AutoApprovable() bool

AutoApprovable reports whether a policy rule may ever auto-approve this tier. Destructive never can (until a deliberately-deferred future opt-in escalation), so this is the single chokepoint enforcing that non-negotiable.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL