You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
guild-cli started as "a small file-based CLI for a team of agents to file requests, review them, and leave an append-only trail." The 0.3.x stream has closed most of the first-touch friction (see #30, #31, #32, #33, #34, #35): misconfigured-cwd detection, severity/verdict/lense aliases, gate register, message/inbox guild-flow hints, content_root_health.
The core (request / review / issue / message lifecycle with Two-Persona Devil discipline) now has enough dogfood surface to start thinking about the next structural investments — the things that will let the tool grow without losing its local-first, human-readable, git-native shape.
This is a living roadmap. Individual Phases should be split into their own issues as they approach; this meta-issue exists so contributors can reason about each Phase in the context of the whole.
Status (as of 2026-05-09)
Reconciliation against current main. Phases 1 and 2 fully shipped; Phases 3 and 4 deferred per the original spec.
Phase 1 — Extension points ✅ shipped
Prior-art loader pattern (DoctorPluginContext / DoctorPluginFn in src/application/diagnostic/DiagnosticUseCases.ts)
Outstanding: Content transforms (on:save / on:load around YAML I/O) — sketched in the original Phase 1 plan but not yet shipped. Treated as Phase 4 territory now since the post-#36 dogfood didn't surface a concrete need; spin up a focused sub-issue when index-rebuild / derived-field use cases actually emerge.
Per the spec, deferred until Phases 1 + 2 are stable (now true). No work landed yet. Spin up sub-issues when concrete cross-content_root use cases surface.
Phase 4 — Event fabric 🔒 deferred
Outbound primitive (lifecycle hooks) is now in place via Phase 1. Inbound (gate import, inbound-events/, source: external) and content transforms (deferred from Phase 1) are the two remaining seams. Spin up sub-issues when concrete external integrations are wanted.
Adjacent work that landed alongside
Several feature waves shipped during Phases 1+2 even though they sit outside the original roadmap — capturing them so the roadmap stays a faithful index of the substrate:
Design principles (stable; use these to resolve ambiguity)
1 file = 1 capability. Members, requests, issues, reviews, doctor plugins — all one YAML/TS file per unit. Extension points should preserve this shape.
Local-first, human-readable, git-native. No DB. No network. The content_root is the whole world. Git gives history.
Append-only semantics. Corrections are new entries, not edits. status_log grows monotonically.
Stable surface, evolving infrastructure. The domain layer (Member, Request, Review, Verdict, Lense, Issue) is patch-bump stable per docs/POLICY.md. Extensions go through interface/infrastructure, not by mutating domain types.
Phases
Phase 1 — Extension points
Goal: let adopters add verbs, lifecycle reactions, and content transforms without forking.
Three extension surfaces, ordered by impact:
Verb plugins (.guild/plugins/verbs/*.mjs): load at CLI startup, register new verb names into the dispatch table in src/interface/gate/index.ts. Each plugin exports { name, category, summary, input, output, run(c, args) } — the same shape VerbSchema already uses for built-in verbs. Must also appear in gate schema output so LLM tool layers discover them.
Lifecycle hooks (.guild/plugins/hooks/*.mjs): invoked synchronously around request state transitions (before:approve, after:complete, after:review, etc). Hooks receive the request + transition context, may return { allow: false, reason } to veto (policy enforcement) or emit side-effects (write to inbox, notify external system). Must not block the transition on slow I/O — if a hook needs network, spawn and return.
Content transforms (.guild/plugins/transforms/*.mjs): invoked before YAML serialization (on:save) and after deserialization (on:load). Use case: index rebuild, derived field computation. Must be idempotent.
All three reuse the existing doctor plugins loading pattern (see src/application/diagnostic/DiagnosticUseCases.ts) — ES module paths listed in guild.config.yaml under plugins:. Plugin execution is sandboxed only by Node's module system; document the trust model in SECURITY.md.
Acceptance criteria:
A minimal example plugin (verb, hook, transform — one of each, under examples/plugins/) that works end-to-end.
gate schema surfaces plugin verbs with a source: plugin marker so a consumer can distinguish.
gate doctor reports plugin load failures without breaking the CLI.
docs/POLICY.md gets a paragraph on plugin stability (additive only, no renaming the hook signature without a minor bump).
Phase 2 — Time-aware verbs
Goal: make the passage of time a first-class record, not an implicit side effect of logging.
Candidate verbs (exact names / semantics TBD in sub-issues):
gate rest — boundary record. Not a lifecycle toggle; just "I am putting this down now." Timestamps only; no mandatory wake note (that would turn it into reflect). Rationale: the length of a break is itself information, the way a commit timestamp is information.
gate wake — optional pairing verb that says "I am picking things back up." Decoupled from rest so they don't have to be used together.
gate farewell — ceremonial close meant to be paired with gate resume at the next session start. Different from rest because it is "until next session," not "until later today."
gate resume (exists) — reads the last voice / transition / open loops, composes restoration prose. May gain interaction with rest / wake / farewell records.
Why time-aware verbs at all: agents (human or AI) accumulate fatigue or context drift inside long sessions. Marking the boundaries in-band lets downstream verbs (tail, voices, resume) render the session with the boundaries visible, which changes how the next reader experiences the history.
Interaction with Claude Code's compact + preserved-tail-relinking and with multi-session workflows is an open design question. Spin up a sub-issue when Phase 1 is ready to merge.
Phase 3 — Multi-guild / federation
Goal: let a content_root reference records in another content_root without losing append-only guarantees.
Sketch: gate federate <path> publishes a read-only reference. show / tail / voices can walk cross-root when the reference is resolvable. Actors can belong to multiple guilds; pair-mode (--with) can refer to actors from federated roots.
This is the structural answer to "small pairs would silo themselves" — the tool should let neighboring pairs see each other's work without collapsing into a single content_root.
Defer concrete spec until Phase 1 + 2 are stable; federation affects every reader verb.
Phase 4 — Event fabric (external integrations)
Goal: bidirectional bridges between guild-cli and external systems — MCP, Slack, GitHub, etc — without making those systems authoritative.
Outbound: lifecycle hooks (Phase 1) already handle the side. Just add documented conventions for where to send.
Inbound: gate import <event> or an inbound-events/ directory that plugins drain. Imported events become first-class records (with source: external in YAML) but are auditable as such.
Authoritative store always stays in content_root/. External systems are views or feeds, never truth.
Out of scope (for this roadmap)
Specific persona scaffolding, voice characters, or identity-specific verbs. Those belong in downstream adopters' plugin sets, not in core.
Semantic search / embedding-based retrieval. grep + filters is intentionally the search story.
Database backend. Not happening.
GUI / web UI. Separate project if it appears.
How contributors should proceed
Phases 1 + 2 are now shipped; the natural next-frontier work is Phase 3 (federation) or Phase 4 (inbound events / content transforms) when concrete dogfood pain demands them. Both are deferred until that pain emerges.
When in doubt about a design choice, resolve toward the five principles above.
The existing onboarding-hint pattern (vertical-format errors, hints.* fields on reads, actionable error messages) is how "this feature is discoverable" shows up in this codebase. New surfaces should carry the same pattern.
Context
guild-clistarted as "a small file-based CLI for a team of agents to file requests, review them, and leave an append-only trail." The 0.3.x stream has closed most of the first-touch friction (see #30, #31, #32, #33, #34, #35): misconfigured-cwd detection, severity/verdict/lense aliases,gate register, message/inbox guild-flow hints,content_root_health.The core (
request/review/issue/messagelifecycle with Two-Persona Devil discipline) now has enough dogfood surface to start thinking about the next structural investments — the things that will let the tool grow without losing its local-first, human-readable, git-native shape.This is a living roadmap. Individual Phases should be split into their own issues as they approach; this meta-issue exists so contributors can reason about each Phase in the context of the whole.
Status (as of 2026-05-09)
Reconciliation against current
main. Phases 1 and 2 fully shipped; Phases 3 and 4 deferred per the original spec.Phase 1 — Extension points ✅ shipped
DoctorPluginContext/DoctorPluginFninsrc/application/diagnostic/DiagnosticUseCases.ts)doctor.trusted: trueis required to loaddoctor.plugins, otherwise warned (feat: gate summarize + gate why + plugin trusted guard #90)gate schemaintrospection surface with theVERBStable +source: 'core' | 'plugin'marker (docs + groundwork: plugin stability / trust model / VerbSchema source (#36 Phase 1 step 1-3) #257)gate doctorabsorbs plugin failures as findings without crashing.guild/plugins/verbs/*.mjsregistered into the dispatch table vialoadVerbPlugins(feat(gate): verb plugin loader (#36 Phase 1 step 4) #258)before:/after:bus wired into request / claim / witness handlers, with veto propagation (feat(gate): lifecycle hooks bus (#36 Phase 1 step 5) #259)gate schemasource: pluginmarker onVerbSchema(docs + groundwork: plugin stability / trust model / VerbSchema source (#36 Phase 1 step 1-3) #257)examples/plugins/end-to-end example — verb + policy-veto hook with README walkthrough (docs(examples): plugins README + policy-veto hook example (#36 Phase 1 step 7) #260)docs/POLICY.mdplugin-stability paragraph (docs + groundwork: plugin stability / trust model / VerbSchema source (#36 Phase 1 step 1-3) #257)SECURITY.mdplugin trust-model section (docs + groundwork: plugin stability / trust model / VerbSchema source (#36 Phase 1 step 1-3) #257)Outstanding: Content transforms (
on:save/on:loadaround YAML I/O) — sketched in the original Phase 1 plan but not yet shipped. Treated as Phase 4 territory now since the post-#36 dogfood didn't surface a concrete need; spin up a focused sub-issue when index-rebuild / derived-field use cases actually emerge.Phase 2 — Time-aware verbs ✅ shipped
gate resume(already shipped pre-Roadmap: extension points + time-aware verbs + federation + event fabric #36,src/interface/gate/handlers/resume.ts)gate rest— boundary record (feat(gate): gate rest — boundary record (#36 Phase 2 step 1) #261)gate wake— pairing verb to rest (feat(gate): gate wake — pairing verb to rest (#36 Phase 2 step 2) #262)gate farewell— ceremonial close (feat(gate): gate farewell — ceremonial close (#36 Phase 2 step 3) #263)gate resumeintegration with rest / wake / farewell records — surfaces session boundary in restoration prose (feat(gate resume): surface session boundary in restoration prose (#36 Phase 2 follow-up) #264)Phase 3 — Multi-guild / federation 🔒 deferred
Per the spec, deferred until Phases 1 + 2 are stable (now true). No work landed yet. Spin up sub-issues when concrete cross-content_root use cases surface.
Phase 4 — Event fabric 🔒 deferred
Outbound primitive (lifecycle hooks) is now in place via Phase 1. Inbound (
gate import,inbound-events/,source: external) and content transforms (deferred from Phase 1) are the two remaining seams. Spin up sub-issues when concrete external integrations are wanted.Adjacent work that landed alongside
Several feature waves shipped during Phases 1+2 even though they sit outside the original roadmap — capturing them so the roadmap stays a faithful index of the substrate:
gate claimPR feat(gate): claim verb for cross-session stake (#226 phase 1 — claim only, witness deferred) #243,gate witnessPR feat(gate): witness verb (#226 phase 2) + concurrency safety #247) + design(gate stake verbs): claim / witness / unwitness に --note を許可するか #246 stake-notes (PR feat(gate stake verbs): tight-scope --note on claim / witness (#246) #256)expects_response(PR feat(broadcast): expects-response opt-in surfaced via boot (#220 phase 1) #222) + design: review depth axis for substrate-driven waves #221 review depth axis (PR feat(gate): gate request --depth advisory (#221 phase 1 substrate slot) #223)--to all-sessions) deferredDesign principles (stable; use these to resolve ambiguity)
content_rootis the whole world. Git gives history.status_loggrows monotonically.suggested_nextwhere meaningful,gate schemaintrospection, vertical-format errors with onboarding hints (see feat(ux): severity aliases + lense extension hint #31–feat(boot): add content_root_health hint + one-command fix path #35 for the pattern).docs/POLICY.md. Extensions go through interface/infrastructure, not by mutating domain types.Phases
Phase 1 — Extension points
Goal: let adopters add verbs, lifecycle reactions, and content transforms without forking.
Three extension surfaces, ordered by impact:
.guild/plugins/verbs/*.mjs): load at CLI startup, register new verb names into the dispatch table insrc/interface/gate/index.ts. Each plugin exports{ name, category, summary, input, output, run(c, args) }— the same shapeVerbSchemaalready uses for built-in verbs. Must also appear ingate schemaoutput so LLM tool layers discover them..guild/plugins/hooks/*.mjs): invoked synchronously around request state transitions (before:approve,after:complete,after:review, etc). Hooks receive the request + transition context, may return{ allow: false, reason }to veto (policy enforcement) or emit side-effects (write to inbox, notify external system). Must not block the transition on slow I/O — if a hook needs network, spawn and return..guild/plugins/transforms/*.mjs): invoked before YAML serialization (on:save) and after deserialization (on:load). Use case: index rebuild, derived field computation. Must be idempotent.All three reuse the existing
doctor pluginsloading pattern (seesrc/application/diagnostic/DiagnosticUseCases.ts) — ES module paths listed inguild.config.yamlunderplugins:. Plugin execution is sandboxed only by Node's module system; document the trust model inSECURITY.md.Acceptance criteria:
examples/plugins/) that works end-to-end.gate schemasurfaces plugin verbs with asource: pluginmarker so a consumer can distinguish.gate doctorreports plugin load failures without breaking the CLI.docs/POLICY.mdgets a paragraph on plugin stability (additive only, no renaming the hook signature without a minor bump).Phase 2 — Time-aware verbs
Goal: make the passage of time a first-class record, not an implicit side effect of logging.
Candidate verbs (exact names / semantics TBD in sub-issues):
gate rest— boundary record. Not a lifecycle toggle; just "I am putting this down now." Timestamps only; no mandatory wake note (that would turn it into reflect). Rationale: the length of a break is itself information, the way a commit timestamp is information.gate wake— optional pairing verb that says "I am picking things back up." Decoupled fromrestso they don't have to be used together.gate farewell— ceremonial close meant to be paired withgate resumeat the next session start. Different fromrestbecause it is "until next session," not "until later today."gate resume(exists) — reads the last voice / transition / open loops, composes restoration prose. May gain interaction withrest/wake/farewellrecords.Why time-aware verbs at all: agents (human or AI) accumulate fatigue or context drift inside long sessions. Marking the boundaries in-band lets downstream verbs (tail, voices, resume) render the session with the boundaries visible, which changes how the next reader experiences the history.
Interaction with Claude Code's compact + preserved-tail-relinking and with multi-session workflows is an open design question. Spin up a sub-issue when Phase 1 is ready to merge.
Phase 3 — Multi-guild / federation
Goal: let a content_root reference records in another content_root without losing append-only guarantees.
Sketch:
gate federate <path>publishes a read-only reference.show/tail/voicescan walk cross-root when the reference is resolvable. Actors can belong to multiple guilds; pair-mode (--with) can refer to actors from federated roots.This is the structural answer to "small pairs would silo themselves" — the tool should let neighboring pairs see each other's work without collapsing into a single content_root.
Defer concrete spec until Phase 1 + 2 are stable; federation affects every reader verb.
Phase 4 — Event fabric (external integrations)
Goal: bidirectional bridges between
guild-cliand external systems — MCP, Slack, GitHub, etc — without making those systems authoritative.gate import <event>or aninbound-events/directory that plugins drain. Imported events become first-class records (withsource: externalin YAML) but are auditable as such.Authoritative store always stays in
content_root/. External systems are views or feeds, never truth.Out of scope (for this roadmap)
grep+ filters is intentionally the search story.How contributors should proceed
hints.*fields on reads, actionable error messages) is how "this feature is discoverable" shows up in this codebase. New surfaces should carry the same pattern.Pointers
src/application/diagnostic/DiagnosticUseCases.ts+guild.config.yaml:doctor.pluginssrc/infrastructure/config/GuildConfig.ts+ feat: gate summarize + gate why + plugin trusted guard #90src/interface/gate/handlers/schema.tssrc/interface/gate/index.tsdocs/POLICY.mdAGENT.md,README.md,docs/verbs.md