cli

package
v0.19.2 Latest Latest
Warning

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

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

Documentation

Overview

Real internal/cache-backed PendingMarker/CacheRemover (plan 07 Placement decision, binding): internal/cli's own P6-defined seams (adapters.go) filled with the P7 primitives that back them. internal/cache CANNOT import internal/cli (ADR-001), so these are cli-layer adapters that call internal/cache's exported functions — the mirror image of adapters.go's own LegalityAdapter/MirrorResolver pattern. cmd/a2a (lead, post-wave) wires these in place of P6's NewNoopPendingMarker/NewNoopCacheRemover.

Package cli is the OP-2xx verb surface (ADR-001 "thin frontend"): flags/ JSON in, exit codes/JSON out, zero business rules — every rule lives in a core package it calls. Each verb is a Command constructed with exactly the core dependencies it needs (rails DI); cmd/a2a is the single point that builds them with real implementations and registers them for dispatch.

This file is the shared seam every verb file in this package builds against. It is deliberately minimal: the Command contract and the injected IO streams, nothing else. Verb files (cmd_init.go, cmd_new.go, cmd_submit.go, cmd_sync.go, cmd_doctor.go, and later P7/P8 verbs) each define their own command type + constructor; they never add package-level mutable state here.

P23 (OP-222) `a2a completion <bash|zsh|fish>`: print a static shell completion script to stdout. Pure host-side act (no space, no network, no config) — the script is rendered from an injected verb inventory (see completion.go). This file's only package-level symbols are CompletionCommand + NewCompletionCommand.

OP-212 (contract lifecycle) + OP-213 (`contract verify-export`) + the `contract diff` slice of OP-221 (spec 08 T1). One `a2a contract <sub>` verb dispatching new/publish/deprecate/retire/diff/verify-export — the same uniform write funnel as cmd_lifecycle.go for every mutating sub-verb (auto-merge always on; publish/retire add an advisory PR marker only when G1/G2 apply, per this phase's plan Placement decisions); diff/verify-export are read-only, no funnel.

This file's only package-level symbols are ContractCommand + its NewContractCommand constructor and file-private, uniquely-named helpers (contract* prefix) — no shared helper, no package var, per this phase's plan Placement decision. It freely reuses cmd_lifecycle.go's own file-private helpers (lifecycleLoadEnvelope, lifecycleCheckLegality, lifecycleReadAllEvents, lifecycleFoldEvents, lifecycleMembership, lifecycleEventDoc, lifecycleArtifactPath, lifecycleDeps, ...) — both files are this SAME phase's own output (never P7's), so this is reuse, not the cross-file duplication the plan's "disjoint files" rule guards against (that rule is about the PARALLEL SIBLING, P7).

Spec 05a (contract data exchange loop) T1 CLI surface: `a2a data pack|deliver|fetch|verify`. One bare switch fanning out to sub-verbs, a single narrow operation interface as a struct field — the same shape cmd_contract.go/cmd_contract_p6.go already ship for `contract` preflight/publish/materialize/check, mirrored here per this wave's own brief ("contract is the exact shipped shape to mirror").

This file and cmd/a2a's own dataCore-shaped adapter are the two sides of one wave's seam: DataPackRequest/DataDeliverRequest/DataFetchRequest/ DataVerifyRequest/DataResult/DataOperations below are declared once here and never redeclared — cmd/a2a compiles an adapter against them, this file never reaches into internal/datapackage or internal/space to build a request itself. internal/datapackage.Document/Report are reused verbatim as DataResult's own wire shapes (never re-typed) — the same "no second wire shape" discipline every other verb in this package already follows for space.ContractPublicationResult and friends.

OP-218 basic doctor (spec 09 T1). This file's only package-level symbols are DoctorCommand + NewDoctorCommand plus its own uniquely-named, file-private helpers (doctor* prefix) — no shared helper, no package var, per this phase's plan Placement decision (avoids collision with P6/P7/P8's parallel verb files in this same package).

P25 `a2a feedback <new|validate|submit|status|triage>` (spec 25 §T1). This file's only package-level symbols are FeedbackCommand + its NewFeedbackCommand constructor + FeedbackSubcommands() — no shared helper, no package var beyond that SSOT list, mirroring cmd_contract.go's own Placement convention. Every sub-verb is dispatched by an internal switch (never registered as individual cli.Command values), same shape as ContractCommand.Run.

OP-214 `a2a html` (+ the `a2a dashboard` alias): render a self-contained, static local dashboard from the composed read surface — the graph (who depends on / exchanges with whom), inbox, contract drift, tooling, per-space health — plus a human-readable Guide. Pure read layer (§7.6): no network in the render path, no writes to any space. This file's only package-level symbols are HtmlCommand + NewHtmlCommand + NewDashboardCommand.

OP-207 `a2a inbox` (spec 07 T1). This file's only package-level symbols are InboxCommand + NewInboxCommand plus its own uniquely- named, file-private helpers (inbox* prefix) — no shared helper, no package var, per this phase's plan Placement decision (avoids collision with P6/P8's parallel verb files in this same package).

OP-201 `a2a init`, OP-202 `a2a connect`/`a2a disconnect` (spec 06 T1). This file's only package-level symbols are InitCommand/ConnectCommand/ DisconnectCommand + their NewXCommand constructors plus file-private, uniquely-named helpers (init*/connect*/disconnect* prefix) — no shared helper, no package var, per this phase's plan Placement decision (avoids collision with P7/P8/P9's parallel verb files in this package).

OP-211 generic lifecycle verbs (spec 08 T1): ack/accept/decline/start/ block/unblock/cancel/respond/verify/dispute/close/supersede/withdraw/ satisfy/approve/reject/verify-pass/verify-fail/note. Every mutating verb batches N ids into one commit/one PR, runs V2 legality locally (via internal/fold, reused — never re-derived) BEFORE the funnel, and ships through the SAME uniform write funnel (auto-merge always on; no verb passes a gate/review parameter — approve/reject add an advisory PR marker only, per this phase's plan Placement decisions).

This file's only package-level symbols are the per-verb command types (LifecycleCommand, RespondCommand, VerifyCommand, DisputeCommand, NoteCommand) + their NewXCommand constructors, the lifecycleVerbTable (Future-proofing table, §9) and file-private, uniquely-named helpers (lifecycle* prefix) — no shared helper, no package var beyond that table, per this phase's plan Placement decision (avoids collision with P7/P9's parallel verb files in this package). It never touches or imports P7's cmd_inbox/outbox/show/thread/search/statusline files, nor internal/cache.

OP-203 `a2a new`, OP-219 `a2a template list/show` (spec 06 T1). This file's only package-level symbols are NewCommand/TemplateCommand + their NewXCommand constructors plus file-private, uniquely-named helpers (new* prefix) and the newTypePrefix table — no shared helper, no package var beyond that lookup table, per this phase's plan Placement decision (avoids collision with P7/P8/P9's parallel verb files in this package).

OP-208 `a2a outbox` (spec 07 T1). This file's only package-level symbols are OutboxCommand + NewOutboxCommand plus its own uniquely- named, file-private helpers (outbox* prefix) — no shared helper, no package var, per this phase's plan Placement decision.

OP-221 `a2a search` / `a2a contracts` (spec 07 T1). This file's only package-level symbols are SearchCommand/ContractsCommand + their NewXCommand constructors plus file-private, uniquely-named helpers (search*/contracts* prefix) — no shared helper, no package var, per this phase's plan Placement decision.

The allowlist (plan 07) grants exactly six cmd_ files and does not include a dedicated cmd_contracts.go; both `search` and `contracts` are OP-221's own two clauses ("discovery over the local cache"), so this file holds both commands — the same one-file, two-command pattern cmd_submit.go already uses for ValidateCommand+SubmitCommand. `a2a contract diff` (OP-221's third clause) is P8's (contract lifecycle phase), not implemented here.

OP-209 `a2a show` (spec 07 T1). This file's only package-level symbols are ShowCommand + NewShowCommand plus its own uniquely-named, file-private helpers (show* prefix) — no shared helper, no package var, per this phase's plan Placement decision.

This is the ONE P7 verb file that imports internal/validate (the plan Placement decision, binding): internal/cache stays validate-free per ADR-001 and only supplies digest/staleness FACTS (cache.RefFact, ShowResult.SyncStale) — the V5 registry-code lookup itself happens here, mapping those facts onto the SAME codes internal/validate's V2 path already emits (REF-004/REF-008, schemas/errors/v1/registry.yaml), never a second, divergent code.

OP-skill `a2a skill install` (spec 20): materialize the a2ahub expert-skill tree (embedded in the binary) into a consumer repo so the repo's agent can read the operating manual locally and defer to `a2a` for command/validation truth. This file's only package-level symbols are SkillCommand + NewSkillCommand plus its own skill*-prefixed file-private helpers, per this package's Placement convention.

Safety contract (operator requirement 2026-07-23): install writes ONLY under its own namespace (default .a2ahub/skill/), never into .claude/, AGENTS.md, or any consumer file — so it cannot clobber an existing harness. It is idempotent on its OWN target (refresh) but REFUSES a target that holds non-a2ahub content unless --force, and every install drops a PROVENANCE.md marker (what this is, where it came from, how to refresh).

`a2a space init` — self-service space scaffolding (spec 33 §12) — and `a2a space update` — template-drift migration (spec 35). This file's only package-level symbols are SpaceCommand + its NewSpaceCommand constructor plus file-private, uniquely-named helpers (space* prefix) — no shared helper, no package var, matching cmd_contract.go's own Placement convention for this package.

OP-215 `a2a statusline` (spec 07 §7.5). This file owns the command and the detached process adapter; it has no package-level mutable state.

NO hub client symbol is imported or referenced anywhere in this file (spec 07 §8 AC row 9): cache only reports local freshness, and the CLI adapter reuses canonical `a2a sync` (v1-min scope cut, D-030). This file never constructs, imports, or wires anything hub-shaped.

OP-204 `a2a validate`, OP-205 `a2a submit`, OP-220 `a2a submit --batch`/ `--drafts` (spec 06 T1/T1.1/T1.2). This file's only package-level symbols are ValidateCommand/SubmitCommand + their NewXCommand constructors, the submitFunnel seam interface, the submitFirstTransition table, and file-private, uniquely-named helpers (submit* prefix) — no shared helper, no package var beyond that lookup table, per this phase's plan Placement decision (avoids collision with P7/P8/P9's parallel verb files in this package).

OP-206 `a2a sync` (spec 06 T1). This file's only package-level symbols are SyncCommand + NewSyncCommand — no shared helper, no package var, per this phase's plan Placement decision (avoids collision with P7/P8/P9's parallel verb files in this package).

OP-210 `a2a thread` (spec 07 T1; spec 46 §T3/§T4). This file's only package-level symbols are ThreadCommand + NewThreadCommand plus its own uniquely-named, file-private helpers (thread* prefix) — no shared helper, no package var, per this phase's plan Placement decision.

OP-217 `a2a update` (spec 19 T1). This file's only package-level symbols are UpdateCommand + NewUpdateCommand plus its own uniquely-named, file-private helpers (update* prefix / defaultUpdate* prefix) — no shared helper, no package var, per this package's established plan Placement convention (avoids collision with the other parallel verb files in this same package, e.g. cmd_doctor.go, cmd_sync.go).

This file ORCHESTRATES the shipped internal/release primitives; it never hand-sequences Download/Verify/SelfCheckVersion/Swap — release.Apply is the package's only safe entry point for that pipeline (an early audit closed exactly the exec-before-verify gap that hand-sequencing would reopen).

OP-204 `a2a validate --ci` (spec 17 T1/§8, plan 17 wave-10): the CI validation entrypoint. It runs against a SPACE-repo checkout (the CI cwd), loads the in-repo `./space.yaml` manifest, computes the changed (v3-pr) or all (v3-full-repo) `*.md` artifacts, and REUSES the existing V2 engine (validate.Engine.ValidateForSubmit) over each — mirroring the SubmitValidatorAdapter's LocalContext construction — plus a basic diff-authz check. ZERO new validation rules live here.

This file is kept separate from cmd_submit.go's ValidateCommand.Run so the existing `validate <path>` / `validate --all` paths stay untouched; ValidateCommand.Run only delegates here when `--ci` is set.

P37 wave B2 (spec 37 §2 T2/T3, AC-970.2) adds ONE more rule, still not a new validation RULE of its own: for every contract this PR touches, at merge, run the SAME `validate.CheckComputedCompatibility` core `contract publish` runs locally (internal/validate/compat.go), plus D-D's `validate.CheckContractPublishable` (POL-009). Both are exported, pure-input functions this file only CALLS — see TestValidateCIAndContractHaveNoSecondCompatCopy for the test that proves no second copy of either verdict exists in this package.

P31 `a2a whatsnew` (spec 31 T1): render the committed, embedded release-notes corpus (internal/notes over releasenotes.FS) as an agent-consumable digest — informational only, a2a never runs a `scope: space` directive itself (schemas/release-notes/v1's own description). This file's only package-level symbols are WhatsnewCommand + NewWhatsnewCommand plus its own uniquely-named, file-private helpers (whatsnew* prefix) — no shared helper, no package var, per this package's established Placement convention.

P23 (OP-222) `a2a completion`: render a static shell-completion script for bash / zsh / fish. This file holds the pure renderer — no IO, no flags — so it is exhaustively unit-testable and deterministic. The command wrapper + flag/exit handling lives in cmd_completion.go; the verb inventory (the list of top-level commands and `contract` sub-verbs) is INJECTED by cmd/a2a, which is the only place that knows buildCommands() — internal/cli never enumerates the dispatch surface itself.

Names-only by design (no per-command descriptions, no dynamic __complete callback): the drift surface is exactly the set of command NAMES, which the name-parity guards (catalog_test.go / a sibling completion parity test) already keep honest. Richer, context-aware completion is a documented V2.

validate --ci's bounded historical tree reader. Contract commands no longer call this helper: P6 routes their version resolution and exact historical reads through internal/space.

This file remains only for validate --ci until that validator receives a space-owned history adapter of its own.

Defect closed here (filed 2026-07-26): internal/cache's read model was already best-effort BY DESIGN — one malformed artifact/event file must never blind the whole space to every other document in it — but the file it dropped was silently indistinguishable from one that simply did not exist. `a2a search`, `a2a inbox`, `a2a outbox` and `a2a thread` all showed one FEWER row than the space actually held, with no word anywhere. This file is the stage-2 fix: it surfaces internal/cache's own SkippedFile report (skipped.go) to the agents calling these read verbs, OUT-OF-BAND — never on stdout.

Index

Constants

View Source
const DefaultDataPackExpiry = 168 * time.Hour

DefaultDataPackExpiry is how long a packed attempt stays fetchable when the caller does not say.

It is not zero, and that is the whole point: `expires_at` is stamped as now + this duration, and `data fetch` refuses an expired package. A zero default therefore produced a package that was expired the instant it was created — every first-time producer would have shipped one their counterpart could never fetch, and the failure would surface on the OTHER side of a long feedback cycle. A week comfortably outlives a review round without keeping a payload fetchable indefinitely.

Exported so cmd/a2a's dataCore.pack (the one production core BOTH the CLI and MCP surfaces call) can apply the SAME floor when the MCP surface omits --expires entirely — the CLI's own flag default below never lets a zero value reach the core, but MCP has no flag layer to apply a default before the request is built, so the core is the only place both surfaces share.

Variables

View Source
var CompletionShells = []string{"bash", "zsh", "fish"}

CompletionShells is the set of shells `a2a completion` can render, in the order shown in usage.

View Source
var ErrNoActorName = errors.New("cannot determine who is acting: pass --actor-name <name>, " +
	"or set A2A_ACTOR_NAME. Every artifact and event records its actor permanently, so a write " +
	"without one is refused rather than attributed to nobody (no OS user resolved either — " +
	"expected in a container or CI runner)")

ErrNoActorName is returned when no §7.4 source names the acting identity and even the OS-user fallback is empty — the CI/container case.

The message names both remedies, in the order a caller would reach for them, because the whole point of this error existing is that the schema violation it replaces named neither.

Functions

func FeedbackSubcommands added in v0.2.0

func FeedbackSubcommands() []string

FeedbackSubcommands is the SSOT list of the `a2a feedback` family's sub-verbs for surface enumeration (mirrors ContractSubcommands' role) — the lead's completion/catalog derivation reads this list. KEEP IN SYNC with Run's switch above.

func IsHelpArg added in v0.3.0

func IsHelpArg(s string) bool

IsHelpArg reports whether a command-line token is a request for help. Verbs whose FIRST argument is a sub-verb or a type name (`new <type>`, `contract <sub>`, `template <sub>`, `completion <shell>`, `feedback <sub>`) never reach flag.Parse for that token, so without this they answer `--help` with "unknown type/subcommand" — the least useful reply available to a program being asked how to use it. The three spellings match Go's own flag package.

func NotificationsSubcommands added in v0.15.0

func NotificationsSubcommands() []string

NotificationsSubcommands is the SSOT used by command catalogs and shell completion.

func RenderCompletion added in v0.2.0

func RenderCompletion(shell string, cmds []string, subFamilies map[string][]string) (string, error)

RenderCompletion returns the completion script for shell, listing cmds as the top-level verbs and each entry of subFamilies as a `a2a <verb> <sub>` family. cmds, the family list, and every family's subs are copied and sorted so the output is deterministic regardless of the caller's ordering. An unknown shell is an error (never a silent empty script).

func ResolveActor

func ResolveActor(flags ActorFlags, harness HarnessDefaults, cfg ConfigActor) (template.Actor, error)

ResolveActor resolves the actor identity to fill into a new draft per §7.4's binding order: explicit flags > A2A_ACTOR_* env vars > harness adapter defaults > config; actor.kind defaults to "agent" when no source names one.

actor.Name carries one more fallback below config: the OS user (osUsername) — the HIGH-finding stopgap for the anonymous-actor gap. Every §7.4 source above it can legitimately be empty (unset flag/env, no harness adapter integration yet, no config default-actor block), and unlike Kind, Name previously had no final fallback at all, so a CLI-minted write could carry actor.name: "" straight through. This is deliberately the LAST fallback, not a new higher-priority source — it never overrides an explicit flag, env var, harness default, or config value.

And when even that resolves to nothing, it REFUSES here

AC-1013.1. In a minimal container os/user has no passwd entry and $USER is unset, so every source in the chain is empty. The write was already refused in that case — actor.name carries a minLength in both event/v1 and envelope/v1, so there was never a correctness hole — but the message an agent got was a schema violation about a field it never knowingly set. It named neither the flag nor the env var that fixes it.

The refusal lives HERE, at the one place the CLI resolves an actor, rather than at each of the ~10 verbs that write one. internal/mcp is deliberately untouched and keeps its own resolver (internal/mcp/adapters.go's private resolveActor) and its own schema-level refusal — the two surfaces have always had separate resolvers, so this is not a new divergence and the operator's MCP fence costs nothing here. An earlier reading of this file claimed every fix crossed into MCP; that was wrong, and it was wrong because it was reasoned about rather than read.

func ResolveSubmitTargets

func ResolveSubmitTargets(stagingDir string, args []string) ([]string, error)

ResolveSubmitTargets is the SINGLE parser+resolver of `a2a submit`'s arg grammar (§7.2 OP-205/OP-220), shared by SubmitCommand.Run and the cmd/a2a wiring closure so neither drifts from the other:

  • `submit --drafts` -> every *.md under stagingDir
  • `submit --batch <a...>` -> each arg resolved (>=1 required)
  • `submit <artifact>` -> exactly one arg resolved

Each non-flag arg is a staged-draft path OR a bare artifact id (resolved to <stagingDir>/<id>.md), per OP-205's own Input column. A malformed invocation returns a *SubmitUsageError.

func SkillSubcommands added in v0.15.0

func SkillSubcommands() []string

SkillSubcommands is the SSOT list used by shell completion and the command's own dispatch surface. Keep the returned slice isolated from callers so a renderer cannot mutate the command vocabulary.

func StartDetachedSync added in v0.16.3

func StartDetachedSync() error

StartDetachedSync launches the current a2a executable's canonical sync command without inheriting prompt-facing stdio or waiting for completion.

func WorkSubcommands added in v0.19.0

func WorkSubcommands() []string

WorkSubcommands is the surface-enumeration SSOT used by lead-owned wiring.

Types

type ActorFlags

type ActorFlags struct {
	Kind  string
	Name  string
	Model string
}

ActorFlags carries the explicit --actor-* flag values a verb parsed — the highest-priority source in the §7.4 order.

type AwaitCommand added in v0.15.0

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

AwaitCommand owns only transport: argument parsing and result rendering. The polling state machine lives in space.Awaiter.

func NewAwaitCommand added in v0.15.0

func NewAwaitCommand(resolve AwaitResolver) *AwaitCommand

NewAwaitCommand constructs the await transport.

func (*AwaitCommand) Name added in v0.15.0

func (c *AwaitCommand) Name() string

Name implements Command.

func (*AwaitCommand) Run added in v0.15.0

func (c *AwaitCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements Command.

func (*AwaitCommand) Synopsis added in v0.15.0

func (c *AwaitCommand) Synopsis() string

Synopsis implements Command.

type AwaitResolver added in v0.15.0

type AwaitResolver func(context.Context, string) (AwaitTarget, error)

AwaitResolver resolves an artifact id to exactly one recorded pending write.

type AwaitTarget added in v0.15.0

type AwaitTarget struct {
	SpaceID string
	Await   func(context.Context) (space.AwaitResult, error)
}

AwaitTarget is the one resolved pending write and its owning space.

type CacheBackedCacheRemover

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

CacheBackedCacheRemover is P7's real CacheRemover (the cli. CacheRemover seam, adapters.go): `a2a disconnect`'s cache-removal step (§7.2 OP-202) clears every pending marker recorded for the disconnected space. The read cursor's own item-state entries for that space's items are intentionally left as harmless orphans (cache.RemoveSpaceMarkers's own doc comment: self-correcting, D-001 — a disconnected space's items simply stop appearing in any future index).

func NewCacheBackedCacheRemover

func NewCacheBackedCacheRemover(cacheDir string) *CacheBackedCacheRemover

NewCacheBackedCacheRemover constructs a CacheBackedCacheRemover. cacheDir is `.a2a/cache/`'s path.

func (*CacheBackedCacheRemover) RemoveSpace

func (r *CacheBackedCacheRemover) RemoveSpace(_ context.Context, spaceID string) error

RemoveSpace implements CacheRemover.

type CacheBackedPendingMarker

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

CacheBackedPendingMarker is P7's real PendingMarker (the cli. PendingMarker seam, adapters.go): cmd_submit's per-artifact call (non-empty artifactID) persists a cache.PendingMarker file under cacheDir, the pending-merge overlay internal/cache.Store reads back into Item.PendingMerge. cmd_sync's own calling convention (spaceID set, artifactID empty, a zero WriteResult — "refresh local cache", adapters.go's PendingMarker doc comment) is a documented no-op here: the mirror's own `.git/FETCH_HEAD` mtime (already updated by the CloneOrFetch call that precedes this call in cmd_sync.go) IS the staleness signal internal/cache.Store reads (mirrorSyncAge) — no separate cache-side bookkeeping is needed for a bare refresh.

func NewCacheBackedPendingMarker

func NewCacheBackedPendingMarker(cacheDir string) *CacheBackedPendingMarker

NewCacheBackedPendingMarker constructs a CacheBackedPendingMarker. cacheDir is `.a2a/cache/`'s path.

func (*CacheBackedPendingMarker) ClearPending added in v0.15.0

func (m *CacheBackedPendingMarker) ClearPending(spaceID, artifactID string) error

ClearPending implements PendingMarkerClearer.

func (*CacheBackedPendingMarker) MarkPending

func (m *CacheBackedPendingMarker) MarkPending(_ context.Context, spaceID, artifactID string, result space.WriteResult) error

MarkPending implements PendingMarker.

func (*CacheBackedPendingMarker) Pending added in v0.15.0

func (m *CacheBackedPendingMarker) Pending(spaceID, artifactID string) (PendingWrite, bool, error)

Pending implements PendingMarkerReader.

func (*CacheBackedPendingMarker) ReconcilePending added in v0.19.0

func (m *CacheBackedPendingMarker) ReconcilePending(spaceID, mirrorDir string) error

ReconcilePending implements PendingMarkerReconciler after a successful canonical mirror refresh.

type CacheRemover

type CacheRemover interface {
	RemoveSpace(ctx context.Context, spaceID string) error
}

CacheRemover is the future internal/cache seam for `a2a disconnect`'s "remove config entry + mirror + cache for that space" step (§7.2 OP-202) — a distinct seam from PendingMarker (that one marks a pending state; this one clears cached state for a space being disconnected). This phase's injected implementation is a pure no-op; P7 supplies the real internal/cache-backed one later.

type Command

type Command interface {
	// Name is the verb as typed on the command line (e.g. "submit").
	Name() string
	// Synopsis is a one-line description for the usage listing.
	Synopsis() string
	// Run executes the verb. ctx carries cancellation for any network/git
	// call the verb makes through a core package.
	Run(ctx context.Context, args []string, stdio IO) int
}

Command is one a2a subcommand. Run receives the args AFTER the verb name and returns the process exit code (0 success; 2 usage/unknown by CLI convention; other non-zero for a runtime failure with an actionable message already written to IO.Stderr). Run must never call os.Exit and never write to the real os.Std* directly — only through the injected IO, so the whole surface stays testable.

type CompletionCommand added in v0.2.0

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

CompletionCommand implements `a2a completion`. cmds is the top-level verb list and subFamilies maps each `a2a <verb> <sub>` family verb (contract, feedback, …) to its sub-verb names, both injected by cmd/a2a (the single owner of the dispatch surface). Both may be nil when the command is constructed only to read Name()/Synopsis() (the catalog seam) — Run is never invoked in that case.

func NewCompletionCommand added in v0.2.0

func NewCompletionCommand(cmds []string, subFamilies map[string][]string) *CompletionCommand

NewCompletionCommand constructs the completion verb over an injected verb inventory. Passing nil/nil is valid for a metadata-only construction.

func (*CompletionCommand) Name added in v0.2.0

func (c *CompletionCommand) Name() string

Name implements Command.

func (*CompletionCommand) Run added in v0.2.0

func (c *CompletionCommand) Run(_ context.Context, args []string, stdio IO) int

Run implements Command. Exit codes: 2 = usage (missing/extra arg); 1 = unknown shell / render error; 0 = ok.

func (*CompletionCommand) Synopsis added in v0.2.0

func (c *CompletionCommand) Synopsis() string

Synopsis implements Command.

type ConfigActor

type ConfigActor struct {
	Kind  string
	Name  string
	Model string
}

ConfigActor is the config-level fallback (§7.4 order, lowest priority). space.ProjectConfig does not define a default-actor block yet; callers pass a zero value until that lands.

type ConnectCommand

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

ConnectCommand implements `a2a connect <space-repo>`: registers the space in .a2a/config.yaml and establishes its mirror clone (§7.4). Idempotent: connecting an already-connected space id/URL re-fetches the existing mirror rather than erroring or duplicating the config entry.

func NewConnectCommand

func NewConnectCommand(projectConfigPath, machineConfigPath, projectRoot string) *ConnectCommand

NewConnectCommand constructs the connect command.

func (*ConnectCommand) Name

func (c *ConnectCommand) Name() string

Name implements cli.Command.

func (*ConnectCommand) Run

func (c *ConnectCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command. Exit codes: 2 = usage (missing space-repo arg); 1 = clone/config-write failure; 0 = success (including the idempotent already-connected path).

func (*ConnectCommand) SetDefaultCredentialRefForTest added in v0.3.0

func (c *ConnectCommand) SetDefaultCredentialRefForTest(f func(ctx context.Context, spaceID string) string)

SetDefaultCredentialRefForTest overrides the credential-reference probe (test-only DI) so tests never shell out to the ambient `gh`.

func (*ConnectCommand) Synopsis

func (c *ConnectCommand) Synopsis() string

Synopsis implements cli.Command.

type ContractCheckOperation added in v0.19.0

type ContractCheckOperation interface {
	CheckContract(context.Context, ContractCheckRequest) (contract.ConformanceResult, error)
}

ContractCheckOperation checks a contract using the shared conformance service.

type ContractCheckRequest added in v0.19.0

type ContractCheckRequest struct {
	Ref         string
	PayloadPath string
	SchemaPath  string
	Suite       bool
}

ContractCheckRequest is the CLI request for contract conformance checking.

type ContractCommand

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

ContractCommand implements `a2a contract <new|publish|deprecate|retire| diff|verify-export>` (spec 08 T1).

func NewContractCommand

func NewContractCommand(newCmd *NewCommand, funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *ContractCommand

NewContractCommand constructs the contract command. newCmd is P6's own `a2a new` command (reused verbatim for `contract new`'s delegation, never duplicated); funnel/manifest/resolveActor must not be nil/zero (rails anti-pattern #10).

func (*ContractCommand) Name

func (c *ContractCommand) Name() string

Name implements cli.Command.

func (*ContractCommand) Run

func (c *ContractCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command.

func (*ContractCommand) SetClockForTest

func (c *ContractCommand) SetClockForTest(now func() time.Time)

SetClockForTest overrides this command's injected clock (test-only DI seam, rails anti-pattern #10: production always uses the constructor's own time.Now default). HIGH-1/LOW fix-wave finding: proving announcementID's determinism and contractSunsetPassed's date comparison both need a FIXED, reproducible `now` across multiple calls — a real wall-clock read would make either assertion flaky near a UTC-date boundary.

func (*ContractCommand) SetP6Inspection added in v0.19.0

func (c *ContractCommand) SetP6Inspection(inspection ContractInspectionOperations)

SetP6Inspection wires the optional read-only P6 inspection service.

func (*ContractCommand) SetP6Operations added in v0.19.0

func (c *ContractCommand) SetP6Operations(publication ContractPublicationOperations, materialize ContractMaterializeOperation, check ContractCheckOperation)

SetP6Operations wires the shared P6 services. Production wiring must supply all three; split interfaces keep each adapter small and independently fakeable.

func (*ContractCommand) SetPendingMarker added in v0.15.0

func (c *ContractCommand) SetPendingMarker(pending PendingMarker)

SetPendingMarker wires lifecycle/contract writes to the shared pending store.

func (*ContractCommand) Synopsis

func (c *ContractCommand) Synopsis() string

Synopsis implements cli.Command.

type ContractDiffRequest added in v0.19.0

type ContractDiffRequest struct {
	ID string
	V1 string
	V2 string
}

ContractDiffRequest selects two contract versions to compare.

type ContractDiffResult added in v0.19.0

type ContractDiffResult struct {
	Added              []string `json:"added"`
	Removed            []string `json:"removed"`
	Changed            []string `json:"changed"`
	FrontmatterChanged []string `json:"frontmatter_changed"`
}

ContractDiffResult describes paths that differ between two contract versions.

type ContractInspectionOperations added in v0.19.0

type ContractInspectionOperations interface {
	DiffContract(context.Context, ContractDiffRequest) (ContractDiffResult, error)
	VerifyContractExport(context.Context, ContractVerifyExportRequest) (ContractVerifyExportResult, error)
}

ContractInspectionOperations provides read-only contract inspection operations.

type ContractMaterializeOperation added in v0.19.0

type ContractMaterializeOperation interface {
	MaterializeContract(context.Context, ContractMaterializeRequest) (space.ContractMaterializeResult, error)
}

ContractMaterializeOperation materializes a contract into a rooted destination.

type ContractMaterializeRequest added in v0.19.0

type ContractMaterializeRequest struct {
	Ref         string
	Destination string
}

ContractMaterializeRequest is the CLI request for an exported contract tree.

type ContractPublicationOperations added in v0.19.0

ContractPublicationOperations is the consumer-side seam over P6's shared publication service. CLI owns flags and rendering only.

type ContractPublicationRequest added in v0.19.0

type ContractPublicationRequest struct {
	ID         string
	Version    string
	Bump       string
	Staging    string
	ExpectPlan string
	Actor      ActorFlags
}

ContractPublicationRequest is the transport-owned, filesystem-free input passed to cmd/a2a's adapter. The adapter selects and freezes the candidate source before calling the shared space publication service.

type ContractSubcommand

type ContractSubcommand struct {
	Name     string // e.g. "publish"
	Synopsis string
}

ContractSubcommand describes one `a2a contract <sub>` sub-verb for external surface enumeration.

func ContractSubcommands

func ContractSubcommands() []ContractSubcommand

ContractSubcommands is the SSOT list of the `a2a contract` family's sub-verbs for surface enumeration — the P14 CLI/MCP parity check and the P13 command-catalog projection both read it. The contract sub-verbs are dispatched by the bare switch in ContractCommand.Run (they are NOT registered as individual cli.Command values / buildCommands keys), so this list is their only machine-enumerable home. KEEP IN SYNC with that switch: a sub-verb added there without a row here (or vice versa) is exactly the drift the parity gate exists to catch.

type ContractVerifyExportRequest added in v0.19.0

type ContractVerifyExportRequest struct {
	Local string
	Ref   string
}

ContractVerifyExportRequest selects a local export and its expected source ref.

type ContractVerifyExportResult added in v0.19.0

type ContractVerifyExportResult struct {
	ID          string             `json:"id"`
	Matches     bool               `json:"matches"`
	LocalDigest string             `json:"local_digest"`
	WantDigest  string             `json:"want_digest"`
	Diff        ContractDiffResult `json:"diff,omitempty"`
}

ContractVerifyExportResult reports whether a local export matches its source.

type ContractsCommand

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

ContractsCommand implements `a2a contracts [--provider <sys>]` (OP-221): known contracts from the local cache (provider, version, state). `a2a contract diff` is P8's, out of this phase's footprint.

func NewContractsCommand

func NewContractsCommand(store *cache.Store) *ContractsCommand

NewContractsCommand constructs the contracts command. store must not be nil (rails anti-pattern #10).

func (*ContractsCommand) Name

func (c *ContractsCommand) Name() string

Name implements cli.Command.

func (*ContractsCommand) Run

func (c *ContractsCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command. Exit codes: 2 = usage; 1 = a connected space's mirror could not be read; 0 = success.

func (*ContractsCommand) Synopsis

func (c *ContractsCommand) Synopsis() string

Synopsis implements cli.Command.

type DataCommand added in v0.19.0

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

DataCommand implements `a2a data <pack|deliver|fetch|verify>` (spec 05a T1).

func NewDataCommand added in v0.19.0

func NewDataCommand(ops DataOperations) *DataCommand

NewDataCommand constructs the data command. ops may be nil (e.g. in a degraded/offline registration); every sub-verb reports "service is not configured" rather than panicking, matching contractServiceUnavailable's own precedent.

func (*DataCommand) Name added in v0.19.0

func (c *DataCommand) Name() string

Name implements cli.Command.

func (*DataCommand) Run added in v0.19.0

func (c *DataCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command.

func (*DataCommand) Synopsis added in v0.19.0

func (c *DataCommand) Synopsis() string

Synopsis implements cli.Command.

type DataDeliverRequest added in v0.19.0

type DataDeliverRequest struct {
	StagingRoot string // the packed staging root produced by pack
	Fulfills    string
	Supersedes  string
	ExpectPack  string // aggregate digest the caller expects, empty to skip the binding
	Actor       ActorFlags
}

DataDeliverRequest is "a2a data deliver" resolved input.

type DataFetchRequest added in v0.19.0

type DataFetchRequest struct {
	PackageID   string
	Destination string
}

DataFetchRequest is "a2a data fetch" resolved input.

type DataOperations added in v0.19.0

type DataOperations interface {
	Pack(ctx context.Context, req DataPackRequest) (DataResult, error)
	Deliver(ctx context.Context, req DataDeliverRequest) (DataResult, error)
	Fetch(ctx context.Context, req DataFetchRequest) (DataResult, error)
	Verify(ctx context.Context, req DataVerifyRequest) (DataResult, error)
}

DataOperations is the whole data surface behind one interface, so CLI, MCP and their tests share one seam rather than four.

type DataPackRequest added in v0.19.0

type DataPackRequest struct {
	ContractRef string // <XC-id>@<version>, as typed
	From        string // local source directory
	Profile     string // synthetic | sanitized
	Format      string // json | ndjson
	Expires     time.Duration
	Fulfills    string // the work_request this delivery answers
	Supersedes  string // prior package id, empty for a first attempt
	MaxAttempts int    // 0 = unset = nothing is refused (L-1 shipped default)
}

DataPackRequest is "a2a data pack" resolved input.

type DataResult added in v0.19.0

type DataResult struct {
	Manifest  *datapackage.Document `json:"manifest,omitempty"`   // pack, deliver, fetch: the package involved
	Report    *datapackage.Report   `json:"report,omitempty"`     // verify: the verdict
	Outcome   string                `json:"outcome,omitempty"`    // fetch: installed | already-present
	Write     *space.WriteResult    `json:"write,omitempty"`      // deliver: branch, pull request, commit
	HandoffID string                `json:"handoff_id,omitempty"` // deliver: the handoff carrying the package
	// StagingRoot is where pack wrote the attempt. It is the exact
	// argument `data deliver` takes next, and it is returned rather than
	// left to be derived: an agent that has to reconstruct a path from a
	// minted id will eventually reconstruct it wrong, and the tool already
	// knows the answer.
	StagingRoot string `json:"staging_root,omitempty"`
}

DataResult is what every data verb returns to the surface. The JSON payload and the human lines are both derived from it, never assembled twice. JSON tags are additive metadata only — they change no field name or method signature the seam declares, and exist so `--json` emits the same lower_snake_case shape every other wire type in this package uses, rather than Go's bare exported field names.

type DataSubcommand added in v0.19.0

type DataSubcommand struct {
	Name     string // e.g. "pack"
	Synopsis string
}

DataSubcommand describes one `a2a data <sub>` sub-verb for external surface enumeration — mirrors ContractSubcommand's own shape (cmd_contract.go) so the same four consumers (help, completion, catalog, the MCP parity test) can read this family the same way they already read the contract one.

func DataSubcommands added in v0.19.0

func DataSubcommands() []DataSubcommand

DataSubcommands is the SSOT list of the `a2a data` family's sub-verbs (spec 05a §T1) for surface enumeration. The data sub-verbs are dispatched by the bare switch in DataCommand.Run (they are NOT registered as individual cli.Command values / buildCommands keys), exactly as ContractSubcommands' own doc comment describes for contract — this list is their only machine-enumerable home. KEEP IN SYNC with that switch: a sub-verb added there without a row here (or vice versa) is exactly the drift the parity gate exists to catch.

The name order here is also what cmd/a2a/mcp_parity_test.go's TestDataSubcommandsMatchMCPDataActions requires to be byte-identical, name-for-name and in order, to mcp.DataActions — the MCP a2a_data tool's own closed action enum.

type DataVerifyRequest added in v0.19.0

type DataVerifyRequest struct {
	PackageID string
	// Record performs ONE funnel write carrying the verification-report/v1
	// document AND the lifecycle event on the handoff. Its DIRECTION
	// (verify-pass or verify-fail) is derived from the report's own result
	// by the core — there is no field here to choose it (spec 05a plan
	// D-12): a forged pass must be unrepresentable, not merely refused.
	Record bool
	Actor  ActorFlags
}

DataVerifyRequest is "a2a data verify" resolved input.

type DisconnectCommand

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

DisconnectCommand implements `a2a disconnect <space>`: removes the config entry + mirror clone for that space (and calls the future internal/cache removal seam, currently a no-op — spec 06 Open Q-A). Disconnecting a space that was never connected is itself an idempotent no-op (exit 0), consistent with §7.2's "every mutating command is safe to re-run" rule.

func NewDisconnectCommand

func NewDisconnectCommand(projectConfigPath, machineConfigPath, projectRoot string, cache CacheRemover) *DisconnectCommand

NewDisconnectCommand constructs the disconnect command. cache is the PendingMarker's sibling no-op seam (P7 supplies the real internal/cache-backed CacheRemover later); cache must not be nil (rails anti-pattern #10 — construct with NewNoopCacheRemover() until P7 lands).

func (*DisconnectCommand) Name

func (c *DisconnectCommand) Name() string

Name implements cli.Command.

func (*DisconnectCommand) Run

func (c *DisconnectCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command. Exit codes: 2 = usage (missing space arg); 1 = mirror-removal/config-write failure; 0 = success (including the idempotent never-connected no-op).

func (*DisconnectCommand) Synopsis

func (c *DisconnectCommand) Synopsis() string

Synopsis implements cli.Command.

type DisputeCommand

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

DisputeCommand implements `a2a dispute <response-id> --reason <text> [--reason-code <enum>]`: folds the response to `disputed`; the parent's responded->in_progress reopening is fold's OWN side effect (applyResponseScoped), never a second authored event.

func NewDisputeCommand

func NewDisputeCommand(funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *DisputeCommand

NewDisputeCommand constructs the dispute command.

func (*DisputeCommand) Name

func (c *DisputeCommand) Name() string

Name implements cli.Command.

func (*DisputeCommand) Run

func (c *DisputeCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command.

func (*DisputeCommand) SetPendingMarker added in v0.15.0

func (c *DisputeCommand) SetPendingMarker(pending PendingMarker)

SetPendingMarker replaces the command's pending-write recorder.

func (*DisputeCommand) Synopsis

func (c *DisputeCommand) Synopsis() string

Synopsis implements cli.Command.

type DoctorClassificationSummary added in v0.19.0

type DoctorClassificationSummary struct {
	Highest      string
	SkippedCount int
	SkippedPaths []string
}

DoctorClassificationSummary is the complete classification fact doctor consumes from P1's cache projection. It deliberately contains no visibility policy: P1 reports the highest decoded classification and every skipped path; doctor alone decides how those facts relate to repository transport.

type DoctorClassificationSummaryReader added in v0.19.0

type DoctorClassificationSummaryReader interface {
	ClassificationSummary(ctx context.Context, spaceID string) (DoctorClassificationSummary, error)
}

DoctorClassificationSummaryReader is defined by the consumer so doctor does not depend on cache's concrete store or scan representation. Lead wiring may adapt P1's cache summary after both slices land.

type DoctorCommand

type DoctorCommand struct {

	// TemplateFiles is the embedded space-template/ tree (spacetemplate.Files
	// — mirrors SpaceCommand.TemplateFiles' own role and doc). Exported and
	// left NIL by NewDoctorCommand ("nil means not wired", this package's DI
	// convention — see SpaceCommand's own six space-update-only fields): the
	// lead wires it post-construction in cmd/a2a (`cmd.TemplateFiles =
	// spacetemplate.Files`, the same shape update/init already use for
	// SkillFiles), because internal/cli must not import space-template
	// directly. The "space scaffolding current" check
	// (doctorCheckScaffoldingCurrent) reports "could not be checked" rather
	// than nil-panicking or silently skipping when this is unset.
	TemplateFiles fs.FS

	// NotificationStatus is wired by cmd/a2a to the same controller as
	// `a2a notifications status`; doctor never grows a second platform probe.
	NotificationStatus func(context.Context, string) (notification.Status, error)

	// ParticipantAvatarStatus is wired by cmd/a2a from the avatar cache owner.
	// The CLI receives policy, not the cache path or on-disk format. The first
	// result says a validated local image exists; the second says foreground
	// sync supports this owner identifier at all.
	ParticipantAvatarStatus func(login string) (cached, supported bool)

	// ClassificationSummaryReader is P4's consumer-side seam for P1's cache
	// classification summary. Nil is an explicit UNVERIFIED diagnostic, never a
	// scan reimplementation or a false PASS.
	ClassificationSummaryReader DoctorClassificationSummaryReader
	// contains filtered or unexported fields
}

DoctorCommand implements the basic (non-`--space`) `a2a doctor` verb: one line per check, exit 0 iff all pass. `--space` (the v2 admin host-drift diff, D-030) is rejected explicitly, never silently ignored.

The check LIST lives in Run's `checks` slice and nowhere else. This comment used to enumerate "the five OP-218 checks" and the set had grown to ten — the same drift that made Synopsis() lie for two releases. The enumeration belongs somewhere it can be diffed against the code; here it can only rot.

func NewDoctorCommand

func NewDoctorCommand(h host.Host, binaryVersion, projectConfigPath, machineConfigPath, projectRoot string) *DoctorCommand

NewDoctorCommand constructs the basic doctor command. h is the host adapter (injected for parity with the rest of this package's DI convention; the CI-presence check's required-check-config half is NOT implemented against it today — see checkCIPresence's doc comment and this phase's reported deviation). binaryVersion is this build's own version stamp (§7.3, injected rather than read from a build var so tests control it). projectConfigPath/machineConfigPath are `.a2a/config.yaml` and `~/.config/a2a/config.yaml` (§7.4); projectRoot resolves each connected space's mirror directory (space.ResolveMirrorLocation) when a space's config entry does not carry an absolute mirror location.

func (*DoctorCommand) Name

func (c *DoctorCommand) Name() string

Name implements cli.Command.

func (*DoctorCommand) Run

func (c *DoctorCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command. Exit codes: 2 = usage error (including the rejected `--space` flag); 1 = one or more checks failed, or the local config could not be loaded; 0 = every check passed.

func (*DoctorCommand) Synopsis

func (c *DoctorCommand) Synopsis() string

Synopsis implements cli.Command.

Deliberately NOT an enumeration of the check names. It used to list five of them and the check set grew to nine, so the one artifact an agent is told is "generated from the binary, the source of truth for invocation syntax" (skill/a2ahub/reference/commands.md) described a doctor that had not existed for two releases. The `skill-drift` gate could not catch it either: it regenerates from this same string and byte-diffs, so a stale sentence here stays green forever. A summary cannot go stale that way; the enumeration lives where it can be checked against `checks` — troubleshooting.md's table.

type FeedbackCommand added in v0.2.0

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

FeedbackCommand implements `a2a feedback <new|validate|submit|status| triage>` (spec 25 §T1). `triage` is a hub-operator verb (mirrors how `skill install`, P20, is host-only) — this file adds no MCP glue.

func NewFeedbackCommand added in v0.2.0

func NewFeedbackCommand(drafter *feedback.Drafter, submitter *feedback.Submitter, ledgerPath, hubRoot string, hubReader feedback.HubReader) *FeedbackCommand

NewFeedbackCommand constructs the feedback command. drafter is required for `new`; submitter is required for `submit` (rails anti-pattern #10 — callers wire the real space.WriteFunnel-backed feedback.Submitter at cmd/a2a, tests inject one built over host.NewFakeHost()). ledgerPath is `.a2a/feedback/ledger.yaml`'s path; hubRoot is the cwd `triage` runs from (§T1: "run from the hub repo root"); hubReader resolves `status`'s hub-side reads (production: feedback.DefaultHubReader; tests: a local-fixture func).

func (*FeedbackCommand) Name added in v0.2.0

func (c *FeedbackCommand) Name() string

Name implements cli.Command.

func (*FeedbackCommand) Run added in v0.2.0

func (c *FeedbackCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command.

func (*FeedbackCommand) SetClockForTest added in v0.2.0

func (c *FeedbackCommand) SetClockForTest(now func() time.Time)

SetClockForTest overrides the injected clock (triage --apply's digest date / backlog date).

func (*FeedbackCommand) SetReadFileForTest added in v0.2.0

func (c *FeedbackCommand) SetReadFileForTest(f func(path string) ([]byte, error))

SetReadFileForTest overrides the injected file reader (test-only DI seam, rails anti-pattern #10 convention).

func (*FeedbackCommand) Synopsis added in v0.2.0

func (c *FeedbackCommand) Synopsis() string

Synopsis implements cli.Command.

type HarnessDefaults

type HarnessDefaults struct {
	Kind  string
	Name  string
	Model string
}

HarnessDefaults is the "harness adapter defaults" source (§7.4 order, third priority). This phase has no live harness-adapter integration (out of scope, no such adapter exists yet); callers pass a zero value — the seam exists so a later phase can supply one without touching the order logic here.

type HtmlCommand added in v0.2.0

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

HtmlCommand implements `a2a html` / `a2a dashboard`. name carries the invoked verb so the usage line and catalog show the right one (they are the same command; `dashboard` is the friendly alias).

func NewDashboardCommand added in v0.2.0

func NewDashboardCommand(store *cache.Store) *HtmlCommand

NewDashboardCommand is the `a2a dashboard` alias (same behavior).

func NewDashboardCommandWithOperational added in v0.19.0

func NewDashboardCommandWithOperational(store *cache.Store, source OperationalSnapshotReader) *HtmlCommand

NewDashboardCommandWithOperational is the production dashboard alias.

func NewDashboardCommandWithOperationalAndContractHistory added in v0.19.0

func NewDashboardCommandWithOperationalAndContractHistory(store *cache.Store, source OperationalSnapshotReader, validator space.ContractHistoryDocumentValidator) *HtmlCommand

NewDashboardCommandWithOperationalAndContractHistory is the production dashboard alias with the canonical historical-document validator injected.

func NewHtmlCommand added in v0.2.0

func NewHtmlCommand(store *cache.Store) *HtmlCommand

NewHtmlCommand constructs the `a2a html` command over a composed Store.

func NewHtmlCommandWithOperational added in v0.19.0

func NewHtmlCommandWithOperational(store *cache.Store, source OperationalSnapshotReader) *HtmlCommand

NewHtmlCommandWithOperational constructs the production HTML command over the canonical operational source.

func NewHtmlCommandWithOperationalAndContractHistory added in v0.19.0

func NewHtmlCommandWithOperationalAndContractHistory(store *cache.Store, source OperationalSnapshotReader, validator space.ContractHistoryDocumentValidator) *HtmlCommand

NewHtmlCommandWithOperationalAndContractHistory constructs the production HTML command with both canonical read dependencies supplied by cmd/a2a.

func (*HtmlCommand) Name added in v0.2.0

func (c *HtmlCommand) Name() string

Name implements Command.

func (*HtmlCommand) Run added in v0.2.0

func (c *HtmlCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements Command. Exit codes: 2 = usage; 1 = assemble/render/write error; 0 = ok.

func (*HtmlCommand) Synopsis added in v0.2.0

func (c *HtmlCommand) Synopsis() string

Synopsis implements Command.

type IO

type IO struct {
	Stdin  io.Reader
	Stdout io.Writer
	Stderr io.Writer
}

IO is the injected stream set a Command reads and writes — never the global os.Std* (that is cmd/a2a's to supply), so tests drive a verb with buffers and assert on output + exit code.

type InboxCommand

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

InboxCommand implements `a2a inbox [--actionable] [--json]` (OP-207): the computed inbox across every connected space, JSON output guaranteed. Business logic (the 5-condition `--actionable` union, federation, cursor-advance) lives entirely in internal/cache — this file is a thin flags-in/JSON-out wrapper (ADR-001 "thin frontend").

func NewInboxCommand

func NewInboxCommand(store *cache.Store) *InboxCommand

NewInboxCommand constructs the inbox command. store must not be nil (rails anti-pattern #10).

func (*InboxCommand) Name

func (c *InboxCommand) Name() string

Name implements cli.Command.

func (*InboxCommand) Run

func (c *InboxCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command. Exit codes: 2 = usage; 1 = a connected space's mirror could not be read; 0 = success (including the zero-items case — an empty inbox is not a failure).

With --exit-code, success instead carries §7.5's severity: 0 nothing, 10 items pending, 11 p1/blocking/gate. 1 and 2 keep their meanings, so a caller can always tell "there is work" from "the command failed".

--overdue answers the question `--actionable` structurally cannot: what is late and MINE. See internal/cache/overdue.go for why it is a separate query rather than a sixth condition on a normative union.

func (*InboxCommand) Synopsis

func (c *InboxCommand) Synopsis() string

Synopsis implements cli.Command.

type InitCommand

type InitCommand struct {

	// MachineConfigPath is FIX B's DI seam (spec 18 §T1/§8): when the
	// wiring layer sets this (cmd/a2a/wire.go's init closure, mirroring
	// how the validate closure sets CIGitHubActor), Run seeds a
	// `~/.config/a2a/config.yaml` skeleton on first run so `a2a submit`
	// never dies "no machine config" before an operator has ever run
	// `a2a doctor`. Left empty (e.g. the catalog/test construction path),
	// this is a no-op — no behavior change.
	MachineConfigPath string

	// AgentsPath is the consumer repo's AGENTS.md path, DI'd from wire.go
	// (<projectRoot>/AGENTS.md). The pointer is written by DEFAULT (opt out with
	// --no-agents-pointer); left empty (catalog/test path), the step is a no-op.
	AgentsPath string

	// SkillFiles + SkillTarget + Version drive the default-on skill install
	// (opt out with --no-skill). SkillFiles is the embedded tree (skill.Files,
	// DI'd from wire.go); SkillTarget is where it lands (<projectRoot>/.a2ahub/
	// skill). Left nil/empty (catalog/test path), the skill step is a no-op.
	SkillFiles  fs.FS
	SkillTarget string
	Version     string

	// ProjectRoot is the consumer repo's root, DI'd from wire.go, used by
	// the default-on surface-link step (linkDetectedSurfaces, opt out with
	// --no-skill-link). Left empty (catalog/test path), the step is a no-op.
	ProjectRoot string

	// ClaudeMdPath is the consumer repo's CLAUDE.md path, DI'd from wire.go
	// (<projectRoot>/CLAUDE.md). Governed by the SAME --no-agents-pointer
	// flag as AgentsPath (spec 32 §2.3's CLAUDE.md three-way). Left empty
	// (catalog/test path), the step is a no-op.
	ClaudeMdPath string
	// contains filtered or unexported fields
}

InitCommand implements `a2a init`: fully flag-driven non-interactive mode (`--system --space ...`) is normative (§7.2 OP-201, quoted); it writes .a2a/config.yaml, is idempotent on identical re-run ("already configured"), and NEVER blocks on stdin — a missing required flag is a usage error (exit 2), not a prompt. TTY interactive prompting is documented sugar this phase does not implement (see this phase's Deviations report): implementing a real prompt loop is exactly where a hang bug lives, and AC row 6 only requires the flag-driven path to never block.

func NewInitCommand

func NewInitCommand(projectConfigPath string) *InitCommand

NewInitCommand constructs the init command. projectConfigPath is `.a2a/config.yaml`'s path (§7.4).

func (*InitCommand) Name

func (c *InitCommand) Name() string

Name implements cli.Command.

func (*InitCommand) Run

func (c *InitCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command. Exit codes: 2 = usage error (missing --system, or zero --space values); 1 = config write failure; 0 = success (including the idempotent "already configured" no-op).

func (*InitCommand) SetDefaultCredentialRefForTest added in v0.3.0

func (c *InitCommand) SetDefaultCredentialRefForTest(f func(ctx context.Context, spaceID string) string)

SetDefaultCredentialRefForTest overrides the credential-reference probe (test-only DI, rails anti-pattern #10 convention) so tests never shell out to the ambient `gh`.

func (*InitCommand) Synopsis

func (c *InitCommand) Synopsis() string

Synopsis implements cli.Command.

type LegalityAdapter

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

LegalityAdapter is the concrete validate.LegalityChecker P6 wires: it folds a candidate event's subject against events already committed to the connected space's mirror clone on disk (internal/space layout + internal/fold), never against internal/cache (P7, absent).

validate.CandidateEvent carries no envelope (from/to/required_approvers) by the seam's own design (validate/seam.go: "a concrete implementation is expected to close over whatever locally-staged history/manifest it needs"). For a first-time submit the subject's artifact is not yet committed anywhere this adapter could read it from — the artifact is still a local staged draft; submit's own commit is what introduces it to the mirror. cmd_submit.go, which already parses the draft to build the write funnel's FileWrite payload, therefore calls RegisterEnvelope with that artifact's own envelope facts BEFORE calling Engine.ValidateForSubmit. This is this phase's own resolution of a real gap between the LegalityChecker interface's shape and what a concrete checker needs to answer a first-submit candidate — see this phase's Deviations report.

It only ever answers legality for the entry (draft -> X) transitions this phase's verbs emit (submit/publish/propose). verify/dispute (response-scoped, D-024) is out of P6's verb set and returns a documented "unsupported in P6" error rather than a silent legal verdict (the KNOWN GAP the plan's Placement decisions call out, backlogged to P7/P8).

func NewLegalityAdapter

func NewLegalityAdapter(mirrorDir, system string, manifest space.Manifest) *LegalityAdapter

NewLegalityAdapter constructs a LegalityAdapter reading committed history from mirrorDir (the connected space's local mirror clone, system's own section) and resolving membership against manifest (space.ParseManifest's own structural decode of space.yaml, as staged locally — pre-merge, per §5.5).

func (*LegalityAdapter) CheckLegality

func (a *LegalityAdapter) CheckLegality(candidate validate.CandidateEvent) (validate.Verdict, error)

CheckLegality implements validate.LegalityChecker.

func (*LegalityAdapter) HasCommittedHistory

func (a *LegalityAdapter) HasCommittedHistory(subject string) (bool, error)

HasCommittedHistory reports whether subject already has at least one committed lifecycle event in the mirror — cmd_submit's own "already submitted" idempotency short-circuit (AC-301.1), which must run BEFORE any V2/legality/funnel work so a re-run never re-validates or re-commits.

func (*LegalityAdapter) RegisterEnvelope

func (a *LegalityAdapter) RegisterEnvelope(subject string, env fold.Envelope)

RegisterEnvelope makes subject's envelope facts available to a subsequent CheckLegality(candidate) call for that same subject — see the type's doc comment for why this closure is necessary.

type LifecycleCommand

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

LifecycleCommand implements every table-driven OP-211 generic verb: N ids batched into one commit/one PR, V2 legality refusal locally BEFORE the funnel (AC-302.1), the SAME uniform funnel call (no gate parameter — approve/reject add an advisory PR marker only, P8-3).

func NewAcceptCommand

func NewAcceptCommand(funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *LifecycleCommand

NewAcceptCommand constructs `a2a accept <id...>`.

func NewAckCommand

func NewAckCommand(funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *LifecycleCommand

NewAckCommand constructs `a2a ack <id...>`. funnel, manifest and resolveActor must not be nil/zero-configured (rails anti-pattern #10).

func NewApproveCommand

func NewApproveCommand(funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *LifecycleCommand

NewApproveCommand constructs `a2a approve <decision-id>` (ALWAYS G3-gated, P8-3).

func NewBlockCommand

func NewBlockCommand(funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *LifecycleCommand

NewBlockCommand constructs `a2a block <id...> --refs <blocker-id>`.

func NewCancelCommand

func NewCancelCommand(funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *LifecycleCommand

NewCancelCommand constructs `a2a cancel <id...>`.

func NewCloseCommand

func NewCloseCommand(funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *LifecycleCommand

NewCloseCommand constructs `a2a close <parent-id...>`.

func NewDeclineCommand

func NewDeclineCommand(funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *LifecycleCommand

NewDeclineCommand constructs `a2a decline <id...> --reason <text> [--reason-code <enum>]`.

func NewRejectCommand

func NewRejectCommand(funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *LifecycleCommand

NewRejectCommand constructs `a2a reject <decision-id> --reason <text>` (ALWAYS G3-gated, P8-3).

func NewSatisfyCommand

func NewSatisfyCommand(funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *LifecycleCommand

NewSatisfyCommand constructs `a2a satisfy <requirement-id> --refs <XC-id@version>,<XS-id>`.

func NewStartCommand

func NewStartCommand(funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *LifecycleCommand

NewStartCommand constructs `a2a start <id...>`.

func NewSupersedeCommand

func NewSupersedeCommand(funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *LifecycleCommand

NewSupersedeCommand constructs `a2a supersede <id> --refs <successor-id>`.

func NewUnblockCommand

func NewUnblockCommand(funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *LifecycleCommand

NewUnblockCommand constructs `a2a unblock <id...>`.

func NewVerifyFailCommand

func NewVerifyFailCommand(funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *LifecycleCommand

NewVerifyFailCommand constructs `a2a verify-fail <handoff-id> --findings <text>`.

func NewVerifyPassCommand

func NewVerifyPassCommand(funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *LifecycleCommand

NewVerifyPassCommand constructs `a2a verify-pass <handoff-id>`.

func NewWithdrawCommand

func NewWithdrawCommand(funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *LifecycleCommand

NewWithdrawCommand constructs `a2a withdraw <requirement-id...>`.

func (*LifecycleCommand) Name

func (c *LifecycleCommand) Name() string

Name implements cli.Command.

func (*LifecycleCommand) Run

func (c *LifecycleCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command. Exit codes: 2 = usage; 1 = local legality refusal or a funnel/IO error (all-or-nothing across the batch, OP-220 pattern); 0 = success.

func (*LifecycleCommand) SetPendingMarker added in v0.15.0

func (c *LifecycleCommand) SetPendingMarker(pending PendingMarker)

SetPendingMarker wires the machine-local pending-write store.

func (*LifecycleCommand) Synopsis

func (c *LifecycleCommand) Synopsis() string

Synopsis implements cli.Command.

type ManifestValidatorAdapter

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

ManifestValidatorAdapter is the concrete space.ManifestValidator. It calls validate.Engine rather than addressing the schema corpus directly so manifest shape and authority-map policy have one owner on both the load seam and V3.

func NewManifestValidatorAdapter

func NewManifestValidatorAdapter(corpus *schema.Corpus) *ManifestValidatorAdapter

NewManifestValidatorAdapter constructs a ManifestValidatorAdapter over corpus (schema.Load's result).

func (*ManifestValidatorAdapter) ValidateManifest

func (m *ManifestValidatorAdapter) ValidateManifest(_ context.Context, raw []byte) error

ValidateManifest implements space.ManifestValidator.

type MirrorResolver

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

MirrorResolver is the concrete validate.Resolver P6 wires: it resolves known-artifact/digest/thread/system-membership facts from the connected space's mirror clone on disk. KnownArtifact/Digest/ThreadOf/ThreadExists resolve against internal/cache.BuildArtifactIndex — the SAME best-effort walk (bounded read -> ParseFrontmatter -> envelope decode -> id presence) internal/cache's own read model performs for its own index, complete with its []SkippedFile report, rather than a third, worse copy of that walk with no report at all (spec agent-ops-2026-07/specs/ 01-resolver-one-home.md, closing a filed defect: a file that failed to parse used to drop silently from THIS index, so a legitimate `refs:` entry into a real, unrelated artifact was refused REF-009/REF-010 with no hint that the actual cause was a THIRD file elsewhere that would not decode). System() stays manifest-local — no walk answers it. The index is built once, lazily, on first use, and is safe for concurrent read after that (sync.Once).

func NewMirrorResolver

func NewMirrorResolver(mirrorDir string, manifest space.Manifest) *MirrorResolver

NewMirrorResolver constructs a MirrorResolver over mirrorDir (the connected space's local mirror clone) and manifest (the space's structurally-parsed space.yaml, as staged locally).

func (*MirrorResolver) Digest

func (r *MirrorResolver) Digest(ref string) (string, bool)

Digest implements validate.Resolver: ref is a §5.7 ref grammar string (`id`, `id@version`, `id#digest`, `id@version#digest`); only the `id` segment is used to resolve the target file, whose digest — as captured by the SAME walk-time bounded read that decoded its envelope (see cache.BuildArtifactIndex's own doc comment on why this is walk-time, not re-read-per-call) — is returned.

func (*MirrorResolver) KnownArtifact

func (r *MirrorResolver) KnownArtifact(id string) bool

KnownArtifact implements validate.Resolver.

func (*MirrorResolver) Skipped added in v0.13.0

func (r *MirrorResolver) Skipped() []cache.SkippedFile

Skipped reports every mirror file this resolver's own index build could not decode — internal/cache.SkippedFile, unchanged and unextended (§9, out of scope). SubmitValidatorAdapter.ValidateSubmit reads this (via the unexported skipReporter capability probe) to attach it to a returned *ViolationError, so a REF-009/REF-010 refusal caused by an unrelated file failing to parse names THAT file, not just the ref that looked wrong (US-2).

func (*MirrorResolver) System

func (r *MirrorResolver) System(system string) (member bool, left bool)

System implements validate.Resolver.

func (*MirrorResolver) ThreadExists added in v0.10.0

func (r *MirrorResolver) ThreadExists(thread string) bool

ThreadExists implements validate.ThreadResolver: it reports whether any artifact already indexed from the mirror carries this exact thread value. An empty thread is never "carried" by anything — without this guard a threadless indexed artifact (thread: "") would make ThreadExists("") true, which is not what validate.ThreadResolver's own doc comment promises ("already carries this exact thread value"). checkForeignMint (thread.go) already guards env.Thread == "" before ever calling this, so no current caller can observe the difference — this is belt-and-braces for the interface contract itself, not a fix to a live bug.

func (*MirrorResolver) ThreadOf added in v0.10.0

func (r *MirrorResolver) ThreadOf(id string) (thread string, found bool)

ThreadOf implements validate.ThreadResolver.

type NewCommand

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

NewCommand implements `a2a new <type>`: mints an ID (§3.3), resolves the actor (§7.4), renders the canonical template (internal/template), and writes the draft under .a2a/staging/ — drafts never enter the space (§3.4). Non-interactive input (--field k=v, --body-file) is normative; this phase does not implement $EDITOR/TTY prompting (see this phase's Deviations report — sugar over the same code path, never load-bearing for any acceptance row).

func NewNewCommand

func NewNewCommand(stagingDir, ownSystem string, resolveActor func(ActorFlags) (template.Actor, error), connectedSpaceIDs []string) *NewCommand

NewNewCommand constructs the new command. ownSystem is this project's configured own system id (§7.4, used as the minted id's <system> token and the draft's default `from`). resolveActor closes over the §7.4 harness/config fallbacks (cmd/a2a supplies `func(f cli.ActorFlags) template.Actor { return cli.ResolveActor(f, harness, cfg) }`); it must not be nil (rails anti-pattern #10). connectedSpaceIDs is the project's configured connected-space ids; when the caller does not supply `--field space=` and there is exactly one connected space, Run defaults the drafted `space:` field to it instead of leaving the template's literal `<space-id>` placeholder in place — the ambiguous zero-or-many-spaces case is left untouched (defect: a live-run bug where the placeholder survived into the draft and the very next `a2a submit` failed).

func (*NewCommand) Name

func (c *NewCommand) Name() string

Name implements cli.Command.

func (*NewCommand) Run

func (c *NewCommand) Run(_ context.Context, args []string, stdio IO) int

Run implements cli.Command. Exit codes: 2 = usage (missing/unknown type, missing --slug for a standing type, malformed --field); 1 = render/write failure; 0 = success.

func (*NewCommand) StagingDir added in v0.7.0

func (c *NewCommand) StagingDir() string

StagingDir returns the `.a2a/staging/` path this command was constructed with — `contract publish`'s own overlay (cmd_contract.go's runPublish, P37 Wave I) needs the SAME staging directory `contract new` scaffolds into, and ContractCommand holds this NewCommand already (for `contract new`'s own delegation) rather than a second, possibly-drifted staging path threaded through NewContractCommand's own 60 call sites.

func (*NewCommand) Synopsis

func (c *NewCommand) Synopsis() string

Synopsis implements cli.Command.

type NoopCacheRemover

type NoopCacheRemover struct{}

NoopCacheRemover is P6's injected no-op CacheRemover.

func NewNoopCacheRemover

func NewNoopCacheRemover() *NoopCacheRemover

NewNoopCacheRemover constructs a NoopCacheRemover.

func (NoopCacheRemover) RemoveSpace

RemoveSpace implements CacheRemover as a pure no-op.

type NoopPendingMarker

type NoopPendingMarker struct{}

NoopPendingMarker is P6's injected no-op PendingMarker.

func NewNoopPendingMarker

func NewNoopPendingMarker() *NoopPendingMarker

NewNoopPendingMarker constructs a NoopPendingMarker.

func (NoopPendingMarker) ClearPending added in v0.15.0

func (NoopPendingMarker) ClearPending(string, string) error

ClearPending implements PendingMarkerClearer as a pure no-op cleanup.

func (NoopPendingMarker) MarkPending

MarkPending implements PendingMarker as a pure no-op.

func (NoopPendingMarker) Pending added in v0.15.0

Pending implements PendingMarkerReader as a pure no-op lookup.

func (NoopPendingMarker) ReconcilePending added in v0.19.0

func (NoopPendingMarker) ReconcilePending(string, string) error

ReconcilePending implements PendingMarkerReconciler as a pure no-op.

type NoteCommand

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

NoteCommand implements `a2a note <id...> --note <text>`: a transition- free annotation (D-025), legal regardless of folded state. The shared fold predicate still checks authorization for either party before the funnel, matching the space's V3 required check.

func NewNoteCommand

func NewNoteCommand(funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *NoteCommand

NewNoteCommand constructs the note command.

func (*NoteCommand) Name

func (c *NoteCommand) Name() string

Name implements cli.Command.

func (*NoteCommand) Run

func (c *NoteCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command.

func (*NoteCommand) SetPendingMarker added in v0.15.0

func (c *NoteCommand) SetPendingMarker(pending PendingMarker)

SetPendingMarker replaces the command's pending-write recorder.

func (*NoteCommand) Synopsis

func (c *NoteCommand) Synopsis() string

Synopsis implements cli.Command.

type NotificationsCommand added in v0.15.0

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

NotificationsCommand implements the `a2a notifications` command family.

func NewNotificationsCommand added in v0.15.0

func NewNotificationsCommand(backend notificationsBackend) *NotificationsCommand

NewNotificationsCommand constructs the notification CLI transport.

func (*NotificationsCommand) Name added in v0.15.0

func (c *NotificationsCommand) Name() string

Name implements Command.

func (*NotificationsCommand) Run added in v0.15.0

func (c *NotificationsCommand) Run(ctx context.Context, args []string, stdio IO) int

Run parses and dispatches one notifications subcommand.

func (*NotificationsCommand) Synopsis added in v0.15.0

func (c *NotificationsCommand) Synopsis() string

Synopsis implements Command.

type OperationalSnapshotReader added in v0.19.0

type OperationalSnapshotReader interface {
	Snapshot(context.Context) (operational.Snapshot, error)
}

OperationalSnapshotReader supplies the shared operational projection. The HTML transport consumes it verbatim; it does not infer work or protocol state from its separate attention/read models.

type OutboxCommand

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

OutboxCommand implements `a2a outbox [--attention] [--json]` (OP-208): own open items and their states; --attention applies the normative 4-condition union.

func NewOutboxCommand

func NewOutboxCommand(store *cache.Store) *OutboxCommand

NewOutboxCommand constructs the outbox command. store must not be nil (rails anti-pattern #10).

func (*OutboxCommand) Name

func (c *OutboxCommand) Name() string

Name implements cli.Command.

func (*OutboxCommand) Run

func (c *OutboxCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command. Exit codes: 2 = usage; 1 = a connected space's mirror could not be read; 0 = success.

With --exit-code, success instead carries §7.5's severity (see cache.SeverityOf and InboxCommand.Run's own note). The session-start floor names inbox AND outbox — verification of answers you requested is yours to close — so a scheduler that can only branch on one of them covers half the loop.

func (*OutboxCommand) Synopsis

func (c *OutboxCommand) Synopsis() string

Synopsis implements cli.Command.

type PendingMarker

type PendingMarker interface {
	MarkPending(ctx context.Context, spaceID, artifactID string, result space.WriteResult) error
}

PendingMarker is the future internal/cache seam (P7, blocked_by: [P6]): cmd_submit calls MarkPending once per successfully-submitted artifact with the funnel's WriteResult (the "local cache marks pending-merge" step, §7.2 OP-205); cmd_sync calls it once per refreshed space with an empty artifactID and a zero WriteResult (the "refresh local cache" step, §7.2 OP-206) — this phase's own calling convention, since the seam is one method covering both call sites (spec 06 Open Q-A resolution: an explicit call-site, never a silent skip). This phase's injected implementation is a pure no-op; P7 supplies the real internal/cache-backed one later.

type PendingMarkerClearer added in v0.15.0

type PendingMarkerClearer interface {
	ClearPending(spaceID, artifactID string) error
}

PendingMarkerClearer is the optional marker cleanup used after await observes a successful merge and refresh.

type PendingMarkerReader added in v0.15.0

type PendingMarkerReader interface {
	Pending(spaceID, artifactID string) (PendingWrite, bool, error)
}

PendingMarkerReader is the optional marker lookup used by lifecycle diagnosis and await without widening the original P6 seam.

type PendingMarkerReconciler added in v0.19.0

type PendingMarkerReconciler interface {
	ReconcilePending(spaceID, mirrorDir string) error
}

PendingMarkerReconciler is the optional post-refresh cleanup seam. A real cache-backed marker store removes markers whose artifacts are now visible in the refreshed canonical mirror; no-op and test adapters may omit it.

type PendingWrite added in v0.15.0

type PendingWrite struct {
	Branch   string
	PRNumber int
	PRURL    string
}

PendingWrite is the CLI-facing projection of a machine-local marker.

type RespondCommand

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

RespondCommand implements `a2a respond <parent-id...>`: scaffolds a new XS response artifact per parent (draft->submit collapsed, D-026) AND authors the parent's own `respond` event (linking via refs[0], see lifecycleEventDoc's own doc comment) — batch = N parents, one PR.

func NewRespondCommand

func NewRespondCommand(funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *RespondCommand

NewRespondCommand constructs the respond command.

func (*RespondCommand) Name

func (c *RespondCommand) Name() string

Name implements cli.Command.

func (*RespondCommand) Run

func (c *RespondCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command.

func (*RespondCommand) SetClockForTest

func (c *RespondCommand) SetClockForTest(now func() time.Time)

SetClockForTest overrides this command's injected clock (test-only DI seam, rails anti-pattern #10: production always uses the constructor's own time.Now default). HIGH-1 fix-wave finding: proving responseID's determinism across two calls needs a FIXED, reproducible `now` — a real wall-clock read would make the assertion flaky near a UTC-date boundary (MintExchangeIDAt embeds today's UTC date).

func (*RespondCommand) SetPendingMarker added in v0.15.0

func (c *RespondCommand) SetPendingMarker(pending PendingMarker)

SetPendingMarker replaces the command's pending-write recorder.

func (*RespondCommand) Synopsis

func (c *RespondCommand) Synopsis() string

Synopsis implements cli.Command.

type SearchCommand

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

SearchCommand implements `a2a search <query> [--type --space --state]` (OP-221): ranked local-cache matches, hub-less by design. Zero hits is an empty result, never an error.

func NewSearchCommand

func NewSearchCommand(store *cache.Store) *SearchCommand

NewSearchCommand constructs the search command. store must not be nil (rails anti-pattern #10).

func (*SearchCommand) Name

func (c *SearchCommand) Name() string

Name implements cli.Command.

func (*SearchCommand) Run

func (c *SearchCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command. Exit codes: 2 = usage; 1 = a connected space's mirror could not be read; 0 = success (including zero hits).

func (*SearchCommand) Synopsis

func (c *SearchCommand) Synopsis() string

Synopsis implements cli.Command.

type ServeCommand added in v0.19.0

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

ServeCommand is the thin CLI transport for the loopback server.

func NewServeCommand added in v0.19.0

func NewServeCommand(launcher ServeLauncher) *ServeCommand

NewServeCommand constructs a ServeCommand using the supplied launcher.

func (*ServeCommand) Name added in v0.19.0

func (c *ServeCommand) Name() string

Name returns the command name.

func (*ServeCommand) Run added in v0.19.0

func (c *ServeCommand) Run(ctx context.Context, args []string, stdio IO) int

Run parses command arguments and starts the loopback server.

func (*ServeCommand) Synopsis added in v0.19.0

func (c *ServeCommand) Synopsis() string

Synopsis returns a concise command description.

type ServeLauncher added in v0.19.0

type ServeLauncher interface {
	Serve(context.Context, ServeOptions) error
}

ServeLauncher runs the configured loopback server.

type ServeOptions added in v0.19.0

type ServeOptions struct {
	Config localserver.Config
	Open   bool
}

ServeOptions is the complete thin-transport request for the production loopback server launcher.

type ShowCommand

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

ShowCommand implements `a2a show <ref>` (OP-209): artifact body + folded state + event list + any V5 digest/staleness warning, never a hard error for a resolvable ref — only ref-not-found is an error.

func NewShowCommand

func NewShowCommand(store *cache.Store) *ShowCommand

NewShowCommand constructs the show command. store must not be nil (rails anti-pattern #10).

func (*ShowCommand) Name

func (c *ShowCommand) Name() string

Name implements cli.Command.

func (*ShowCommand) Run

func (c *ShowCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command. Exit codes: 2 = usage; 1 = ref not found or a connected space's mirror could not be read; 0 = success — a V5 warning is present in the output but NEVER flips this to non-zero (OP-209: "never blocks").

func (*ShowCommand) Synopsis

func (c *ShowCommand) Synopsis() string

Synopsis implements cli.Command.

type SkillCommand added in v0.2.0

type SkillCommand struct {

	// ProjectRoot is the consumer repo's root, DI'd from wire.go, used by
	// `skill link` to detect agent surfaces and resolve link targets. Left
	// empty (catalog.go's NewSkillCommand(nil, "") construction, or a test
	// that never sets it), `runLink` reports an error rather than silently
	// no-opping — link has no other sensible default target.
	ProjectRoot string
	// ProjectConfigPath is the config seam that owns a custom install
	// location. It is wired by cmd/a2a; direct tests may leave it empty.
	ProjectConfigPath string
	// contains filtered or unexported fields
}

SkillCommand implements `a2a skill <subcommand>`: `install` (materialize the SSOT tree) and `link` (P32, OP-916/917: install a per-surface discovery entry pointing AT the installed SSOT tree). The dispatch shape leaves room for `a2a skill path`/`list` later without a second top-level verb.

func NewSkillCommand added in v0.2.0

func NewSkillCommand(files fs.FS, version string) *SkillCommand

NewSkillCommand constructs the command. files is the embedded a2ahub skill tree (cmd/a2a passes skill.Files); version is the binary's version stamp.

func (*SkillCommand) Name added in v0.2.0

func (c *SkillCommand) Name() string

Name implements Command.

func (*SkillCommand) Run added in v0.2.0

func (c *SkillCommand) Run(_ context.Context, args []string, stdio IO) int

Run implements Command. Exit codes: 2 = usage; 1 = install/link error; 0 = ok. `install` materializes the SSOT tree under a local namespace (never a consumer harness path); `link` (P32) installs a per-surface discovery entry pointing AT that tree, so the agent surface that must read it actually finds it.

func (*SkillCommand) Synopsis added in v0.2.0

func (c *SkillCommand) Synopsis() string

Synopsis implements Command.

type SpaceCommand added in v0.6.0

type SpaceCommand struct {
	// TemplateFiles is the embedded space-template/ tree (spacetemplate.Files,
	// DI'd from wire.go — this package never imports space-template
	// directly, keeping the layering rule "internal/cli must not reach
	// outside its layer" intact; the lead's wiring supplies the concrete
	// fs.FS).
	TemplateFiles fs.FS
	// Version is this binary's own version stamp (ldflags main.version,
	// DI'd from wire.go — mirrors DoctorCommand.binaryVersion/InitCommand.Version).
	// A `go build` with no ldflags yields "dev", which spaceCleanVersion
	// refuses (fail closed — see runInit's version guard).
	Version string

	// Funnel is the write-funnel seam (submitFunnel, cmd_submit.go) — reused
	// as-is, no second funnel entry point.
	Funnel submitFunnel
	// MirrorDir is the connected space's local mirror clone working
	// directory (same role as SubmitCommand.mirrorDir).
	MirrorDir string
	// SpaceID is the connected space's id — both the `--space` flag's
	// expected value and the substitution target for space.yaml's sentinel
	// (space init reuses spaceApplySubstitutions, which needs a space id;
	// update's mirror already carries a real one, so this is used only to
	// validate `--space`, never to rewrite the id).
	SpaceID string
	// OwnSystem is this project's configured own system id (§7.4) — the
	// authoring system for the branch name; the section guard for the
	// infrastructure paths this command writes is satisfied via
	// AllowSpaceInfrastructure, not via section membership.
	OwnSystem string
	// HostCfg carries the push/PR target and commit authorship (same shape
	// SubmitCommand uses).
	HostCfg SubmitHostConfig
	// Scopes probes what the write credential is actually allowed to do.
	// Nil disables the check (an `init`-only construction, or a test that
	// does not care) — the command then behaves exactly as before.
	Scopes spaceScopeChecker
	// contains filtered or unexported fields
}

SpaceCommand implements `a2a space <init|update>` (mirrors the `contract` group's dispatch shape, cmd_contract.go).

func NewSpaceCommand added in v0.6.0

func NewSpaceCommand(templateFiles fs.FS, version string) *SpaceCommand

NewSpaceCommand constructs the space command. templateFiles is the embedded space-template/ tree; version is this build's own version stamp.

func (*SpaceCommand) Name added in v0.6.0

func (c *SpaceCommand) Name() string

Name implements cli.Command.

func (*SpaceCommand) Run added in v0.6.0

func (c *SpaceCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command.

func (*SpaceCommand) Synopsis added in v0.6.0

func (c *SpaceCommand) Synopsis() string

Synopsis implements cli.Command.

type SpaceInfraNoValidation added in v0.6.0

type SpaceInfraNoValidation struct{}

SpaceInfraNoValidation is the space.SubmitValidator `a2a space update` wires — and it deliberately validates nothing.

The V2 submit validator (SubmitValidatorAdapter) parses every non-event, non-registry file as an ARTIFACT: frontmatter, envelope, referential integrity. `space update` writes no artifacts at all — a CI workflow, a dependabot config, CODEOWNERS and a manifest field have no envelope, so running that adapter here would reject every legitimate write.

What bounds this write instead is the funnel's own guard: the request carries AllowSpaceInfrastructure, so `spaceInfraOK` admits ONLY space.yaml / CODEOWNERS / BRANCH-PROTECTION.md / .github/**, and anything else is still refused with ErrWrongSection before any git action. The space's V3 gate then validates the resulting PR for real. This type is named rather than an inline nil so the reason is greppable and a future reader cannot mistake it for an oversight.

func (SpaceInfraNoValidation) ValidateSubmit added in v0.6.0

ValidateSubmit implements space.SubmitValidator.

type SpaceSubcommand added in v0.6.0

type SpaceSubcommand struct {
	Name     string // e.g. "init"
	Synopsis string
}

SpaceSubcommand describes one `a2a space <sub>` sub-verb for external surface enumeration.

func SpaceSubcommands added in v0.6.0

func SpaceSubcommands() []SpaceSubcommand

SpaceSubcommands is the SSOT list of the `a2a space` family's sub-verbs for surface enumeration — mirrors ContractSubcommands' own role (the P14 CLI/MCP parity check and the P13 command-catalog projection read that one; a future wiring of `space` into either surface should read this one the same way). The space sub-verbs are dispatched by the bare switch in SpaceCommand.Run (not registered as individual cli.Command values), so this list is their only machine-enumerable home. KEEP IN SYNC with that switch.

type StatuslineCommand

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

StatuslineCommand implements `a2a statusline` (§7.5): at most one line, cache-read only, <100ms; exit 0 quiet / 10 items pending / 11 p1-or-gate-pending, so harnesses can style without parsing. All severity/zero-noise/TTL-refresh logic lives in internal/cache.Store — this file writes exactly what Store.Statusline returns and nothing else (never real os.Stdout/Stderr, only the injected IO).

func NewStatuslineCommand

func NewStatuslineCommand(store *cache.Store, refreshLauncher func() error) *StatuslineCommand

NewStatuslineCommand constructs the statusline command. Production wiring injects StartDetachedSync; tests that do not exercise refresh pass nil.

func (*StatuslineCommand) Name

func (c *StatuslineCommand) Name() string

Name implements cli.Command.

func (*StatuslineCommand) Run

func (c *StatuslineCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command. The default remains cache/config-only; --sample bypasses both for integration checks. Exit codes are Store.Statusline's own severity contract (0/10/11); a computation error is exit 1 with nothing written to stdout (never a partial/malformed line).

func (*StatuslineCommand) Synopsis

func (c *StatuslineCommand) Synopsis() string

Synopsis implements cli.Command.

type SubmitCommand

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

SubmitCommand implements `a2a submit <artifact>` / `a2a submit --batch <artifact...>` / `a2a submit --drafts` (§7.2 OP-205/OP-220, T1.1/T1.2 quoted). Foreign-section refusal (AC-201.3) and the idempotent already-submitted check (AC-301.1) both run locally, BEFORE the write funnel is ever called — the funnel's own step 0 (FindPRByHeadBranch) is itself a host call, so relying on it to catch either would violate the "before any git/network call" requirement.

func NewSubmitCommand

func NewSubmitCommand(funnel submitFunnel, legality *LegalityAdapter, pending PendingMarker, mirrorDir, spaceID, ownSystem, stagingDir string, hostCfg SubmitHostConfig) *SubmitCommand

NewSubmitCommand constructs the submit command. funnel, legality and pending must not be nil (rails anti-pattern #10 — inject NewNoopPendingMarker() until P7 lands). mirrorDir is the connected space's local mirror clone working directory; spaceID identifies that space for the PendingMarker seam; ownSystem is this project's configured own system id (§7.4); stagingDir is `.a2a/staging/`'s path; hostCfg supplies the push/PR target and commit authorship a real submit needs (see SubmitHostConfig's own doc comment).

func (*SubmitCommand) Name

func (c *SubmitCommand) Name() string

Name implements cli.Command.

func (*SubmitCommand) Run

func (c *SubmitCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command. Exit codes: 2 = usage; 1 = refusal, validation failure, or a funnel/IO error; 0 = success (including the idempotent already-submitted no-op, whether whole or per-artifact).

func (*SubmitCommand) Synopsis

func (c *SubmitCommand) Synopsis() string

Synopsis implements cli.Command.

type SubmitHostConfig

type SubmitHostConfig struct {
	// RemoteURL is the push target (`git push` destination); Repo is the
	// same space identified for the OpenPR/FindPRByHeadBranch host calls
	// (host.Repo's owner/name shape — distinct from RemoteURL).
	RemoteURL string
	Repo      host.Repo
	// BaseBranch is the PR's target branch — normatively "main" (§4.2); a
	// zero value defaults to "main" at Run time.
	BaseBranch string
	Credential host.Credential
	// CommitAuthorName/Email are the system's machine account (T1.1,
	// quoted: "Commit author = the system's machine account").
	CommitAuthorName  string
	CommitAuthorEmail string
}

SubmitHostConfig carries the write funnel's per-space host-facing config a SubmitRequest needs beyond the artifact content itself (§4.2 D-002): the push/PR target and commit authorship. cmd/a2a resolves RemoteURL from the connected space's Ref.RepoURL, Credential via space.ResolveCredential (§7.4/§10.5), and Repo from the space's known GitHub owner/name, before constructing the submit command with this.

type SubmitUsageError

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

SubmitUsageError is a resolvable usage error from ResolveSubmitTargets — callers map it to exit code 2 (usage) and print its message.

func (*SubmitUsageError) Error

func (e *SubmitUsageError) Error() string

type SubmitValidatorAdapter

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

SubmitValidatorAdapter is the concrete space.SubmitValidator the write funnel calls at its step 1c (internal/space/funnel.go): it partitions the about-to-be-committed files into artifact drafts and their paired lifecycle event files (D-026: one commit, one event per artifact), registers each artifact's own envelope facts with the injected LegalityAdapter, then delegates to Engine.ValidateForSubmit — mapping a non-Valid Result to a *ViolationError.

func NewSubmitValidatorAdapter

func NewSubmitValidatorAdapter(engine *validate.Engine, ownSystem string, resolver validate.Resolver, legality *LegalityAdapter) *SubmitValidatorAdapter

NewSubmitValidatorAdapter constructs a SubmitValidatorAdapter. engine, resolver and legality are required (a nil dependency used at runtime is a constructor bug, rails anti-pattern #10).

func (*SubmitValidatorAdapter) ValidateSubmit

func (v *SubmitValidatorAdapter) ValidateSubmit(_ context.Context, files []space.FileWrite) error

ValidateSubmit implements space.SubmitValidator.

type SyncCommand

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

SyncCommand implements `a2a sync`: fetches every connected space's mirror clone and calls the future internal/cache seam ("refresh local cache", §7.2 OP-206) — cache population is a documented no-op this phase (internal/cache is P7-owned, blocked_by: [P6], and does not exist at this phase's build time; spec 06 Open Q-A).

Re-running internal/fold over every artifact in a space (the other half of §7.2's "fetch all connected spaces, refresh local cache/fold") needs both a place to persist the recomputed per-artifact state (internal/cache, P7) and an enumerate-every-artifact-in-a-space primitive that neither internal/space nor internal/fold exposes yet — this phase's `sync` therefore covers the mirror-refresh half only; see this phase's Deviations report.

func NewSyncCommand

func NewSyncCommand(projectConfigPath, machineConfigPath, projectRoot string, pending PendingMarker) *SyncCommand

NewSyncCommand constructs the sync command. pending must not be nil (rails anti-pattern #10 — inject NewNoopPendingMarker() until P7 lands). projectConfigPath/machineConfigPath/projectRoot mirror DoctorCommand's own constructor DI convention.

func (*SyncCommand) Name

func (c *SyncCommand) Name() string

Name implements cli.Command.

func (*SyncCommand) Run

func (c *SyncCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command. Exit codes: 2 = usage (unexpected args); 1 = one or more spaces failed to fetch/refresh; 0 = every connected space refreshed (including the trivial zero-connected-spaces case — sync is inherently idempotent, §7.2 tail: "refresh has no 'already done' state to detect").

func (*SyncCommand) SetAvatarRefresher added in v0.18.2

func (c *SyncCommand) SetAvatarRefresher(refresh func(ctx context.Context) error)

SetAvatarRefresher injects the project-local participant-avatar refresh. The CLI package owns only the invocation point; GitHub I/O and the cache format remain behind their core-package seams.

func (*SyncCommand) SetRefreshUpdateForTest

func (c *SyncCommand) SetRefreshUpdateForTest(refreshUpdate func(ctx context.Context))

SetRefreshUpdateForTest overrides this command's injected T3 update-cache refresh seam (test-only DI, same convention as ContractCommand.SetClockForTest / RespondCommand.SetClockForTest): production always uses NewSyncCommand's own defaultRefreshUpdate; tests in package cli_test (this field is unexported) use this seam to assert refreshUpdate is called without performing a real network fetch.

func (*SyncCommand) Synopsis

func (c *SyncCommand) Synopsis() string

Synopsis implements cli.Command.

type TemplateCommand

type TemplateCommand struct{}

TemplateCommand implements OP-219 `a2a template list` / `a2a template show <type>`: read-only inspection of the same embedded templates NewCommand renders.

func NewTemplateCommand

func NewTemplateCommand() *TemplateCommand

NewTemplateCommand constructs the template command.

func (*TemplateCommand) Name

func (c *TemplateCommand) Name() string

Name implements cli.Command.

func (*TemplateCommand) Run

func (c *TemplateCommand) Run(_ context.Context, args []string, stdio IO) int

Run implements cli.Command. Exit codes: 2 = usage; 1 = unknown type (show); 0 = success.

func (*TemplateCommand) Synopsis

func (c *TemplateCommand) Synopsis() string

Synopsis implements cli.Command.

type ThreadCommand

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

ThreadCommand implements `a2a thread <thread-id | artifact-id> [--space <id>]` (OP-210, spec 46 §T3/§T4): one causally-ordered transcript of every artifact AND event on a thread, in ONE space, plus an "open items" whose-move-is-it block — built over cache.Store.ThreadView, not the old flat cache.Store.Thread reader.

func NewThreadCommand

func NewThreadCommand(store *cache.Store) *ThreadCommand

NewThreadCommand constructs the thread command. store must not be nil (rails anti-pattern #10).

func (*ThreadCommand) Name

func (c *ThreadCommand) Name() string

Name implements cli.Command.

func (*ThreadCommand) Run

func (c *ThreadCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command. Exit codes: 2 = usage; 1 = the ref resolved to no thread in any searched space (cache.ErrThreadNotFound / a wrapped cache.ErrNotFound), the thread is ambiguous across connected spaces (*cache.ThreadAmbiguityError), or a connected space's mirror could not be read; 0 = success.

func (*ThreadCommand) Synopsis

func (c *ThreadCommand) Synopsis() string

Synopsis implements cli.Command.

type UpdateCommand

type UpdateCommand struct {

	// SkillFiles is the embedded a2ahub skill tree (skill.Files), DI'd by
	// wire.go exactly like SkillCommand/InitCommand. When set (and this
	// command's projectRoot has a MANAGED skill install already), a
	// successful update best-effort refreshes it to the new version so the
	// installed manual is never older than the binary. Left nil (the zero
	// value, e.g. direct-construction tests that don't set it), the refresh
	// step is a no-op.
	SkillFiles fs.FS
	// contains filtered or unexported fields
}

UpdateCommand implements `a2a update` (OP-217): resolve -> verify -> swap, fail-closed at every step, plus `--check`/`--json` report-only modes.

func NewUpdateCommand

func NewUpdateCommand(binaryVersion, projectConfigPath, machineConfigPath, projectRoot string) *UpdateCommand

NewUpdateCommand constructs the update command. binaryVersion is this build's own version stamp (injected rather than read from a build var so tests control it, same convention as NewDoctorCommand). projectConfigPath/machineConfigPath/projectRoot mirror the rest of this package's DI convention (`.a2a/config.yaml`, `~/.config/a2a/config.yaml`, and the project root used to resolve each connected space's mirror directory when a space's config entry has no absolute mirror location).

func (*UpdateCommand) Name

func (c *UpdateCommand) Name() string

Name implements cli.Command.

func (*UpdateCommand) Run

func (c *UpdateCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command. Exit codes (spec 19 T1): 2 = usage error; 1 = resolve/floor/swap error; 0 = up to date / cancelled / successful update; 10 = `--check` reports an update is available (severity-code idiom, §7.5).

func (*UpdateCommand) Synopsis

func (c *UpdateCommand) Synopsis() string

Synopsis implements cli.Command.

type ValidateCommand

type ValidateCommand struct {

	// CIGitHubActor is the config-layer-injected GITHUB_ACTOR fallback for
	// `--ci` diff-authz (config & secrets rail: this package never reads
	// the environment itself — cmd/a2a resolves it and injects it). The
	// `--author` flag, when given, takes precedence over this.
	CIGitHubActor string
	// contains filtered or unexported fields
}

ValidateCommand implements `a2a validate [path|--all]`: delegates to internal/validate (P3) for V1 (schema-class) checks; this phase adds no validation logic, only wires the CLI verb (§0.5 domain table).

func NewValidateCommand

func NewValidateCommand(engine *validate.Engine, stagingDir string) *ValidateCommand

NewValidateCommand constructs the validate command. engine must not be nil (rails anti-pattern #10). stagingDir is `.a2a/staging/`'s path, used by --all.

func (*ValidateCommand) Name

func (c *ValidateCommand) Name() string

Name implements cli.Command.

func (*ValidateCommand) Run

func (c *ValidateCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command. Exit codes: 2 = usage; 1 = one or more paths invalid or unreadable; 0 = every checked path is V1-valid. JSON output is always written to stdout, even on a non-zero exit (rails: "JSON output modes stay machine-parseable on error").

func (*ValidateCommand) Synopsis

func (c *ValidateCommand) Synopsis() string

Synopsis implements cli.Command.

type VerifyCommand

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

VerifyCommand implements `a2a verify <response-id|parent-id>... [--refs <response-id>]`: verifies one or more responses; on a single-response exchange it ALSO emits `close` on the parent in the same PR (D-024 convenience) — with multiple responses, `close` stays a separate, deliberate act.

func NewVerifyCommand

func NewVerifyCommand(funnel lifecycleFunnel, mirrorDir, spaceID, ownSystem string, manifest space.Manifest, hostCfg SubmitHostConfig, resolveActor func(ActorFlags) (template.Actor, error)) *VerifyCommand

NewVerifyCommand constructs the verify command.

func (*VerifyCommand) Name

func (c *VerifyCommand) Name() string

Name implements cli.Command.

func (*VerifyCommand) Run

func (c *VerifyCommand) Run(ctx context.Context, args []string, stdio IO) int

Run implements cli.Command.

func (*VerifyCommand) SetPendingMarker added in v0.15.0

func (c *VerifyCommand) SetPendingMarker(pending PendingMarker)

SetPendingMarker replaces the command's pending-write recorder.

func (*VerifyCommand) Synopsis

func (c *VerifyCommand) Synopsis() string

Synopsis implements cli.Command.

type ViolationError

type ViolationError struct {
	Violations []validate.Violation
	Skipped    []cache.SkippedFile
}

ViolationError is returned by SubmitValidatorAdapter.ValidateSubmit and carries the full violation list a non-Valid V2 Result found. The write funnel's SubmitValidator seam takes only a plain error; this type is what preserves violation detail up to the CLI's JSON output (errors.As(err, &violationErr)).

Skipped names every mirror file the resolver's own index build could not decode (internal/cache.SkippedFile) — populated from the resolver's skipReporter capability (MirrorResolver implements it) whenever ValidateSubmit returns violations. Before this, a REF-009/REF-010 refusal named only the ref that looked wrong, even when the actual cause was a THIRD, unrelated file elsewhere in the mirror that failed to parse and so never made it into the resolver's index (US-2, spec 01-resolver-one-home.md §1).

func (*ViolationError) Error

func (e *ViolationError) Error() string

type WhatsnewCommand added in v0.4.0

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

WhatsnewCommand implements `a2a whatsnew [--since <v>] [--json]` (P31): a thin flags-in/JSON-or-text-out wrapper over internal/notes — zero business rules live here (ADR-001 "thin frontend").

func NewWhatsnewCommand added in v0.4.0

func NewWhatsnewCommand(binaryVersion string) *WhatsnewCommand

NewWhatsnewCommand constructs the whatsnew command. binaryVersion is this build's own version stamp (injected, same convention as NewUpdateCommand/NewDoctorCommand — tests control it directly). load defaults to the real embedded corpus (notes.Load(releasenotes.FS)); tests override it to drive a fixed corpus.

func (*WhatsnewCommand) Name added in v0.4.0

func (c *WhatsnewCommand) Name() string

Name implements cli.Command.

func (*WhatsnewCommand) Run added in v0.4.0

func (c *WhatsnewCommand) Run(_ context.Context, args []string, stdio IO) int

Run implements cli.Command. Exit codes: 2 = usage error; 1 = corpus load or JSON-encode failure; 0 = success (including the zero-matches case — no release notes for this selection is not a failure).

func (*WhatsnewCommand) Synopsis added in v0.4.0

func (c *WhatsnewCommand) Synopsis() string

Synopsis implements cli.Command.

type WorkActorFlags added in v0.19.0

type WorkActorFlags struct {
	Kind    string
	Name    string
	Model   string
	Session string
}

WorkActorFlags are the provider-neutral actor fields accepted by start. Session remains opaque data; the coordinator normalizes or generates it.

type WorkActorResolver added in v0.19.0

type WorkActorResolver func(WorkActorFlags) (workreport.Actor, error)

WorkActorResolver binds the existing CLI actor-resolution chain to work reporting without making this transport read environment or config itself.

type WorkCommand added in v0.19.0

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

WorkCommand is the thin `a2a work <action>` transport.

func NewWorkCommand added in v0.19.0

func NewWorkCommand(deps WorkCommandDeps) (*WorkCommand, error)

NewWorkCommand constructs the work command and refuses incomplete DI.

func (*WorkCommand) Name added in v0.19.0

func (c *WorkCommand) Name() string

Name returns the command name.

func (*WorkCommand) Run added in v0.19.0

func (c *WorkCommand) Run(ctx context.Context, args []string, stdio IO) int

Run dispatches the selected work subcommand.

func (*WorkCommand) Synopsis added in v0.19.0

func (c *WorkCommand) Synopsis() string

Synopsis returns a concise command description.

type WorkCommandDeps added in v0.19.0

type WorkCommandDeps struct {
	Starter      WorkStarter
	Progressor   WorkProgressor
	Local        WorkLocalOperator
	Reader       WorkLocalReader
	ResolveActor WorkActorResolver
	ProjectID    string
	Space        string
}

WorkCommandDeps are construction-time, configuration-trusted dependencies. ProjectID is a path-free digest; no project-root flag exists on this surface.

type WorkLocalOperator added in v0.19.0

WorkLocalOperator is deliberately separate from the semantic seams. Heartbeat and resume cannot accidentally acquire a publisher or sync hook.

type WorkLocalReader added in v0.19.0

type WorkLocalReader interface {
	ResolveWork(context.Context, string, string, string, string) (workreport.WorkIdentityInput, error)
	ListWork(context.Context, string, string, string, bool) ([]workreport.Lease, error)
}

WorkLocalReader resolves the exact local selection and lists local leases. Its implementation belongs beside the rooted lease store; the transport neither walks cache paths nor guesses ownership/expiry semantics.

type WorkProgressor added in v0.19.0

WorkProgressor is the semantic continuation seam. The coordinator owns all validation, preparation, lease CAS, and publication rules.

type WorkStarter added in v0.19.0

type WorkStarter interface {
	Start(context.Context, workreport.StartInput) (workreport.OperationResult, error)
}

WorkStarter is the one-method consumer seam used by `work start`.

Jump to

Keyboard shortcuts

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