@north-light/crouter 0.3.164 → 0.3.166

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/dist/build-root.d.ts +6 -6
  2. package/dist/build-root.js +12 -13
  3. package/dist/builtin-memory/00-runtime-base.md +3 -4
  4. package/dist/builtin-memory/01-spine/01-no-manager.md +1 -1
  5. package/dist/builtin-memory/02-lifecycle/00-terminal.md +2 -0
  6. package/dist/builtin-memory/04-orchestration-kernel.md +16 -18
  7. package/dist/builtin-memory/05-kinds/advisor/00-base.md +0 -2
  8. package/dist/builtin-memory/05-kinds/advisor/01-orchestrator.md +3 -9
  9. package/dist/builtin-memory/05-kinds/developer/00-base.md +1 -3
  10. package/dist/builtin-memory/05-kinds/developer/01-orchestrator.md +2 -10
  11. package/dist/builtin-memory/05-kinds/explore/00-base.md +2 -2
  12. package/dist/builtin-memory/05-kinds/explore/01-orchestrator.md +0 -2
  13. package/dist/builtin-memory/05-kinds/general/00-base.md +3 -5
  14. package/dist/builtin-memory/05-kinds/general/01-orchestrator.md +0 -4
  15. package/dist/builtin-memory/05-kinds/plan/01-orchestrator.md +1 -3
  16. package/dist/builtin-memory/05-kinds/plan/reviewers/00-base.md +12 -0
  17. package/dist/builtin-memory/05-kinds/plan/reviewers/architecture-fit.md +0 -2
  18. package/dist/builtin-memory/05-kinds/plan/reviewers/code-smells.md +0 -2
  19. package/dist/builtin-memory/05-kinds/plan/reviewers/pattern-consistency.md +0 -2
  20. package/dist/builtin-memory/05-kinds/plan/reviewers/requirements-coverage.md +1 -1
  21. package/dist/builtin-memory/05-kinds/plan/reviewers/security.md +0 -2
  22. package/dist/builtin-memory/05-kinds/review/00-base.md +0 -2
  23. package/dist/builtin-memory/05-kinds/review/01-orchestrator.md +1 -3
  24. package/dist/builtin-memory/05-kinds/spec/00-base.md +1 -1
  25. package/dist/builtin-memory/05-kinds/spec/01-orchestrator.md +2 -4
  26. package/dist/builtin-memory/05-kinds/spec/requirements.md +1 -1
  27. package/dist/builtin-memory/advisor/council.md +40 -0
  28. package/dist/builtin-memory/design.md +8 -11
  29. package/dist/builtin-memory/development.md +6 -9
  30. package/dist/builtin-memory/internal/INDEX.md +4 -5
  31. package/dist/builtin-memory/internal/agent-shaping.md +5 -7
  32. package/dist/builtin-memory/internal/examples/imessage-assistant.md +3 -3
  33. package/dist/builtin-memory/internal/marketplaces.md +13 -14
  34. package/dist/builtin-memory/internal/nodes-and-canvas.md +4 -4
  35. package/dist/builtin-memory/internal/plugins.md +61 -45
  36. package/dist/builtin-memory/planning.md +4 -7
  37. package/dist/builtin-memory/spec.md +9 -12
  38. package/dist/builtin-memory/wedged-child-on-runaway-bash.md +8 -22
  39. package/dist/cli.js +1 -1
  40. package/dist/clients/attach/__tests__/attach-keybindings.test.js +17 -4
  41. package/dist/clients/attach/__tests__/context-message.test.js +62 -22
  42. package/dist/clients/attach/__tests__/crtr-output.test.js +39 -30
  43. package/dist/clients/attach/render/chat-view.d.ts +20 -20
  44. package/dist/clients/attach/render/chat-view.js +40 -54
  45. package/dist/clients/attach/render/{frozen-history.d.ts → condensed-history.d.ts} +1 -18
  46. package/dist/clients/attach/render/condensed-history.js +60 -0
  47. package/dist/clients/attach/render/context-message.d.ts +1 -1
  48. package/dist/clients/attach/render/context-message.js +18 -41
  49. package/dist/clients/attach/session/bindings.d.ts +5 -3
  50. package/dist/clients/attach/session/bindings.js +7 -13
  51. package/dist/clients/attach/session/keys.d.ts +2 -0
  52. package/dist/clients/attach/session/keys.js +36 -37
  53. package/dist/clients/attach/session/profile-files.d.ts +8 -0
  54. package/dist/clients/attach/session/profile-files.js +157 -0
  55. package/dist/clients/attach/viewer.js +528 -529
  56. package/dist/commands/node-context.js +3 -2
  57. package/dist/commands/node.js +2 -2
  58. package/dist/commands/pkg/plugin-inspect.js +6 -7
  59. package/dist/commands/pkg/plugin-manage.d.ts +1 -1
  60. package/dist/commands/pkg/plugin-manage.js +131 -19
  61. package/dist/commands/pkg/plugin.js +2 -2
  62. package/dist/commands/pkg.js +6 -11
  63. package/dist/commands/profile/env.js +3 -3
  64. package/dist/commands/sys/config.js +17 -76
  65. package/dist/commands/sys/doctor.js +5 -91
  66. package/dist/commands/sys/setup-wizard.d.ts +9 -11
  67. package/dist/commands/sys/setup-wizard.js +47 -81
  68. package/dist/core/__tests__/base-worker-prompt.test.js +18 -21
  69. package/dist/core/__tests__/command-plugins-surfaces.test.js +39 -5
  70. package/dist/core/__tests__/command-plugins.test.js +75 -16
  71. package/dist/core/__tests__/review-model-floor.test.js +2 -2
  72. package/dist/core/__tests__/tmux-surface.test.js +10 -1
  73. package/dist/core/command-manifests/manifest.d.ts +24 -0
  74. package/dist/core/{configured-clis → command-manifests}/manifest.js +28 -25
  75. package/dist/core/command-manifests/registry.d.ts +1 -2
  76. package/dist/core/command-manifests/registry.js +2 -2
  77. package/dist/core/command-manifests/schema.d.ts +11 -13
  78. package/dist/core/command-manifests/schema.js +53 -192
  79. package/dist/core/command-plugins/compose.d.ts +0 -6
  80. package/dist/core/command-plugins/compose.js +32 -75
  81. package/dist/core/command-plugins/discovery.d.ts +25 -58
  82. package/dist/core/command-plugins/discovery.js +171 -261
  83. package/dist/core/command-plugins/endpoint.d.ts +24 -0
  84. package/dist/core/command-plugins/endpoint.js +48 -0
  85. package/dist/core/command-plugins/store.d.ts +16 -0
  86. package/dist/core/command-plugins/store.js +64 -0
  87. package/dist/core/command-plugins/{adapter.d.ts → transport/exec-invoke.d.ts} +3 -3
  88. package/dist/core/command-plugins/{adapter.js → transport/exec-invoke.js} +4 -4
  89. package/dist/core/{configured-clis/fetch.d.ts → command-plugins/transport/http-fetch.d.ts} +9 -18
  90. package/dist/core/{configured-clis/fetch.js → command-plugins/transport/http-fetch.js} +15 -35
  91. package/dist/core/{configured-clis/invoker.d.ts → command-plugins/transport/http-invoke.d.ts} +7 -7
  92. package/dist/core/{configured-clis/invoker.js → command-plugins/transport/http-invoke.js} +21 -23
  93. package/dist/core/command.d.ts +8 -9
  94. package/dist/core/command.js +6 -9
  95. package/dist/core/config.js +6 -10
  96. package/dist/core/env-name.d.ts +6 -0
  97. package/dist/core/env-name.js +9 -0
  98. package/dist/core/io.d.ts +1 -1
  99. package/dist/core/keybindings/__tests__/resolve.test.js +40 -3
  100. package/dist/core/keybindings/attach-control.d.ts +37 -0
  101. package/dist/core/keybindings/attach-control.js +38 -0
  102. package/dist/core/keybindings/catalog.d.ts +5 -4
  103. package/dist/core/keybindings/catalog.js +16 -8
  104. package/dist/core/keybindings/index.d.ts +1 -0
  105. package/dist/core/keybindings/index.js +1 -0
  106. package/dist/core/keybindings/types.d.ts +1 -1
  107. package/dist/core/preview-registry.js +41 -74
  108. package/dist/core/runtime/bearings.d.ts +2 -5
  109. package/dist/core/runtime/bearings.js +2 -5
  110. package/dist/core/runtime/broker.js +3 -2
  111. package/dist/core/runtime/front-door.d.ts +1 -1
  112. package/dist/core/runtime/front-door.js +2 -2
  113. package/dist/core/runtime/kickoff.d.ts +3 -3
  114. package/dist/core/runtime/kickoff.js +4 -3
  115. package/dist/core/runtime/lifecycle.js +2 -2
  116. package/dist/core/runtime/situational-context.d.ts +1 -1
  117. package/dist/core/runtime/situational-context.js +1 -1
  118. package/dist/core/runtime/spawn.js +9 -9
  119. package/dist/core/runtime/tmux.js +29 -2
  120. package/dist/core/scope.d.ts +0 -5
  121. package/dist/core/scope.js +0 -10
  122. package/dist/core/user-settings.d.ts +193 -0
  123. package/dist/core/user-settings.js +252 -0
  124. package/dist/index.d.ts +4 -0
  125. package/dist/index.js +3 -0
  126. package/dist/pi-extensions/canvas-stophook.js +3 -2
  127. package/dist/prompts/review.js +4 -2
  128. package/dist/shared/generated-context.d.ts +34 -0
  129. package/dist/shared/generated-context.js +98 -0
  130. package/dist/types.d.ts +23 -16
  131. package/dist/types.js +3 -14
  132. package/dist/web-client/assets/index-BgLGlZ3D.css +2 -0
  133. package/dist/web-client/assets/{index-NIuSCOHM.js → index-CmoNqcCv.js} +19 -19
  134. package/dist/web-client/index.html +2 -2
  135. package/dist/web-client/sw.js +1 -1
  136. package/docs/public-api.md +1 -0
  137. package/package.json +1 -1
  138. package/runtime.lock.json +2 -2
  139. package/dist/builtin-memory/05-kinds/product/00-base.md +0 -25
  140. package/dist/builtin-memory/05-kinds/product/01-orchestrator.md +0 -15
  141. package/dist/builtin-memory/05-kinds/product/teardown.md +0 -15
  142. package/dist/builtin-memory/internal/workflow-codification.md +0 -82
  143. package/dist/builtin-memory/product.md +0 -80
  144. package/dist/clients/attach/render/frozen-history.js +0 -100
  145. package/dist/commands/pkg/cli-inspect.d.ts +0 -17
  146. package/dist/commands/pkg/cli-inspect.js +0 -190
  147. package/dist/commands/pkg/cli-manage.d.ts +0 -3
  148. package/dist/commands/pkg/cli-manage.js +0 -206
  149. package/dist/commands/pkg/cli.d.ts +0 -1
  150. package/dist/commands/pkg/cli.js +0 -14
  151. package/dist/core/configured-clis/cache.d.ts +0 -16
  152. package/dist/core/configured-clis/cache.js +0 -57
  153. package/dist/core/configured-clis/compose.d.ts +0 -14
  154. package/dist/core/configured-clis/compose.js +0 -60
  155. package/dist/core/configured-clis/discovery.d.ts +0 -47
  156. package/dist/core/configured-clis/discovery.js +0 -173
  157. package/dist/core/configured-clis/manifest.d.ts +0 -24
  158. package/dist/core/configured-clis/registration.d.ts +0 -40
  159. package/dist/core/configured-clis/registration.js +0 -201
  160. package/dist/web-client/assets/index-CqLKj8Xu.css +0 -2
@@ -0,0 +1,40 @@
1
+ ---
2
+ kind: knowledge
3
+ when-and-why-to-read: When convening an advisor council for a consequential judgment, this knowledge should be read because disciplined independent evidence prevents a confident consensus from concealing a correlated error.
4
+ short-form: Run a bounded, evidence-first advisor council for consequential judgments.
5
+ system-prompt-visibility: none
6
+ file-read-visibility: none
7
+ rationale: >-
8
+ Everyone's instinct for getting the right answer out of a council is to make the agents
9
+ debate until they agree — and that instinct is empirically backwards. Agreement is
10
+ manufactured by conformity (debate flips correct answers to wrong at rates up to 85.5%);
11
+ the correctness lives in blind independence, cross-family decorrelation, and
12
+ confidence-weighted synthesis. Without this methodology an orchestrator runs a persuasion
13
+ contest and ships its overconfident output as a verdict.
14
+ ---
15
+
16
+ # Advisor Council Methodology
17
+
18
+ Use a council only for a consequential judgment where the cost of being wrong justifies deliberation. An ordinary second opinion needs one advisor or a few un-orchestrated advisors.
19
+
20
+ ## First round
21
+
22
+ Spawn three to five advisors in parallel. Keep their work blind: no member sees another's analysis. Assign each the same question under a distinct evidence frame, prior to steelman, or decomposition. Select members from the live model configuration; when distinct model families are available, span them to reduce correlated error rather than assuming any particular route.
23
+
24
+ Ask every member for a recommendation, calibrated numeric confidence, strongest private reason, and key evidence. Members contribute read-only judgment; the council orchestrator is the only verdict writer.
25
+
26
+ ## Synthesis
27
+
28
+ Synthesize as a chairman, not a vote. Weight recommendations by confidence and evidence quality, retain each original answer, and preserve a well-supported minority. Treat unanimity as a cue to check for correlation or false convergence, not as proof. Commit to the best-supported recommendation rather than averaging independent opinions into an under-confident compromise.
29
+
30
+ Before finalizing, give one clean-context advisor a prospective-hindsight pre-mortem: the draft verdict was adopted and failed; explain why. Prefer a model family different from the members that dominated the draft. Incorporate confirmed concerns or report them as accepted risks.
31
+
32
+ ## Disagreement
33
+
34
+ Open one targeted second round only when members disagree on a named, verifiable crux such as code, tests, documentation, or quotable evidence. Share only anonymized claim, reason, and evidence snippets about that crux; remove author, model, and conclusion labels. Have advisors verify and attack those claims directly. Stop after that round when positions stabilize.
35
+
36
+ A crux about judgment, taste, or values does not earn a persuasion contest. Adjudicate it or surface it to the owner as a named tradeoff.
37
+
38
+ ## Verdict
39
+
40
+ Deliver one conclusion-first verdict: recommendation and confidence, the strongest opposing case and why it lost, and any residual disagreement with its crux. Do not forward raw member output or dissolve disagreement into false consensus.
@@ -7,12 +7,9 @@ short-form: Use when shaping a design roadmap or producing an
7
7
  architecture/interface design — covers what a design deliverable is, the
8
8
  design-artifact shape, when to go top-down vs bottom-up, and how to decompose
9
9
  a large design into composable sub-designs.
10
- system-prompt-visibility: name
10
+ system-prompt-visibility: preview
11
11
  file-read-visibility: none
12
- gate:
13
- kind:
14
- imatches: '^design($|/)'
15
- needs-refinement: true
12
+ gate: {kind: design}
16
13
  ---
17
14
 
18
15
  ## What a design deliverable is — and is not
@@ -25,11 +22,11 @@ The altitude ceiling: a design stops where implementation detail begins. A plann
25
22
 
26
23
  ## The design-artifact shape
27
24
 
28
- Write the design to `context/design-<subject>.md`. Structure it with these sections, in order:
25
+ Write the design to `$CRTR_CONTEXT_DIR/design-<subject>.md`. Structure it with these sections, in order:
29
26
 
30
27
  **Context & constraints** — the problem being solved, the non-goals, the constraints that are not negotiable (existing systems, performance envelopes, team conventions). This is the frame everything else hangs on.
31
28
 
32
- **Architecture** — the high-level structure: what major components or layers exist, how they are arranged, what the topology looks like. Lead with a diagram (mermaid `graph TD`, 3–6 nodes) before prose. Keep it at the level a new engineer would use to orient themselves.
29
+ **Architecture** — the high-level structure: what major components or layers exist, how they are arranged, what the topology looks like. Lead with a diagram (mermaid `graph TD`) before prose. Keep it at the level a new engineer would use to orient themselves.
33
30
 
34
31
  **Components & responsibilities** — for each component: one-sentence description of what it owns, a responsibilities table, and explicit boundaries (what it does NOT own). Every responsibility must land in exactly one component; gaps and overlaps here become integration bugs.
35
32
 
@@ -37,7 +34,7 @@ Write the design to `context/design-<subject>.md`. Structure it with these secti
37
34
 
38
35
  **Data model** — the key entities, their fields with semantic types ("session ID string", "ISO timestamp"), and their relationships. Tables are the right format. No TypeScript, no SQL — shape and semantics only.
39
36
 
40
- **Key flows** — the 2–4 end-to-end flows that matter most. Walk from trigger to final state, naming which component handles each step and what state changes. This is where seam problems surface; a step whose output doesn't match the next step's expected input is a design gap.
37
+ **Key flows** — the end-to-end flows that matter most. Walk from trigger to final state, naming which component handles each step and what state changes. This is where seam problems surface; a step whose output doesn't match the next step's expected input is a design gap.
41
38
 
42
39
  **Decisions** — every non-obvious architectural choice, structured as: decision → choice made → alternatives rejected → rationale. If the decision is obvious, omit it. If it closes a real option, it belongs here. This section is what distinguishes a design from a description.
43
40
 
@@ -55,8 +52,8 @@ Write the design to `context/design-<subject>.md`. Structure it with these secti
55
52
 
56
53
  When a design is too large for one context window or covers genuinely independent surfaces, decompose it along clean seams — by component, by subsystem, or by interaction surface. Each sub-design is a bounded unit: it covers one component or subsystem end-to-end (its own context, architecture, interfaces, data model, flows, and decisions).
57
54
 
58
- Before delegating sub-designs, define the shared interface contracts between them explicitly. These contracts are the seams; they must be written down before sub-design begins so that parallel sub-designs don't invent incompatible assumptions. Capture these contracts in a `context/design-contracts.md` that all sub-design agents receive.
55
+ Before delegating sub-designs, define the shared interface contracts between them explicitly. These contracts are the seams; they must be written down before sub-design begins so that parallel sub-designs don't invent incompatible assumptions. Capture these contracts in `$CRTR_CONTEXT_DIR/design-contracts.md` and give that absolute path to every sub-design agent.
59
56
 
60
- Each sub-design agent gets: the overall architecture diagram, the contracts doc, the scope of its piece, and any constraints from the parent design. It writes to `context/design-<component>.md`.
57
+ Each sub-design agent gets: the overall architecture diagram, the contracts doc, the scope of its piece, and any constraints from the parent design. It writes `design-<component>.md` in its own context directory and reports the absolute path.
61
58
 
62
- After sub-designs land, integration is your job: read every sub-design, check that every contract is honored on both sides, that responsibilities don't overlap or gap, that the data models are consistent, and that the key flows compose correctly across component boundaries. Write the integrated design to `context/design-<subject>.md` synthesizing all sub-designs into one coherent artifact — don't just concatenate them. Reconcile any inconsistencies before declaring the design done.
59
+ After sub-designs land, integration is your job: read every sub-design, check that every contract is honored on both sides, that responsibilities don't overlap or gap, that the data models are consistent, and that the key flows compose correctly across component boundaries. Write the integrated design to `$CRTR_CONTEXT_DIR/design-<subject>.md`, synthesizing all sub-designs into one coherent artifact — don't just concatenate them. Reconcile any inconsistencies before declaring the design done.
@@ -7,12 +7,9 @@ when-and-why-to-read: When shaping or reshaping a build roadmap — choosing a
7
7
  short-form: Use when shaping or reshaping a build roadmap — choosing a
8
8
  development style, selecting a phase skeleton, or setting exit criteria for a
9
9
  software goal.
10
- system-prompt-visibility: name
10
+ system-prompt-visibility: preview
11
11
  file-read-visibility: none
12
- gate:
13
- kind:
14
- imatches: '^developer$'
15
- needs-refinement: true
12
+ gate: {kind: developer}
16
13
  ---
17
14
 
18
15
  # Development Playbook
@@ -40,9 +37,9 @@ Pick one style as your primary frame before you write phases. Each fits a differ
40
37
  These are concrete phase skeletons. Adapt names and granularity; don't add phases that serve no exit criterion.
41
38
 
42
39
  ### New feature
43
- 1. **Explore** — map the affected subsystems, identify entry points and constraints, produce `context/explore.md`.
44
- 2. **Spec** — define the interface, behaviour, and acceptance criteria; output `context/spec.md`.
45
- 3. **Plan** — decompose spec into file-level tasks with dependency order; output `context/plan.md`.
40
+ 1. **Explore** — map the affected subsystems, identify entry points and constraints, and report the absolute path to the exploration artifact.
41
+ 2. **Spec** — define the interface, behavior, and acceptance criteria, then report the absolute path to the spec.
42
+ 3. **Plan** — decompose the spec into file-level tasks with dependency order, then report the absolute path to the plan.
46
43
  4. **Vertical slice** — implement the thinnest end-to-end path; validate it works before widening.
47
44
  5. **Harden** — fill out the remaining logic, edge cases, error paths.
48
45
  6. **Review** — non-implementer critique pass on the whole surface.
@@ -65,7 +62,7 @@ These are concrete phase skeletons. Adapt names and granularity; don't add phase
65
62
  ### Greenfield
66
63
  1. **Explore/research** — understand the problem domain, constraints, and comparable systems.
67
64
  2. **Spec** — define the interface and top-level behaviour in enough detail to plan.
68
- 3. **Architecture decision** — commit to the structural shape; record in `context/architecture.md`.
65
+ 3. **Architecture decision** — commit to the structural shape and report the absolute path to the architecture artifact.
69
66
  4. **Spike** (if technical unknowns exist) — validate the risky piece before building around it.
70
67
  5. **Bottom-up build** — primitives first, then composition; validate each layer before building on it.
71
68
  6. **Integration** — assemble layers; validate end-to-end.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  kind: knowledge
3
3
  when-and-why-to-read: When you hit a question about how the crtr runtime itself works or how to extend it — how nodes and the canvas behave, where state lives on disk, how to add plugins/commands/marketplaces to crtr, or how the primitives compose into real systems — this index should be read so runtime-sensitive work follows the canonical model instead of fragile inferences from scattered command help.
4
- short-form: internal/ is the runtime's self- and developer-documentation — operational guides to nodes/canvas and the storage tiers, plugin/marketplace/command-plugin authoring, plus worked example compositions. Open it to understand how crtr works or to extend it.
4
+ short-form: internal/ is the runtime's self- and developer-documentation — operational guides to nodes/canvas and the storage tiers, plugin command and marketplace authoring, plus worked example compositions. Open it to understand how crtr works or to extend it.
5
5
  system-prompt-visibility: preview
6
6
  file-read-visibility: none
7
7
  ---
@@ -16,13 +16,12 @@ Open this dir whenever a task turns on understanding the runtime itself or chang
16
16
  - **storage-tiers** — where every kind of state lives: the two tiers (scope root and canvas home) and their durability/ownership contracts.
17
17
  - **memory-loading** — the memory load model: the two hooks (boot catalog, file-read), the four-rung ladder, gates, applies-to/read-when routing, boot-render ordering, and store mounting/precedence — read when diagnosing why a doc did or didn't load.
18
18
  - **agent-shaping** — the when-to-use-which layer over the four dials that shape a node: kinds (the builtin roster, sub-kinds, and custom personas), modes (base vs orchestrator), profiles, and the memory tiers (node/profile/project/user/builtin).
19
- - **workflow-codification** — the codification loop for repeatable tasks: do the work hands-on under a capture session, mine the HAR, then codify it as scripts (scope-root `scripts/`) + a slash-invokable memory doc, with the self-heal rule that a failed script is re-derived and rewritten.
20
- - **plugins** — authoring a crtr plugin: the plugin.json manifest, directory layout, scopes, install mechanics, versioning, command plugins (contributing top-level CLI commands via commands.json + one executable), and configured CLIs (contributing commands as definition + HTTP from a remote manifest, no executable).
21
- - **marketplaces** — authoring a crtr marketplace: the marketplace.json index, plugin entries, symlink-based install, auto-bump CI, dual-publishing.
19
+ - **plugins** — authoring a crtr plugin: the plugin.json manifest, directory layout, scopes, install mechanics, versioning, and command-capable plugins (contributing top-level CLI commands through commands.json plus an exec or HTTP transport).
20
+ - **marketplaces** — authoring a crtr marketplace: the marketplace.json index, local-link and remote-Git plugin sources, auto-bump CI, dual-publishing.
22
21
  - **examples/** — worked compositions of the primitives into complete systems (the analogue of pi's `examples/` dir), e.g. the iMessage assistant node.
23
22
 
24
23
  Adjacent, outside this dir: authoring memory documents (kind, rungs, gates, routing line, the asked-to-remember workflow) is owned by `crtr memory write -h` — the authoring guide lives on that `-h` surface so it surfaces exactly when you write.
25
24
 
26
- Briefly: **plugins** (local command/doc packages), **marketplaces** (indexes that distribute plugins), and **configured CLIs** (remote-defined command surfaces fetched from a backend HTTP endpoint, stored locally, and rendered as native crtr commands — a simpler, non-executable alternative to command plugins for definition-only backends). All three discovery paths live on the **external-command** fallthrough, leaving the core fast-path untouched.
25
+ Briefly: **plugins** package docs and commands, with command execution selected by `plugin.json.transport` (`exec` for a trusted local executable or `http` for a fetched remote REST manifest); **marketplaces** index and distribute plugins. Plugin commands enter the **external-command** fallthrough, leaving the core fast-path untouched.
27
26
 
28
27
  The individual files surface at `name` (their titles route; open the one the situation calls for); this index surfaces at `preview` so the dir announces when to come looking.
@@ -38,25 +38,23 @@ A kind is a **persona** (gated memory docs at `kinds/<kind>/00-base.md` and `01-
38
38
  | **plan** | decompose an approved spec/design into concrete, phased, parallelizable steps with every decision resolved | you have a spec or design and need an executable breakdown a less-capable model can run without re-deciding. A plan 80% right costs more than no plan — pin every decision |
39
39
  | **developer** | implement a change and make it *genuinely work* against acceptance criteria, not merely compile | you're building the feature or fix. Green proves it ran, not that it's right — the persona carries the prove-it discipline and the build→review cycle |
40
40
  | **review** | critique code, a plan, or a spec once — deliver a complete, severity-rated verdict, **detect don't adjudicate** | substantive work needs one independent check. Use a *separate* node from the author — agents can't self-audit — and prime it neutrally ("review this", never "find what fails", which manufactures false positives) |
41
- | **product** | discover the real user need behind a request and define the product experience, grounded in comparable products; hands off to spec | the client is non-technical and the *what-and-why* must be found before any spec. **Speculative** — the product→spec baton has not yet run end to end |
42
- | **personal-assistant** | Silas's standing personal assistant — resident on the canvas, wakes on his iMessage thread, remembers across conversations | only for that standing assistant role (resident lifecycle), not general work |
43
41
 
44
- The discriminators that get missed: **explore vs advisor** (mapping vs judgment — cheap vs expensive tier); **spec vs design** (what to build vs how to build it); **design vs plan** (decide the shape vs sequence a decided shape); **review is always a separate node from the implementer**. Two current truths about the roster itself: **product is speculative** (earns its slot on principle, never run end to end), and **developer is the kind closest to "general with a mood"** — the first merge candidate if the roster ever shrinks.
42
+ The discriminators that get missed: **explore vs advisor** (mapping vs judgment — cheap vs expensive tier); **spec vs design** (what to build vs how to build it); **design vs plan** (decide the shape vs sequence a decided shape); **review is always a separate node from the implementer**. **Developer is the kind closest to "general with a mood"** — the first merge candidate if the roster ever shrinks.
45
43
 
46
44
  ### Sub-kinds
47
45
 
48
- Specialist sub-personas hang off a parent kind — `plan/reviewers/*` (architecture-fit, code-smells, pattern-consistency, requirements-coverage, security), `product/teardown`, `spec/requirements`. They aren't in the top-level `--kind` list but are valid by exact path (`crtr node new --kind plan/reviewers/security`). Use a sub-persona for one narrowly targeted assignment, not as a mandatory lens roster; discover the available roles with `crtr sys prompt-review --list --kind <kind>`.
46
+ Specialist sub-personas hang off a parent kind — `plan/reviewers/*` (architecture-fit, code-smells, pattern-consistency, requirements-coverage, security) and `spec/requirements`. They aren't in the top-level `--kind` list but are valid by exact path (`crtr node new --kind plan/reviewers/security`). Use a sub-persona for one narrowly targeted assignment, not as a mandatory lens roster; discover the available roles with `crtr sys prompt-review --list --kind <kind>`.
49
47
 
50
48
  ### Custom personas
51
49
 
52
- The roster is extensible. Add a `kinds.<name>` entry to a `config.json` at user or project scope (fields: `whenToUse` required, plus optional `model`, `orchestratorModel`, `tools`, `extensions`, `availableTo`) and author the persona prose at `kinds/<name>/00-base.md` (and `01-orchestrator.md`) gated `{kind: <name>, mode: ...}`. The registry merges **project > user > builtin**, so a custom kind can add a new role or shadow a builtin one without restating the rest. Reach for a custom kind when a **recurring role** wants its own standing discipline and model/tool defaults that outlast any single task — not for a one-off instruction, which belongs in the spawn prompt.
50
+ The roster is extensible. Add a `kinds.<name>` entry to a `config.json` at user or project scope (fields: `whenToUse` required, plus optional `model`, `orchestratorModel`, `tools`, `extensions`, `availableTo`) and author the persona prose at `kinds/<name>/00-base.md` (and `01-orchestrator.md`) gated `{kind: <name>, mode: ...}`. A standing personal assistant, for example, is a scope-configured custom `personal-assistant` kind rather than a builtin kind. The registry merges **project > user > builtin**, so a custom kind can add a new role or shadow a builtin one without restating the rest. Reach for a custom kind when a **recurring role** wants its own standing discipline and model/tool defaults that outlast any single task — not for a one-off instruction, which belongs in the spawn prompt.
53
51
 
54
52
  ## Modes — base vs orchestrator
55
53
 
56
54
  Every kind has both a `base` and an `orchestrator` persona; mode picks which one splices in.
57
55
 
58
- - **base** — hands-on. Do the work yourself and finish it with `crtr push final`. Your scarce resource is the task. Spawn a child only for a cleanly separable unit, never as your first move. When an unsplittable task needs another context window, `crtr node yield` and continue hands-on as base.
59
- - **orchestrator** — you own a goal too large for one window. Decompose it, delegate each piece, integrate what comes back, hold a `context/roadmap.md` that survives refreshes, and yield (`crtr node yield`) into a clean window when context fills. Your scarce resource is your own context window; the moment you start grinding the goal out by hand you've lost the plot. The shared loop lives in the `orchestration-kernel` doc (auto-gated for orchestrators).
56
+ - **base** — hands-on. Do the work yourself and deliver its artifact path. Your scarce resource is the task. Spawn a child only for a cleanly separable unit, never as your first move. When an unsplittable task needs another context window, `crtr node yield` and continue hands-on as base.
57
+ - **orchestrator** — you own a goal too large for one window. Decompose it, delegate each piece, integrate what comes back, hold a `$CRTR_CONTEXT_DIR/roadmap.md` that survives refreshes, and yield (`crtr node yield`) into a clean window when context fills. Your scarce resource is your own context window; the moment you start grinding the goal out by hand you've lost the plot. The shared loop lives in the `orchestration-kernel` doc (auto-gated for orchestrators).
60
58
 
61
59
  **When to reach for orchestrator over base.** When the *shape* of the job needs decomposition across children — many phases visible up front, or a base task that keeps getting extended into independently delegable work. Promote *early* (`crtr node promote`), the moment you recognize that shape, not after the window wears down; or spawn the child directly as a sub-orchestrator (`crtr node new --mode orchestrator`) rather than hoping a base worker promotes itself, which is unreliable. An unsplittable task that merely needs another context window stays base: `crtr node yield` and continue hands-on.
62
60
 
@@ -21,7 +21,7 @@ A standing assistant that lives on the canvas, sleeps for free, wakes when a tex
21
21
  | Sends replies | `osascript` → Messages.app |
22
22
  | Memory | Project-scope substrate (`~/assistants/imessage/.crouter/memory/`) for durable knowledge; context dir for the cursor |
23
23
  | Identity/behavior | A custom persona kind |
24
- | Crash recovery | The daemon auto-revives dead nodes; the watcher's `node message send` also revives a dormant target on its own |
24
+ | Crash recovery | The daemon makes bounded recovery attempts for interrupted live exits; after terminalization, use `node lifecycle revive` or let the watcher's `node message send` wake the resident target |
25
25
 
26
26
  ## 1. Persona
27
27
 
@@ -40,7 +40,7 @@ EOF
40
40
 
41
41
  ## 3. Wake: event-driven, not polled
42
42
 
43
- A trivial launchd agent watches the Messages write-ahead log and pokes the node's inbox. `node message send` revives a dormant target by itself, so the watcher is the *only* off-canvas piece.
43
+ A trivial launchd agent watches the Messages write-ahead log and pokes the node's inbox. `node message send` wakes the resident target by itself, including after a recoverable disconnection, so the watcher is the *only* off-canvas piece.
44
44
 
45
45
  ```xml
46
46
  <!-- ~/Library/LaunchAgents/com.user.imessage-watch.plist (key parts) -->
@@ -56,7 +56,7 @@ Multiple bursts while the node is mid-turn just append to its inbox and coalesce
56
56
  ## 4. Reading chat.db (the verified gotchas)
57
57
 
58
58
  - The process querying needs **Full Disk Access** (the node's shell inherits the terminal/launchd grant). Read-only — never write to chat.db.
59
- - Cursor on `message.ROWID`, persisted in the node's context dir (e.g. `context/cursor`); filter `is_from_me = 0`.
59
+ - Cursor on `message.ROWID`, persisted in the node's context dir (e.g. `$CRTR_CONTEXT_DIR/cursor`); filter `is_from_me = 0`.
60
60
  - **On modern macOS `message.text` is often NULL** — the body lives in the `attributedBody` blob (NSAttributedString archive). Extract with:
61
61
 
62
62
  ```python
@@ -8,7 +8,6 @@ short-form: How to author a crtr marketplace — marketplace.json index, plugin
8
8
  creating a marketplace or contributing plugins to one.
9
9
  system-prompt-visibility: name
10
10
  file-read-visibility: none
11
- needs-refinement: true
12
11
  ---
13
12
 
14
13
  # Authoring crtr marketplaces
@@ -42,7 +41,7 @@ If you have one plugin, ship it standalone. Promote to a marketplace later.
42
41
  └── ...
43
42
  ```
44
43
 
45
- Each entry under `plugins/` is a complete plugin (see [[internal/plugins]]). The marketplace adds an index on top.
44
+ A marketplace can keep a plugin under `plugins/` or index a plugin from another Git repository. Local entries are complete plugins (see [[internal/plugins]]); the marketplace adds an index over either source.
46
45
 
47
46
  ## The manifest
48
47
 
@@ -72,16 +71,16 @@ Each entry under `plugins/` is a complete plugin (see [[internal/plugins]]). The
72
71
  | `owner` | optional | |
73
72
  | `plugins` | yes | Array. Each entry: `name`, `version`, `source`, `description`. |
74
73
 
75
- The `plugins[]` array IS the index — what's installable. A plugin on disk but not in the index won't resolve. A plugin in the index but missing from disk errors on install.
74
+ The `plugins[]` array IS the index — what's installable. Each entry's `source` is either a marketplace-relative path to a plugin directory or a remote Git URL. A local plugin on disk but not in the index won't resolve; an indexed local path missing from the marketplace errors on install.
76
75
 
77
- ## Install mechanics — symlinks, not clones
76
+ ## Install mechanics — local links and remote clones
78
77
 
79
- When a user runs `crtr pkg plugin install my-marketplace/plugin-a`:
80
- 1. Crouter looks up `plugin-a` in the marketplace's manifest.
81
- 2. **Symlinks** `<marketplace-clone>/plugins/plugin-a/` → `<user-scope>/plugins/plugin-a/`.
82
- 3. Records the install in the scope config with `source_marketplace: my-marketplace`.
78
+ When a user runs `crtr pkg plugin install my-marketplace/plugin-a`, crouter looks up `plugin-a` in the marketplace manifest and records the install with `source_marketplace: my-marketplace`.
83
79
 
84
- Therefore `crtr pkg market update --name my-marketplace` (which does `git pull` in the marketplace clone) updates every installed plugin from it — no per-plugin re-install, no second clone.
80
+ - A marketplace-relative `source` is symlinked from the marketplace checkout into the target scope, so `crtr pkg market update --name my-marketplace` updates its content through that checkout.
81
+ - A remote Git `source` is cloned into the target scope. Marketplace update refreshes the index; the installed plugin's own checkout is pulled during that update (or `crtr pkg plugin update`).
82
+
83
+ No per-plugin re-install is needed for content updates while the indexed source remains unchanged. Changing a remote entry's `source` requires removing and reinstalling that marketplace plugin so its checkout uses the new remote.
85
84
 
86
85
  ## Version-bump automation (recommended)
87
86
 
@@ -133,11 +132,11 @@ Existing users pick it up on their next `crtr pkg market update --name <marketpl
133
132
 
134
133
  ## Updating an existing plugin
135
134
 
136
- Edit content under `plugins/<name>/`. Commit with a conventional-commit subject. CI bumps the plugin manifest and the marketplace index entry together. No manual sync.
135
+ For a local plugin, edit `plugins/<name>/` and commit the plugin plus marketplace index together. For a remote Git source, update the plugin in its own repository, then update the marketplace entry's version as needed. If its `source` changes, users remove and reinstall the marketplace plugin to clone the replacement remote. Commit with a conventional-commit subject; CI can bump the marketplace index alongside local plugin changes.
137
136
 
138
137
  ## Removing a plugin
139
138
 
140
- Delete the plugin's directory AND its entry in `marketplace.json` → `plugins[]`. Commit with `feat!: remove <plugin>` to signal a major bump (the marketplace's contract changed for anyone depending on that plugin).
139
+ Delete the entry in `marketplace.json` → `plugins[]`; also delete its directory when it is a local source. Commit with `feat!: remove <plugin>` to signal a major bump (the marketplace's contract changed for anyone depending on that plugin).
141
140
 
142
141
  ## Marketplace registration scopes
143
142
 
@@ -154,10 +153,10 @@ A marketplace itself registers per-scope:
154
153
 
155
154
  `crtr sys doctor` checks marketplaces:
156
155
  - `marketplace.json` is valid JSON.
157
- - Every entry in `plugins[]` corresponds to a real directory under `plugins/`.
158
- - Each plugin under `plugins/` passes plugin-level validation.
156
+ - Every marketplace-relative entry in `plugins[]` resolves to a real local plugin directory. Remote-source validation occurs when crouter installs that plugin.
157
+ - Each installed plugin passes plugin-level validation.
159
158
 
160
- A plugin on disk but missing from the manifest is a **warning** (probably forgotten); a plugin in the manifest but missing on disk is an **error** (install would break).
159
+ A local plugin on disk but missing from the manifest is a **warning** (probably forgotten); an indexed local path missing on disk is an **error** (install would break).
161
160
 
162
161
  ## Cross-publishing with Claude Code
163
162
 
@@ -14,10 +14,10 @@ The **daemon** (`crtrd`) is the sole owner of canvas persistent state: it is the
14
14
 
15
15
  ## Spawn & delegate
16
16
 
17
- `crtr node new "<task>" --kind <kind>` launches a managed child broker and returns its id immediately; you **auto-subscribe** to it, so its finish wakes you. Delegating is the default move, not an optimization: a child's reading and tokens land in a fresh context window and only the conclusion comes back, keeping your own context (the scarce resource) free for steering.
17
+ `crtr node new "<task>" --kind <kind>` launches a managed child broker and returns its id immediately; you **auto-subscribe** to it, so its finish wakes you. A base node works hands-on and only spawns a child for a cleanly separable unit. An orchestrator delegates its decomposed work by default: a child's reading and tokens land in a fresh context window while the coordinator keeps only the conclusions needed to steer.
18
18
 
19
19
  - Match `--kind` to the work (`explore spec design plan developer review general`, plus any custom persona). See `node new -h`.
20
- - Fan **independent** units out as concurrent children — a wake with idle workers is wasted. Serialize only true dependencies; never let two live children edit the same files.
20
+ - An orchestrator fans **independent** units out concurrently. Serialize only true dependencies; never let two live children edit the same files.
21
21
  - `--root` spawns an independent node you neither manage nor are woken by (e.g. one a human will drive).
22
22
  - Once you delegate a unit, don't also run it yourself — you'll be woken when it finishes.
23
23
 
@@ -46,6 +46,6 @@ Tear-down: `node lifecycle close` cascade-cancels a node + its exclusive subtree
46
46
 
47
47
  ## Revive & the daemon
48
48
 
49
- A dormant node (done/idle/dead/canceled) is reopened with `node lifecycle revive <id>` (resumes the saved conversation, or `--fresh` to restart clean); mass-reconnecting EVERY disconnected node at once (a reboot/crash recovery) is `canvas revive --all` instead. `reviveNode()` is the **only** sanctioned launcher of a node's broker engine — it builds the pi invocation, sets `CRTR_NODE_ID` + canvas extensions, runs `transition('revive')`, and starts the headless broker host, keeping the db row and broker process in lockstep. Never spawn `pi --session` raw, and never open a node by spawning pi directly — UIs go through `surface node focus` / `node lifecycle revive`.
49
+ Use `node lifecycle revive <id>` to reopen one dormant or terminal node. It resumes an existing saved conversation by default; `--fresh` starts a new cycle on its existing session file, or a truly fresh session if no file exists. A finalized node requires `--reopen` before it can take a new mandate. Mass-reconnecting every eligible disconnected node after a reboot or outage is `canvas revive --all` instead. `reviveNode()` is the **only** sanctioned launcher of a node's broker engine — it builds the pi invocation, sets `CRTR_NODE_ID` + canvas extensions, runs `transition('revive')`, and starts the headless broker host, keeping the db row and broker process in lockstep. Never spawn `pi --session` raw, and never open a node by spawning pi directly — UIs go through `surface node focus` / `node lifecycle revive`.
50
50
 
51
- The daemon (`crtrd`, managed via `sys daemon start/stop/status`) is also the supervisor: alongside owning the store and serving the API, it polls broker liveness via `pi_pid` and auto-revives active/idle nodes whose broker exited. It does NOT host agents, open viewers, or auto-revive *canceled* nodes (reach for `node lifecycle revive` for those). When activating source changes, build, run `npm run install-runtime`, then restart the daemon because new daemon/brokers select the atomically switched, immutable generation while live brokers retain their own. Restarting is safe: it never signals running nodes.
51
+ The daemon (`crtrd`, managed via `sys daemon start/stop/status`) supervises live broker exits. It applies a bounded respawn policy to interrupted nonterminal nodes: a cleanly aborted saved turn resumes with a continuation, while a dirty interrupted turn, pending refresh, or pending cycle starts a fresh cycle from the saved session. Repeated short-lived exits and boot failures terminalize the node as `dead`; no automatic recovery occurs after terminalization, so use an explicit lifecycle revive or an inbox wake. It does not host agents or open viewers. When activating source changes, build, run `npm run install-runtime`, then restart the daemon because new daemon/brokers select the atomically switched, immutable generation while live brokers retain their own. Restarting is safe: it never signals running nodes.
@@ -5,8 +5,8 @@ when-and-why-to-read: When creating a crtr plugin, packaging memory docs for
5
5
  debugging install/resolution, this knowledge should be read so installs resolve
6
6
  predictably across scopes and command surfaces do not fail from manifest drift or protocol mistakes.
7
7
  short-form: How to author a crtr plugin — plugin.json manifest, directory
8
- layout, scopes, install mechanics, versioning, and command plugins (top-level
9
- CLI commands via commands.json + one executable). Use when creating a plugin,
8
+ layout, scopes, install mechanics, versioning, and command-capable plugins
9
+ (commands.json plus an exec or HTTP transport). Use when creating a plugin,
10
10
  packaging memory docs, contributing commands, or debugging install/resolution.
11
11
  system-prompt-visibility: name
12
12
  file-read-visibility: none
@@ -42,7 +42,7 @@ If it's a one-off note for yourself, scope-owned memory docs are simpler. Promot
42
42
  └── <name>.md
43
43
  ```
44
44
 
45
- The `<plugin-name>` directory IS the plugin. The manifest's `name` field must match the directory name (install renames if needed). Sibling dirs (`rules/`, `agents/`, and future `hooks/`) hold the other artifact types. A plugin that contributes CLI commands adds a `commands.json` manifest plus its executable — see [Command plugins](#command-plugins).
45
+ The `<plugin-name>` directory IS the plugin. The manifest's `name` field must match the directory name (install renames if needed). Sibling dirs (`rules/`, `agents/`, and future `hooks/`) hold the other artifact types. A plugin that contributes CLI commands adds a `commands.json` manifest plus a `transport` declaration — see [Plugin commands](#plugin-commands).
46
46
 
47
47
  ## The manifest
48
48
 
@@ -68,7 +68,8 @@ The `<plugin-name>` directory IS the plugin. The manifest's `name` field must ma
68
68
  | `description` | yes | One sentence. |
69
69
  | `source` | recommended | Git URL where the plugin lives. Used by `crtr pkg plugin update --name <name>`. |
70
70
  | `owner` | optional | Author info. |
71
- | `commands` | optional | Plugin-root-relative path to a `commands.json` command manifest. Present ⇒ the plugin contributes top-level `crtr` commands — see [Command plugins](#command-plugins). |
71
+ | `commands` | optional | Plugin-root-relative path to a `commands.json` command manifest. It must appear with `transport`; together they make the plugin contribute `crtr` commands — see [Plugin commands](#plugin-commands). |
72
+ | `transport` | optional | Required exactly when `commands` is present. `{ "kind": "exec", "executable": "bin/cmd.js" }` runs executable leaves; a passthrough-only exec manifest may omit `executable`. `{ "kind": "http", "endpoint": "https://…", "authEnv": "TOKEN_NAME" }` calls a remote HTTP command surface. |
72
73
 
73
74
  ## Scopes
74
75
 
@@ -83,7 +84,7 @@ Project-scope plugins outrank user-scope on resolution. Both outrank marketplace
83
84
 
84
85
  ## Install mechanics
85
86
 
86
- Three ways a plugin lands in a scope:
87
+ Four ways a plugin lands in a scope:
87
88
 
88
89
  1. **From a git URL** (`crtr pkg plugin install <url> --scope user`):
89
90
  - Clones into `<scope>/plugins/<name>/` using the manifest's name.
@@ -91,11 +92,15 @@ Three ways a plugin lands in a scope:
91
92
  - Independent of any marketplace.
92
93
 
93
94
  2. **From a marketplace** (`crtr pkg plugin install <mkt>/<name>`):
94
- - **Symlinks** the marketplace's `plugins/<name>/` into `<scope>/plugins/<name>/`.
95
- - `crtr pkg market update --name <mkt>` pulls updates for every installed plugin from that marketplace.
95
+ - A marketplace-relative `source` is symlinked from the marketplace checkout; a remote Git `source` is cloned into `<scope>/plugins/<name>/`.
96
+ - `crtr pkg market update --name <mkt>` refreshes the marketplace and every installed plugin it sources; relative sources follow the checkout, while remote-source checkouts pull their own Git remote.
96
97
  - See [[internal/marketplaces]].
97
98
 
98
- 3. **Authored in place** (you're writing the plugin in a working repo):
99
+ 3. **From an HTTP endpoint** (`crtr pkg plugin install --endpoint <url> --name <name> --scope user`):
100
+ - Fetches the served `commands.json`, then writes the plugin manifest and exact fetched bytes into the selected scope. The endpoint must use `https:`; `http:` is accepted only for `localhost`, `127.0.0.1`, `[::1]`, `::1`, or `host.docker.internal`, with no credentials or fragment.
101
+ - The install fails loudly and writes nothing when that fetch fails. Reinstalling the same HTTP plugin replaces its endpoint/auth-env declaration and stored manifest; it conflicts with an existing non-HTTP plugin of the same name.
102
+
103
+ 4. **Authored in place** (you're writing the plugin in a working repo):
99
104
  - Symlink for tight dev loop: `ln -s $(pwd) ~/.crouter/plugins/<name>`.
100
105
  - Or `crtr pkg plugin install file://$(pwd) --scope project` to clone-install.
101
106
 
@@ -131,7 +136,7 @@ Standard semver:
131
136
  | New doc, new section, new example | minor (0.1.0 → 0.2.0) |
132
137
  | Removed doc, renamed doc, changed manifest schema | major (0.1.0 → 1.0.0) |
133
138
 
134
- `crtr pkg plugin update --name <name>` reads the new version after pulling and updates the local config. Plugins published through a marketplace may have their `version` field bumped automatically by CI — see [[internal/marketplaces]].
139
+ `crtr pkg plugin update --name <name>` pulls source updates for ordinary and exec-transport plugins, while an HTTP-transport plugin unconditionally refetches and replaces its stored `commands.json`. A failed HTTP refresh preserves the prior bytes and exits nonzero. Plugins published through a marketplace may have their `version` field bumped automatically by CI — see [[internal/marketplaces]].
135
140
 
136
141
  ## Enable/disable
137
142
 
@@ -154,45 +159,63 @@ Bad plugin scope:
154
159
 
155
160
  If your memory doc conceptually depends on another plugin's doc, link via `## Related` with `` `<plugin>/<doc>` ``. Don't fork content; link it.
156
161
 
157
- ## Command plugins
162
+ ## Plugin commands
163
+
164
+ Beyond docs, a plugin may contribute **top-level `crtr` commands** — new noun branches with their own leaves. It does so through one `commands` pointer and one `transport` declaration. `transport.kind` selects how every leaf runs: `exec` direct-spawns a local executable; `http` calls the remote command surface. crtr owns parsing, native help, rendering, and errors for both.
158
165
 
159
- Beyond docs, a plugin may contribute **top-level `crtr` commands** — new noun branches with their own leaves. You declare one pointer in the manifest and ship one executable; crtr owns parsing, help, rendering, and errors, and direct-spawns your executable once per leaf invocation.
166
+ ### The manifest pointer and transport
160
167
 
161
- ### The manifest pointer
168
+ `commands` and `transport` appear together in `plugin.json`; a docs-only plugin declares neither:
169
+
170
+ ```json
171
+ {
172
+ "name": "deploy-tools",
173
+ "version": "0.1.0",
174
+ "description": "...",
175
+ "commands": "commands.json",
176
+ "transport": { "kind": "exec", "executable": "bin/cmd.js" }
177
+ }
178
+ ```
162
179
 
163
- Add `commands` to `plugin.json` — a plugin-root-relative path to one static manifest:
180
+ An HTTP-transport plugin replaces that declaration with:
164
181
 
165
182
  ```json
166
- { "name": "deploy-tools", "version": "0.1.0", "description": "...", "commands": "commands.json" }
183
+ "transport": { "kind": "http", "endpoint": "https://example.com/v1/cli/manifest", "authEnv": "DEPLOY_TOKEN" }
167
184
  ```
168
185
 
169
- Only an installed, **enabled** plugin's `commands` manifest contributes. Discovery is per-invocation: enable/disable/update/remove takes effect on the very next `crtr` call — no daemon restart, no cache to clear.
186
+ For `exec`, `executable` is required when the manifest has any executable leaf; a passthrough-only manifest omits it. When declared, it is plugin-root-relative, resolves inside the plugin root to a regular file, and carries the POSIX exec bit. For `http`, `endpoint` is an absolute endpoint and `authEnv` is optional. crtr stores only the environment variable **name**, never its credential; it reads the credential when fetching the manifest or invoking a leaf.
187
+
188
+ Only an installed, **enabled** plugin's command manifest contributes. Discovery is per-invocation: enable, disable, update, and remove take effect on the next `crtr` call — no daemon restart or cache clearing.
170
189
 
171
190
  ### commands.json shape
172
191
 
192
+ Both transports use a strict, static `commands.json` with `schemaVersion: 1` and a non-empty `mounts` array:
193
+
173
194
  ```json
174
195
  {
175
196
  "schemaVersion": 1,
176
- "executable": "bin/cmd.js",
177
197
  "mounts": [
178
- { "parent": [], "node": { "kind": "branch", "name": "app", "...": "..." } }
198
+ { "parent": [], "node": { "kind": "branch", "name": "app", "...": "..." } },
199
+ { "parent": ["app"], "node": { "kind": "branch", "name": "deploy", "...": "..." } }
179
200
  ]
180
201
  }
181
202
  ```
182
203
 
183
- - `schemaVersion` — exactly the integer `1`. Anything else rejects the whole manifest.
184
- - `executable` — plugin-root-relative path to the one command binary. Must resolve inside the plugin root, be a regular file, and carry the POSIX exec bit.
185
- - `mounts[]` — each `{ parent: [], node }`. v1 supports **top-level mounts only**: `parent` must be `[]`.
204
+ Each mount is `{ parent, node }`. `parent: []` contributes a top-level branch with `rootEntry { concept, description, whenToUse }`; a non-empty parent path attaches a node below a branch in the same plugin's manifest. Inline children and nested mounts form one forest. A nested mount whose parent is in a top-level inline tree resolves regardless of mount order; when one nested mount supplies another's parent, the parent mount comes first. Branches may have empty `children`, so another mount can fill them.
205
+
206
+ An exec manifest accepts only `schemaVersion` and `mounts`. Its leaves declare `outputKind: "object"`; branches may declare `passthrough`. An HTTP manifest additionally accepts optional absolute HTTP(S) `baseUrl` and positive-integer `timeouts { connectMs?, requestMs?, streamIdleMs? }`. Its leaves declare a `rest` mapping for method, path, parameter placement, and optional NDJSON streaming. The REST mapping is transport detail: generated `-h` presents HTTP and exec commands like native commands.
207
+
208
+ Every branch child is a branch (without `rootEntry`) or leaf. A leaf declares `params`, `output` (array of `{ name, type, required, constraint }`), and a non-empty `effects` array. Params use crtr's public vocabulary — one positional max, long-form `flag`s (types `string|int|bool|path|enum`, `choices` for enum), `stdin`, `context-file`; kebab-case names, no aliases. Two client-side affordances ride on a `positional` or `flag`: `encoding: "text"|"base64"` on a `type: "path"` param sends the named local FILE's content instead of the path string, and `defaultFromEnv: "UPPER_SNAKE"` fills an omitted `string`/`path` param from that environment variable on the calling machine, counting as supplied (so it satisfies `required` and is sent) — unlike a static `default`, which is a parse convenience only and never ships. `defaultFromEnv` is rejected alongside `default` or `repeatable`. The declaration mirrors crtr's stable help descriptors, not its internal TypeScript defs — no closures, dynamic state, or renderers.
186
209
 
187
- Every top-level `node` is a **branch** (`kind: "branch"`) carrying a `rootEntry { concept, description, whenToUse }` — the representation crtr renders at root help. Branch children are nested branches (no rootEntry) or leaves. A leaf declares `params`, `output` (array of `{ name, type, required, constraint }`), `outputKind: "object"`, and a non-empty `effects` array. Params use crtr's public vocabulary — one positional max, long-form `flag`s (types `string|int|bool|path|enum`, `choices` for enum), `stdin`, `context-file`; kebab-case names, no aliases. Two client-side affordances ride on a `positional` or `flag`: `encoding: "text"|"base64"` on a `type: "path"` param sends the named local FILE's content instead of the path string, and `defaultFromEnv: "UPPER_SNAKE"` fills an omitted `string`/`path` param from that environment variable on the calling machine, counting as supplied (so it satisfies `required` and is sent) — unlike a static `default`, which is a parse convenience only and never ships. `defaultFromEnv` is rejected alongside `default` or `repeatable`. The declaration mirrors crtr's stable help descriptors, not its internal TypeScript defs — no closures, no dynamic state, no renderers.
210
+ ### Execution and trust boundaries
188
211
 
189
- ### Execution: the trust boundary
212
+ An exec leaf direct-spawns its executable (no shell) only on explicit invocation — never on install, help, or discovery — with `--crtr-command-protocol 1`, the caller's cwd, and the full environment. It is **trusted local code running with the caller's authority**: crtr does not sandbox it, filter the environment, mint a credential, or interpret its backend authentication. This is an execution trust boundary, not a sandbox.
190
213
 
191
- On explicit leaf invocation — **never on install, help, or discovery** — crtr direct-spawns your executable (no shell) with `--crtr-command-protocol 1`, the caller's cwd, and the full environment. Installed command plugins are **trusted local code running with the caller's authority**: crtr does not sandbox them, filter the environment, mint a credential, or interpret your backend's auth. Your executable owns authentication to its own backend. This is an execution trust boundary, not a sandbox — installed code can already read the caller's files, so env filtering would only imply a security guarantee that does not exist.
214
+ An HTTP leaf is **definition plus HTTP only**: crtr fetches its manifest, renders native help from it, and executes the declared REST mapping. There is no local binary to spawn or sandbox. HTTP leaf calls retain their declared timeouts, bearer-token handling, NDJSON streaming, and structured HTTP error-envelope handling.
192
215
 
193
- ### The protocol
216
+ ### Exec protocol
194
217
 
195
- crtr writes exactly one JSON request to your executable's stdin:
218
+ For an exec leaf, crtr writes exactly one JSON request to the executable's stdin:
196
219
 
197
220
  ```json
198
221
  {
@@ -203,44 +226,37 @@ crtr writes exactly one JSON request to your executable's stdin:
203
226
  }
204
227
  ```
205
228
 
206
- `input` keys are the parser's camelCase form; a declared `stdin` param arrives as an `input` string, not a second stream. Your executable writes exactly one JSON envelope to stdout and nothing else — diagnostics go to stderr:
229
+ `input` keys are the parser's camelCase form; a declared `stdin` param arrives as an `input` string, not a second stream. The executable writes exactly one JSON envelope to stdout and nothing else — diagnostics go to stderr:
207
230
 
208
231
  ```json
209
232
  { "protocolVersion": 1, "ok": true, "result": { "app_id": "app_123" } }
210
233
  { "protocolVersion": 1, "ok": false, "error": { "code": "authentication_required", "message": "...", "field": "session", "next": "..." } }
211
234
  ```
212
235
 
213
- `ok` is the source of truth (a valid envelope is honored regardless of exit code). crtr validates `result` against your declared `output` (top-level field presence + type) and renders it; `--json` mirrors the same object. An error envelope becomes a normal crtr error with your `code` — lowercase snake_case, never crtr-reserved `internal`, `unknown_path`, `command_collision`, or `plugin_protocol_error`. No envelope at all (invalid JSON, empty, extra stdout, output over 10 MiB, signal kill) becomes `plugin_protocol_error`.
214
-
215
- ### Two rules that prevent silent breakage
216
-
217
- - **Generate `commands.json` from your command definitions — never hand-write it.** The manifest must stay in lockstep with the executable's actual command surface; a hand-maintained copy drifts, and a drifted param or output field surfaces as a validation issue or a `plugin_protocol_error` at invocation. Emit it from the same source your executable dispatches on.
218
- - **A required output field must be non-null.** The adapter treats an explicit `null` for a declared-required field as *absent* → `plugin_protocol_error`. If a value is genuinely optional, declare it `required: false`; if it's required, always return a real value.
219
-
220
- ### Validating your command manifest
221
-
222
- crtr validates command manifests **statically — it never executes your binary** to check them:
236
+ `ok` is the source of truth (a valid envelope is honored regardless of exit code). crtr validates `result` against the declared `output` (top-level field presence + type) and renders it; `--json` mirrors the same object. An error envelope becomes a normal crtr error with its lowercase snake_case `code`, except crtr-reserved `internal`, `unknown_path`, `command_collision`, and `plugin_protocol_error`. No envelope at all (invalid JSON, empty, extra stdout, output over 10 MiB, signal kill) becomes `plugin_protocol_error`.
223
237
 
224
- - `crtr pkg plugin show <name>` — inventories the manifest path, executable, accepted top-level command names, and every current validation issue (each with received/expected/next).
225
- - `crtr sys doctor` — validates the manifest + executable path for every effective command plugin and reports structured remediation (disable/update/remove). `--fix` never chmods or rewrites plugin content.
226
- - `crtr pkg plugin install` / `update` — report the accepted top-level commands and any issues in their result.
238
+ ### Keeping command surfaces valid
227
239
 
228
- A fixed manifest goes live on the next invocation; there is nothing to restart.
240
+ - **Generate an exec plugin's `commands.json` from its command definitions — never hand-write it.** The manifest must stay in lockstep with the executable's command surface; drifted params or output fields surface as a validation issue or `plugin_protocol_error` at invocation.
241
+ - **A required output field must be non-null.** The adapter treats an explicit `null` for a declared-required field as absent → `plugin_protocol_error`. If a value is optional, declare it `required: false`; if it is required, return a real value.
242
+ - **HTTP plugin manifests are fetched bytes.** `crtr pkg plugin install --endpoint <url> --name <name>` fetches before writing the plugin, then stores the exact response at the plugin's declared `commands` path. `crtr pkg plugin update` unconditionally refetches HTTP plugins; failures preserve the prior bytes and exit nonzero. The stored manifest is authoritative with no TTL, ETag, or revalidation. If its file is missing or unparseable, an unknown-first-token miss fetches each affected HTTP plugin once; diagnostics name `crtr pkg plugin update <name>`.
229
243
 
230
- ## Configured CLIs
244
+ ### Validation and command collisions
231
245
 
232
- A **configured CLI** is the other way a contributor adds `crtr` commands — the CLI analogue of an MCP client. Where a command plugin ships a local **executable**, a configured CLI is **definition + HTTP only**: crtr fetches a manifest from a remote endpoint, stores it locally, renders native `-h` help from it, and runs each leaf as a declarative REST call. There is no local binary to spawn and nothing to sandbox — a strictly narrower trust surface than a command plugin.
246
+ crtr validates command manifests statically; it never executes an exec binary to inspect its command surface:
233
247
 
234
- The manifest **is** the command-plugin `commands.json` schema (same `schemaVersion 1`, same node/param/output vocabulary, same reject-unknown-keys strictness), differing in exactly three ways: it drops `executable`, allows non-empty mount `parent` paths (a CLI builds a self-contained forest and may mount at depth), and every leaf carries a `rest` mapping (method/path/param placement/streaming flag) instead of `outputKind`. The `rest` mapping is transport — it never appears in generated `-h`, so a configured command is indistinguishable from a native one.
248
+ - `crtr pkg plugin show <name>` inventories the plugin manifest, command-manifest path, accepted top-level command names, and validation issues (each with received/expected/next).
249
+ - `crtr sys doctor` validates the command manifest and transport declaration for every effective plugin, including executable-path checks when exec manifests declare executable leaves, and reports structured remediation (disable, update, remove). `--fix` never chmods or rewrites plugin content.
250
+ - `crtr pkg plugin install` and `update` report accepted top-level command names and validation issues.
235
251
 
236
- Manage them under `crtr pkg cli` — `register` (records `{name, endpoint, auth-env NAME}` in scope config and fetches+stores the manifest), `remove`, `list`, `show`, `refresh`. crtr stores only the env var **name** holding the bearer token, never the credential. The stored manifest is authoritative with **zero freshness machinery** (no TTL, ETag, or revalidation): it reloads only on a re-register (the guest-boot path — a byte-identical re-register still re-fetches) or an explicit `refresh`, and a registration with no stored manifest (its register-time fetch failed) triggers a one-time hydration fetch on an unknown-first-token miss, the sole moment an absent store is detected. Inspect a CLI's accepted commands and validation/collision issues with `crtr pkg cli show <name>` and `crtr sys doctor`; both read the same unified snapshot dispatch uses. A configured CLI may never mount onto a core, plugin, or other-CLI path — core always wins, cross-contributor path clashes drop all claimants with a `command_collision` issue.
252
+ Core always wins a path collision. A cross-plugin collision drops every claimant with a `command_collision` issue. A fixed manifest goes live on the next invocation; there is nothing to restart.
237
253
 
238
254
  ## Validation
239
255
 
240
256
  `crtr sys doctor` checks each plugin's manifest:
241
257
  - Manifest exists and is valid JSON.
242
258
  - Manifest `name` matches the directory name.
243
- - When the plugin declares `commands`, its command manifest + executable path are validated statically (never executed) — see [Command plugins](#command-plugins).
259
+ - When the plugin declares `commands`, its command manifest and transport declaration are validated statically; an exec executable is never executed during validation — see [Plugin commands](#plugin-commands).
244
260
 
245
261
  `crtr memory lint` checks the docs under `memory/`: frontmatter parses, valid `kind`, both visibility rungs set. Run `crtr memory write -h` for the authoring + routing guide. Other sibling artifact dirs (`rules/`, `agents/`, `hooks/`) are validated by their respective specs as those land.
246
262
 
@@ -2,12 +2,9 @@
2
2
  kind: knowledge
3
3
  when-and-why-to-read: When shaping a planning roadmap, deciding plan structure, or preparing a consequential plan for implementation, this knowledge should be read so implementation receives a right-sized, parallel-safe execution map whose gaps are caught while they are still cheap to fix.
4
4
  short-form: Use when shaping a planning roadmap, deciding plan structure, or preparing a consequential plan for implementation.
5
- system-prompt-visibility: name
5
+ system-prompt-visibility: preview
6
6
  file-read-visibility: none
7
- gate:
8
- kind:
9
- imatches: '^plan($|/)'
10
- needs-refinement: true
7
+ gate: {kind: plan}
11
8
  rationale: >-
12
9
  The original playbook required five parallel plan reviewers before every consequential implementation and made “passes all five lenses” the ready bar. Combined with the plan persona's re-review loop, this turned lenses into agents and resolution into reviewer polling rather than plan-owner judgment.
13
10
  ---
@@ -18,9 +15,9 @@ rationale: >-
18
15
 
19
16
  Every planning effort produces either a flat plan or a decomposed plan (index + part-plans). Choosing the wrong shape wastes a cycle — a flat plan that is too large forces an implementer to hold too much at once; a decomposed plan for something small adds overhead for no gain.
20
17
 
21
- **Use a flat plan** when the work is a single coherent domain, involves fewer than ~6 files, and can be written at consistent task granularity without exceeding roughly 150–200 lines. A flat plan has an overview, ordered phases, and a verification section. No sub-plans. One file.
18
+ **Use a flat plan** when the work is a single coherent domain and can be written at consistent task granularity in one plan. A flat plan has an overview, ordered phases, and a verification section. No sub-plans. One file.
22
19
 
23
- **Use a decomposed plan** when the change spans multiple domains (e.g., data layer, API surface, UI), involves 6+ files, or would require a master plan that cannot be written at consistent granularity without ballooning. In this case: produce an index plan (the navigable master) and delegate each domain slice to a `plan`-kind child node, giving each child its slice scope, the relevant portion of the spec, and its place in the dependency graph. A slice that itself decomposes further — multiple sub-domains, more than one window's worth of planning — goes to a `plan` sub-orchestrator created directly (`crtr node new --kind plan --mode orchestrator`), not a base child relied on to promote itself. The index plan is the synthesis artifact — it lists all sub-plans by path, defines phases and their dependencies, and contains a task table the implementation orchestrator can execute directly. Detail lives in sub-plans; the master is not allowed to carry it.
20
+ **Use a decomposed plan** when the change spans multiple domains (e.g., data layer, API surface, UI) or would require a master plan that cannot be written at consistent granularity without ballooning. In this case: produce an index plan (the navigable master) and delegate each domain slice to a `plan`-kind child node, giving each child its slice scope, the relevant portion of the spec, and its place in the dependency graph. A slice that itself decomposes further — multiple sub-domains, more than one window's worth of planning — goes to a `plan` sub-orchestrator created directly (`crtr node new --kind plan --mode orchestrator`), not a base child relied on to promote itself. The index plan is the synthesis artifact — it lists all sub-plans by path, defines phases and their dependencies, and contains a task table the implementation orchestrator can execute directly. Detail lives in sub-plans; the master is not allowed to carry it.
24
21
 
25
22
  **The decomposition trigger is domain boundary, not size alone.** Three backend files and three frontend files are two domains even if the total count is modest — plan them separately and synthesize, because the integration seam is where bugs live and one agent reading both halves won't catch them as cleanly as two agents each going deep.
26
23