@arbiterforge/ca-pi 0.6.0

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 (206) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +558 -0
  3. package/package.json +35 -0
  4. package/plugins/ca-pi/CHANGELOG.md +1030 -0
  5. package/plugins/ca-pi/COMMANDS.md +90 -0
  6. package/plugins/ca-pi/ORCHESTRATOR.md +159 -0
  7. package/plugins/ca-pi/SKILLS.md +47 -0
  8. package/plugins/ca-pi/SPRINT.md +142 -0
  9. package/plugins/ca-pi/agents/INDEX.md +31 -0
  10. package/plugins/ca-pi/agents/architecture-drift-reviewer.md +86 -0
  11. package/plugins/ca-pi/agents/auth-crypto-reviewer.md +60 -0
  12. package/plugins/ca-pi/agents/backend-author.md +60 -0
  13. package/plugins/ca-pi/agents/checkpoint-aggregator.md +111 -0
  14. package/plugins/ca-pi/agents/coverage-auditor.md +71 -0
  15. package/plugins/ca-pi/agents/decision-challenger.md +116 -0
  16. package/plugins/ca-pi/agents/dependency-reviewer.md +79 -0
  17. package/plugins/ca-pi/agents/design-quality-reviewer.md +80 -0
  18. package/plugins/ca-pi/agents/finding-triage.md +86 -0
  19. package/plugins/ca-pi/agents/frontend-author.md +64 -0
  20. package/plugins/ca-pi/agents/grader.md +173 -0
  21. package/plugins/ca-pi/agents/infra-author.md +64 -0
  22. package/plugins/ca-pi/agents/map-deps.md +35 -0
  23. package/plugins/ca-pi/agents/map-structure.md +37 -0
  24. package/plugins/ca-pi/agents/migration-reviewer.md +65 -0
  25. package/plugins/ca-pi/agents/scout.md +127 -0
  26. package/plugins/ca-pi/agents/security-reviewer.md +72 -0
  27. package/plugins/ca-pi/agents/tribunal-lens-reviewer.md +65 -0
  28. package/plugins/ca-pi/extensions/codearbiter-child.js +1885 -0
  29. package/plugins/ca-pi/extensions/codearbiter.js +9802 -0
  30. package/plugins/ca-pi/generated/command-catalog.json +197 -0
  31. package/plugins/ca-pi/generated/roles.json +213 -0
  32. package/plugins/ca-pi/helpers/windows-supervisor.js +205 -0
  33. package/plugins/ca-pi/hooks/_activationlib.py +196 -0
  34. package/plugins/ca-pi/hooks/_arbiterstatelib.py +208 -0
  35. package/plugins/ca-pi/hooks/_babysitlib.py +76 -0
  36. package/plugins/ca-pi/hooks/_bashguardlib.py +1667 -0
  37. package/plugins/ca-pi/hooks/_boxlib.py +131 -0
  38. package/plugins/ca-pi/hooks/_colorlib.py +304 -0
  39. package/plugins/ca-pi/hooks/_durabilitylib.py +186 -0
  40. package/plugins/ca-pi/hooks/_entrylib.py +41 -0
  41. package/plugins/ca-pi/hooks/_fmtlib.py +161 -0
  42. package/plugins/ca-pi/hooks/_gitexec.py +45 -0
  43. package/plugins/ca-pi/hooks/_githooks.py +920 -0
  44. package/plugins/ca-pi/hooks/_gitlib.py +110 -0
  45. package/plugins/ca-pi/hooks/_hooklib.py +595 -0
  46. package/plugins/ca-pi/hooks/_host.py +115 -0
  47. package/plugins/ca-pi/hooks/_intentlib.py +242 -0
  48. package/plugins/ca-pi/hooks/_ledgerlib.py +1035 -0
  49. package/plugins/ca-pi/hooks/_metricslib.py +709 -0
  50. package/plugins/ca-pi/hooks/_pathnorm.py +74 -0
  51. package/plugins/ca-pi/hooks/_planfilelib.py +664 -0
  52. package/plugins/ca-pi/hooks/_previewlib.py +193 -0
  53. package/plugins/ca-pi/hooks/_protectedlib.py +312 -0
  54. package/plugins/ca-pi/hooks/_protectedstatelib.py +411 -0
  55. package/plugins/ca-pi/hooks/_provenancelib.py +971 -0
  56. package/plugins/ca-pi/hooks/_prunelib.py +1398 -0
  57. package/plugins/ca-pi/hooks/_prunepolicy.py +235 -0
  58. package/plugins/ca-pi/hooks/_readinjectlib.py +1080 -0
  59. package/plugins/ca-pi/hooks/_releaselib.py +2657 -0
  60. package/plugins/ca-pi/hooks/_scopelib.py +262 -0
  61. package/plugins/ca-pi/hooks/_segmentslib.py +278 -0
  62. package/plugins/ca-pi/hooks/_sensitivelib.py +270 -0
  63. package/plugins/ca-pi/hooks/_sessionlib.py +78 -0
  64. package/plugins/ca-pi/hooks/_sloplib.py +244 -0
  65. package/plugins/ca-pi/hooks/_standuplib.py +214 -0
  66. package/plugins/ca-pi/hooks/_subagentslib.py +219 -0
  67. package/plugins/ca-pi/hooks/_taskboardlib.py +1088 -0
  68. package/plugins/ca-pi/hooks/_updatelib.py +278 -0
  69. package/plugins/ca-pi/hooks/babysit.py +47 -0
  70. package/plugins/ca-pi/hooks/boardsync.py +129 -0
  71. package/plugins/ca-pi/hooks/doctor.py +420 -0
  72. package/plugins/ca-pi/hooks/git-enforce.py +325 -0
  73. package/plugins/ca-pi/hooks/hostapi.py +460 -0
  74. package/plugins/ca-pi/hooks/init-codearbiter.py +225 -0
  75. package/plugins/ca-pi/hooks/metrics.py +62 -0
  76. package/plugins/ca-pi/hooks/migration-pass.py +129 -0
  77. package/plugins/ca-pi/hooks/pi-bridge.py +543 -0
  78. package/plugins/ca-pi/hooks/post-write-edit.py +231 -0
  79. package/plugins/ca-pi/hooks/pre-bash.py +90 -0
  80. package/plugins/ca-pi/hooks/pre-edit.py +284 -0
  81. package/plugins/ca-pi/hooks/pre-read.py +81 -0
  82. package/plugins/ca-pi/hooks/pre-write.py +217 -0
  83. package/plugins/ca-pi/hooks/preview.py +69 -0
  84. package/plugins/ca-pi/hooks/prune-transcript.py +232 -0
  85. package/plugins/ca-pi/hooks/releasehash.py +216 -0
  86. package/plugins/ca-pi/hooks/security-pass.py +139 -0
  87. package/plugins/ca-pi/hooks/session-start.py +1218 -0
  88. package/plugins/ca-pi/hooks/statusline.py +736 -0
  89. package/plugins/ca-pi/hooks/taskwrite.py +351 -0
  90. package/plugins/ca-pi/hooks/update-refresh.py +51 -0
  91. package/plugins/ca-pi/hooks/wire-statusline.py +435 -0
  92. package/plugins/ca-pi/includes/anti-slop-design/INDEX.md +55 -0
  93. package/plugins/ca-pi/includes/anti-slop-design/color.md +43 -0
  94. package/plugins/ca-pi/includes/anti-slop-design/core.md +244 -0
  95. package/plugins/ca-pi/includes/anti-slop-design/images.md +32 -0
  96. package/plugins/ca-pi/includes/anti-slop-design/layout.md +45 -0
  97. package/plugins/ca-pi/includes/anti-slop-design/medium-cli.md +39 -0
  98. package/plugins/ca-pi/includes/anti-slop-design/medium-dataviz.md +43 -0
  99. package/plugins/ca-pi/includes/anti-slop-design/medium-diagram.md +35 -0
  100. package/plugins/ca-pi/includes/anti-slop-design/medium-documents.md +70 -0
  101. package/plugins/ca-pi/includes/anti-slop-design/medium-slides.md +30 -0
  102. package/plugins/ca-pi/includes/anti-slop-design/medium-web.md +39 -0
  103. package/plugins/ca-pi/includes/anti-slop-design/typography.md +51 -0
  104. package/plugins/ca-pi/includes/author-tdd-workflow.md +14 -0
  105. package/plugins/ca-pi/includes/compaction-charter.md +16 -0
  106. package/plugins/ca-pi/includes/cut-docs.md +16 -0
  107. package/plugins/ca-pi/includes/dev-mode.md +30 -0
  108. package/plugins/ca-pi/includes/farm.md +237 -0
  109. package/plugins/ca-pi/includes/fresh-verification.md +14 -0
  110. package/plugins/ca-pi/includes/harvest.md +69 -0
  111. package/plugins/ca-pi/includes/maturity-coverage.md +102 -0
  112. package/plugins/ca-pi/includes/pi-host-notes.md +69 -0
  113. package/plugins/ca-pi/includes/redirect.md +69 -0
  114. package/plugins/ca-pi/includes/reference-map.md +22 -0
  115. package/plugins/ca-pi/includes/review-matrix.md +14 -0
  116. package/plugins/ca-pi/includes/reviewer-contract.md +53 -0
  117. package/plugins/ca-pi/includes/routing-table.md +47 -0
  118. package/plugins/ca-pi/includes/security-gate-record.md +22 -0
  119. package/plugins/ca-pi/includes/smarts/core.md +90 -0
  120. package/plugins/ca-pi/includes/smarts/decision-log-format.md +56 -0
  121. package/plugins/ca-pi/routines/INDEX.md +32 -0
  122. package/plugins/ca-pi/routines/brainstorming/SKILL.md +122 -0
  123. package/plugins/ca-pi/routines/commit-gate/SKILL.md +151 -0
  124. package/plugins/ca-pi/routines/context-check/SKILL.md +85 -0
  125. package/plugins/ca-pi/routines/context-creation/SKILL.md +171 -0
  126. package/plugins/ca-pi/routines/crypto-compliance/SKILL.md +41 -0
  127. package/plugins/ca-pi/routines/debug/SKILL.md +99 -0
  128. package/plugins/ca-pi/routines/decision-lifecycle/SKILL.md +104 -0
  129. package/plugins/ca-pi/routines/decision-lifecycle/references/adr-template.md +74 -0
  130. package/plugins/ca-pi/routines/decision-variance/SKILL.md +147 -0
  131. package/plugins/ca-pi/routines/decompose/SKILL.md +168 -0
  132. package/plugins/ca-pi/routines/dispatching-parallel-agents/SKILL.md +76 -0
  133. package/plugins/ca-pi/routines/executing-plans/SKILL.md +83 -0
  134. package/plugins/ca-pi/routines/finishing-a-development-branch/SKILL.md +91 -0
  135. package/plugins/ca-pi/routines/post-merge-cleanup/SKILL.md +233 -0
  136. package/plugins/ca-pi/routines/refactor/SKILL.md +91 -0
  137. package/plugins/ca-pi/routines/release/SKILL.md +315 -0
  138. package/plugins/ca-pi/routines/secret-handling/SKILL.md +67 -0
  139. package/plugins/ca-pi/routines/security-architecture/SKILL.md +63 -0
  140. package/plugins/ca-pi/routines/skill-author/SKILL.md +108 -0
  141. package/plugins/ca-pi/routines/skill-author/references/skill-template.md +58 -0
  142. package/plugins/ca-pi/routines/subagent-driven-development/SKILL.md +149 -0
  143. package/plugins/ca-pi/routines/subagent-driven-development/references/farm-dispatch.md +145 -0
  144. package/plugins/ca-pi/routines/tdd/SKILL.md +139 -0
  145. package/plugins/ca-pi/routines/tribunal/SKILL.md +109 -0
  146. package/plugins/ca-pi/routines/tribunal/references/ai-markers.md +29 -0
  147. package/plugins/ca-pi/routines/tribunal/references/cost-and-models.md +64 -0
  148. package/plugins/ca-pi/routines/tribunal/references/finding-record.md +27 -0
  149. package/plugins/ca-pi/routines/tribunal/references/issue-filing.md +47 -0
  150. package/plugins/ca-pi/routines/tribunal/references/lenses/appsec.md +22 -0
  151. package/plugins/ca-pi/routines/tribunal/references/lenses/architecture.md +23 -0
  152. package/plugins/ca-pi/routines/tribunal/references/lenses/coverage.md +20 -0
  153. package/plugins/ca-pi/routines/tribunal/references/lenses/infra.md +24 -0
  154. package/plugins/ca-pi/routines/tribunal/references/lenses/migration.md +22 -0
  155. package/plugins/ca-pi/routines/tribunal/references/lenses/observability.md +21 -0
  156. package/plugins/ca-pi/routines/tribunal/references/lenses/performance.md +22 -0
  157. package/plugins/ca-pi/routines/tribunal/references/lenses/reliability.md +23 -0
  158. package/plugins/ca-pi/routines/tribunal/references/lenses/secrets-supply.md +22 -0
  159. package/plugins/ca-pi/routines/tribunal/references/lenses/test-fidelity.md +24 -0
  160. package/plugins/ca-pi/routines/tribunal/references/lenses/typesafety.md +21 -0
  161. package/plugins/ca-pi/routines/tribunal/references/report.md +19 -0
  162. package/plugins/ca-pi/routines/tribunal/references/schemas.md +58 -0
  163. package/plugins/ca-pi/routines/tribunal/references/telemetry.md +28 -0
  164. package/plugins/ca-pi/routines/tribunal/references/triage.md +53 -0
  165. package/plugins/ca-pi/routines/using-git-worktrees/SKILL.md +85 -0
  166. package/plugins/ca-pi/routines/writing-plans/SKILL.md +129 -0
  167. package/plugins/ca-pi/routines/writing-plans/references/farm-plan.md +50 -0
  168. package/plugins/ca-pi/skills/ca-add-dep/SKILL.md +88 -0
  169. package/plugins/ca-pi/skills/ca-adr/SKILL.md +30 -0
  170. package/plugins/ca-pi/skills/ca-adr-status/SKILL.md +30 -0
  171. package/plugins/ca-pi/skills/ca-arbiter/SKILL.md +36 -0
  172. package/plugins/ca-pi/skills/ca-audit/SKILL.md +51 -0
  173. package/plugins/ca-pi/skills/ca-btw/SKILL.md +23 -0
  174. package/plugins/ca-pi/skills/ca-checkpoint/SKILL.md +50 -0
  175. package/plugins/ca-pi/skills/ca-chore/SKILL.md +58 -0
  176. package/plugins/ca-pi/skills/ca-cleanup/SKILL.md +55 -0
  177. package/plugins/ca-pi/skills/ca-commands/SKILL.md +21 -0
  178. package/plugins/ca-pi/skills/ca-commit/SKILL.md +27 -0
  179. package/plugins/ca-pi/skills/ca-conflict/SKILL.md +61 -0
  180. package/plugins/ca-pi/skills/ca-context-check/SKILL.md +32 -0
  181. package/plugins/ca-pi/skills/ca-create-context/SKILL.md +32 -0
  182. package/plugins/ca-pi/skills/ca-debug/SKILL.md +42 -0
  183. package/plugins/ca-pi/skills/ca-decompose/SKILL.md +30 -0
  184. package/plugins/ca-pi/skills/ca-dev/SKILL.md +42 -0
  185. package/plugins/ca-pi/skills/ca-doctor/SKILL.md +44 -0
  186. package/plugins/ca-pi/skills/ca-feature/SKILL.md +105 -0
  187. package/plugins/ca-pi/skills/ca-fix/SKILL.md +42 -0
  188. package/plugins/ca-pi/skills/ca-init/SKILL.md +56 -0
  189. package/plugins/ca-pi/skills/ca-metrics/SKILL.md +80 -0
  190. package/plugins/ca-pi/skills/ca-new-skill/SKILL.md +34 -0
  191. package/plugins/ca-pi/skills/ca-override/SKILL.md +72 -0
  192. package/plugins/ca-pi/skills/ca-pr/SKILL.md +61 -0
  193. package/plugins/ca-pi/skills/ca-preview/SKILL.md +86 -0
  194. package/plugins/ca-pi/skills/ca-prune/SKILL.md +100 -0
  195. package/plugins/ca-pi/skills/ca-reconcile/SKILL.md +43 -0
  196. package/plugins/ca-pi/skills/ca-refactor/SKILL.md +43 -0
  197. package/plugins/ca-pi/skills/ca-release/SKILL.md +57 -0
  198. package/plugins/ca-pi/skills/ca-review/SKILL.md +63 -0
  199. package/plugins/ca-pi/skills/ca-spike/SKILL.md +41 -0
  200. package/plugins/ca-pi/skills/ca-sprint/SKILL.md +44 -0
  201. package/plugins/ca-pi/skills/ca-standup/SKILL.md +112 -0
  202. package/plugins/ca-pi/skills/ca-status/SKILL.md +56 -0
  203. package/plugins/ca-pi/skills/ca-task/SKILL.md +61 -0
  204. package/plugins/ca-pi/skills/ca-threat-model/SKILL.md +45 -0
  205. package/plugins/ca-pi/skills/ca-tribunal/SKILL.md +44 -0
  206. package/plugins/ca-pi/skills/ca-watch/SKILL.md +78 -0
@@ -0,0 +1,1030 @@
1
+ # Changelog
2
+
3
+ All notable changes to `ca-pi` are documented in this file.
4
+
5
+ ## [Unreleased]
6
+
7
+ ## [0.6.0] - 2026-08-09
8
+
9
+ ### Added
10
+
11
+ - npm distribution channel (ADR-0029): the package is now also published as
12
+ `npm:@arbiterforge/ca-pi` by CI on every `ca-pi-v*` tag, with npm provenance.
13
+ The root manifest became the publish unit (scoped name, `files` whitelist,
14
+ `publishConfig`, `repository`; `private` removed); the nested manifest keeps
15
+ `private: true` as an accidental-publish guard. The pinned Git install
16
+ remains the reproducible channel. Install: `pi install npm:@arbiterforge/ca-pi`.
17
+
18
+ ## [0.5.0] - 2026-08-09
19
+
20
+ ### Added
21
+
22
+ - Rich footer parity gaps closed (spec `pi-footer-parity-gaps`): a per-message
23
+ token-burn sparkline derived from Pi session entries (last 20 assistant
24
+ messages, snapshot-independent); refresh-time git repository name and dirty
25
+ indicator for affirmatively trusted projects (bounded `git` spawn — explicit
26
+ argv, `shell: false`, 2s timeout, capped output, omit-on-failure); and up to
27
+ four per-item activity rows with a `+N more` overflow in the wide layout.
28
+ Rate-window telemetry stays omitted, never fabricated.
29
+
30
+ ## [0.4.1] - 2026-08-08
31
+
32
+ ### Changed
33
+
34
+ - Routine frontmatter carries `disable-model-invocation: true` on the nine chain-internal routines (inert on this host) and JSON-quoted scalars per `_yaml_safe_scalar`; route sites cite explicit routine paths.
35
+
36
+ ## [0.4.0] - 2026-08-08
37
+
38
+ ### Changed
39
+
40
+ - Tribunal roster consolidated: the eleven per-lens `tribunal-*-reviewer` roles are replaced
41
+ by one generic `tribunal-lens-reviewer` role dispatched once per active lens; the lens
42
+ cards under `routines/tribunal/references/lenses/` carry each lens's mandate, scope
43
+ emphasis, and required reading. `generated/roles.json` reshapes from 28 to 18 roles.
44
+ - Gate reviewers and authors now load their shared findings/output/TDD contracts from
45
+ `includes/reviewer-contract.md` and `includes/author-tdd-workflow.md` instead of
46
+ restating them per role.
47
+
48
+ ## [0.3.1] - 2026-08-07
49
+
50
+ ### Fixed
51
+
52
+ - `/ca:release`'s `--dry-run` no longer executes a declared `rebuild`/`generate`
53
+ command — it previously ran the row's rebuild unconditionally, overwriting a
54
+ committed build artifact despite promising not to write anything. Found and
55
+ fixed by a required pre-tag blind agent-judgment exercise against the shared
56
+ release-lib core.
57
+ - Phase 3's `resume_publish` path can now reconstruct release notes from the
58
+ committed CHANGELOG via a new `changelog-section` CLI subcommand, instead of
59
+ depending on a scratch file that does not survive a session boundary.
60
+
61
+ ## [0.3.0] - 2026-08-07
62
+
63
+ ### Added
64
+
65
+ - Recorded intent precedes autonomous scoring and spec shaping (ADR-0025),
66
+ projected from the shared core: SMARTS Step 0 (scoped to sprint scoring and
67
+ brainstorming; decision-variance, grader, and decision-challenger exempt by
68
+ name), the sprint pre-approval intent read with the contradiction hard gate
69
+ and stale-record valve, the pinned `intent:` sprint-log field position, and
70
+ the brainstorming routine's deferral-resurrection and accepted-ADR
71
+ conformance checks. Index-first and fail-soft throughout; a project with no
72
+ decomposition record proceeds untouched. Pinned across hosts by
73
+ `test_recorded_intent_surface.py`.
74
+
75
+ ## [0.2.19] - 2026-08-06
76
+
77
+ ### Fixed
78
+
79
+ - Chain-mode dispatch threaded a prior child's `summary` into the next child's task prompt verbatim, bypassing `redaction.ts` even though the redactor is already imported into `dispatch.ts` and already applied to the audit sink (#555). A child that reads a secret-bearing file could put that text into the next child's *instructions*, not just its own output. `taskEnvelope()` now applies the shared `redactSecrets` to `prior.summary` before it is embedded, closing the wiring gap without truncating or altering the rest of the forwarded Markdown report.
80
+
81
+ ## [0.2.18] - 2026-08-06
82
+
83
+ ### Fixed
84
+
85
+ - `bridge.test.ts`'s hung-tree cancellation tests no longer race a fixed wall-clock margin against real Windows process-launch overhead (#580): the hostile test fixture's mutation delay is widened with real headroom and the fixed post-cancellation sleep is replaced with a fail-fast poll, removing a false-flake window measured (in a controlled trial) to leak 8/8 times once the kill trigger fired late and 0/15 times when it fired on schedule. `bridge.ts`'s Windows tree-kill (`killTree`) is also converted from a blocking `spawnSync` taskkill invocation to a non-blocking async one, matching `process-tree.ts`'s own pattern, so a slow kill can no longer stall the event loop it is itself racing.
86
+ - Several `ca-pi` tests that launch real Windows processes under `--coverage` (package.test.ts's live-Pi-loader case, bridge.test.ts's force-settle case) now carry an explicit timeout headroom instead of relying on vitest's 5s default, addressing the same fixed-margin-vs-real-latency shape reported in #559.
87
+
88
+ ## [0.2.17] - 2026-08-06
89
+
90
+ ### Fixed
91
+
92
+ - Corrected the 2.11.0 changelog entry's protected-state-registry description
93
+ to name its three enrolled consumers instead of claiming it ships empty;
94
+ the same stale claim in `_protectedstatelib.py` and `_bashguardlib.py` is
95
+ corrected to match (shared `core/pysrc/` kernel).
96
+ - The release skill's Phase 3 release-notes command used bracket notation
97
+ (`--latest[=false]`), which is prose shorthand and not runnable shell;
98
+ split into the two runnable commands the surrounding prose already
99
+ describes.
100
+ - Pre-flight's clean-tree requirement and the later rebuild step read as
101
+ contradictory in isolation; added a note distinguishing the entry
102
+ condition from the later, deliberately-reconciled exception.
103
+ - `medium-documents` was cited by bare name in the release skill's changelog
104
+ step while every sibling include in the same sentence carries a full
105
+ path; pathed it to match.
106
+ - `load_targets()` folded every unreadable declared-targets file into
107
+ "absent"; added `UnreadableTargetsFileError` so the two cases are
108
+ distinguishable (shared `core/pysrc/` kernel).
109
+ - The context-creation skill's single-target template omitted
110
+ `latest-eligible: true`, disagreeing with the release skill's own
111
+ back-fill detector for the identical shape.
112
+ - `row_assertions()` reported a blank `rebuild: ""` string as a declared
113
+ command instead of "not declared" (shared `core/pysrc/` kernel).
114
+ - `select_release_target_by_name()` returned the bare string `""` for a
115
+ pair with a blank NAME, outside its own documented result vocabulary
116
+ (shared `core/pysrc/` kernel).
117
+
118
+ ## [0.2.16] - 2026-08-06
119
+
120
+ ### Fixed
121
+
122
+ - `run-pre-tag` now resolves a POSIX-compatible shell (Git for Windows' own `bash.exe`) to dispatch a target's declared `pre-tag` commands, instead of always dispatching through `cmd.exe` on Windows — so a row spelled `"$PY" <script>` (the #601 convention) now runs correctly on every platform, not just POSIX. A Windows host with no POSIX shell reachable at all now reports a distinct "could not run" diagnosis (exit 9) rather than misreading the absence as drift. This repository's own `.codearbiter/release-targets.md` `pre-tag` rows are rewritten from hardcoded `python3` to `"$PY"` now that the fix makes it portable (#602).
123
+
124
+ ## [0.2.15] - 2026-08-05
125
+
126
+ ### Added
127
+
128
+ - INDEX.md / routing-table.md consistency is now a CI-checked invariant instead of an authoring discipline: `check_routing_index_parity.py` fails the build when a skill/routine/agent is missing its INDEX row, an INDEX row points at nothing, or `includes/routing-table.md` routes to a name that does not exist — across all four generated surfaces. `skill-author`'s routing-integration phase now cites the check instead of re-stating the hand-verification it replaces (#592).
129
+
130
+ ## [0.2.14] - 2026-08-05
131
+
132
+ ### Added
133
+
134
+ - `/ca:release --dry-run` is now real: it runs Pre-flight and Phase 1's read-only version derivation, then reports the target, the derived version and rationale, the per-commit classification, and the resolved declared row, without writing a changelog entry, bumping a manifest, committing, or tagging (#565).
135
+ - A new `uncovered_intent` helper (`_intentlib.py`) backstops `writing-plans`' bijective plan/criteria check with a citation check against the spec's own scope bullets and a linked issue's acceptance checkboxes (#566).
136
+
137
+ ### Fixed
138
+
139
+ - `writing-plans`' Phase 4 gate is reframed to state only what bijection actually proves — plan/ledger agreement, never ledger completeness — and both `brainstorming` and `writing-plans` now ask an explicit negative-judgment question a bijective check cannot mechanize (#566).
140
+
141
+ ## [0.2.13] - 2026-08-05
142
+
143
+ ### Fixed
144
+
145
+ - Six governance rules in `.github/scripts/test_release_lib.py` that pin
146
+ load-bearing release-skill doctrine had every anchor token also occurring
147
+ elsewhere in the skill, so deleting the one sentence each names could
148
+ slip through with the rule staying green. Each is now re-anchored on a
149
+ span unique to its own guarded sentence — checked against `ca-pi`'s own
150
+ rendered copy (`routines/release/SKILL.md`) as well as the source and the
151
+ other two payloads — with a pinned RED/GREEN mutation proof (#571).
152
+
153
+ ## [0.2.12] - 2026-08-05
154
+
155
+ ### Fixed
156
+
157
+ - The git-level hook backstop (#161) could run from an arbitrarily stale host plugin cache, resurrecting an already-closed false positive (the #279 sensitive-scan exemption) instead of the current, correct enforcement. Each live host's session now records a content-addressed freshness heartbeat (`.git/codearbiter-hooksd/<plugin>.seen`) alongside its registered enforcer entry; the generated shim skips a registered entry whose heartbeat is missing or stale relative to a fresher registered sibling. `/ca:doctor` now surfaces a stale drop-in entry before it can produce a false block (#556).
158
+
159
+ ## [0.2.11] - 2026-08-05
160
+
161
+ ### Fixed
162
+
163
+ - The H-11 authoring-marker freshness window is now declared exactly once (`_hooklib.MARKER_FRESHNESS_MINUTES`) and imported by every enforcement flank, instead of five independently hardcoded copies of the same literal (#567).
164
+ - `_releaselib.py`'s unreachable `_PRERELEASE_MARKERS` dead code is removed (#568).
165
+
166
+ ## [0.2.9] - 2026-08-05
167
+
168
+ ### Fixed
169
+
170
+ - A linked-worktree session running `security-pass.py`/`migration-pass.py`
171
+ bare (no `CLAUDE_PROJECT_DIR` in that shell) recorded a gate pass at the
172
+ worktree's own (gitignored) `.codearbiter/.markers/`, invisible to the
173
+ H-09b/H-10b/H-14 commit guards, which read markers from the main checkout.
174
+ A new `marker_root()` host seam gives both sides the same answer without
175
+ moving the diff/migration scan root itself (#604).
176
+
177
+ ## [0.2.8] - 2026-08-05
178
+
179
+ ### Fixed
180
+
181
+ - H-05/H-11/H-18 (audit logs, ADRs, `CONTEXT.md`) gain the interpreter leg H-22/H-19 already carried, closing an inline-code one-liner bypass (`python3 -c`, `py -c`, `pwsh -Command`) (#574).
182
+ - H-22's git-restore leg now also covers restoring a registered file's enclosing directory, and a package manager's `install` subcommand no longer false-blocks against coreutils' `install` verb (#575).
183
+ - The Codex host notes' audit-log append recipe no longer directs Windows PowerShell 5.1 users to bare `>>`, which can write a UTF-16LE tail onto an existing UTF-8 log; it now uses an explicit UTF-8-no-BOM append with a documented verification step (#594).
184
+
185
+ ## [0.2.7] - 2026-08-05
186
+
187
+ ### Fixed
188
+
189
+ - Every routine/skill surface that spelled the interpreter fallback as `python3 X || python X` now resolves the interpreter once, by presence, before invoking a helper (#577), so a helper answer that carries information in a nonzero exit code is no longer silently re-run and replaced by a second run's verdict.
190
+
191
+ ## [0.2.6] - 2026-08-05
192
+
193
+ ### Changed
194
+
195
+ - The `tdd` routine's red phase gains a rationalization guard (four skip-red excuses paired with rebuttals, A/B-validated before shipping), and `skill-author` adopts the issue #612 evidence-lens checklist for future authoring passes.
196
+
197
+ ## [0.2.5] - 2026-08-05
198
+
199
+ ### Changed
200
+
201
+ - The orchestrator persona is restructured on measured A/B evidence (#609): hard rules move to the head of the document, a rationalization guard and a letter-vs-spirit rule intercept gate-skipping, every user-facing ask leads with a recommendation and its strongest counter-case, a suspicious gate is diagnosed before any bypass, and the startup-presentation instructions move out of the always-on persona and into the SessionStart briefing itself.
202
+
203
+ ## [0.2.4] - 2026-08-04
204
+
205
+ ### Changed
206
+
207
+ - The `brainstorming` routine is modernized for capable models: bundles split before refinement, candidate approaches shaped with one recommendation, parameter choices decided-and-recorded while genuine forks are asked in full, a breaker stops non-converging loops, and the spec is mechanically self-reviewed and adversarially challenged before approval.
208
+
209
+ ## [0.2.3] - 2026-08-04
210
+
211
+ ### Fixed
212
+
213
+ - ORCHESTRATOR.md §6 now defines the tier-1/tier-2 boundary operationally: a fully-resolved command with a complete argument routes directly (ADR-0022 tier 1) instead of asking "did you mean" while displaying the already-resolved command (#595).
214
+
215
+ ## [0.2.2] - 2026-08-04
216
+
217
+ ### Fixed
218
+
219
+ - `post-merge-cleanup` (issue #586): the Phase 1 gate no longer STOPs on every squash-merged branch. SHA-ancestry is now one of two accepted containment proofs — the second is the merged PR record (`headRefOid` == HEAD), reported alongside the ancestry check's negative result rather than treated as a failure. Phase 4 now fast-forwards the local default ref before checking it out, so a stale local default can no longer be misattributed to a correctly-kept Phase 3 artifact. Phase 5 documents why `-d` can accept a squash merge via its upstream, and sanctions `-D` only when this run's Phase 1 proof was the PR-record squash proof and `-d` refused.
220
+ - `standup` (issue #596): stale worktrees can now be confirmed as one explicitly enumerated group naming every member, instead of one confirmation per worktree; declining the group falls back to per-item confirmation. Branch pruning documents the same squash-merge `-D` exception as `post-merge-cleanup`.
221
+
222
+ ## [0.2.1] - 2026-08-04
223
+
224
+ ### Fixed
225
+
226
+ - The shared `_releaselib.py` copy picks up the release lane's `run-pre-tag`
227
+ exit-code split (could-not-run vs. drift vs. tree-probe failure), the
228
+ exported `PY` environment variable for declared row commands, and the new
229
+ `apply-bump` subcommand — no ca-pi-specific behavior change, tracked here
230
+ because the shared module is vendored into this plugin's `hooks/`
231
+ directory.
232
+
233
+ ## [0.2.0] - 2026-08-01
234
+
235
+ ### Added
236
+
237
+ - Protected-state registry (hook `H-22`): `.codearbiter/` files can be enrolled as `marker-gated`, `helper-only`, or `append-only`, enforced across the Write, Edit, and shell flanks. `release-targets.md`, `open-tasks.md`, and `done-tasks.md` are enrolled, one per policy.
238
+ - `taskwrite archive` moves a long-done task to `done-tasks.md`, writing the permanent record before removing from the board so an interrupted run cannot lose it.
239
+
240
+ ### Fixed
241
+
242
+ - `_releaselib.py` spawned git as a bare `git`, bypassing the trusted-path seam every Pi-reachable module must use.
243
+ - The shell flank's interpreter leg missed `py` and PowerShell, and matched on the interpreter token alone — which blocked the sanctioned helper's own invocation whenever a task description named an enrolled file. It now requires an inline-code switch.
244
+ - Archiving moved only a task's top line, orphaning its `Desc`/`Boundaries` sub-bullets onto the following task, and removed every line matching the target, collapsing two identical done entries into one.
245
+ - An unreadable `done-tasks.md` was treated as empty, so a transient read failure rewrote the append-only archive from scratch and discarded every record.
246
+
247
+ ## [0.1.43] - 2026-07-30
248
+
249
+ ### Changed
250
+
251
+ - **`_hooklib` sheds activation, completing the #321 partition (slice 4 of 4).**
252
+ The hook core finishes at **557 lines, from 1,263** - a 56% reduction across
253
+ four slices. `_activationlib` now owns which Host the process runs under, where
254
+ the project root is, and whether the arbiter is switched on, together with the
255
+ two process-lifetime caches those answers share.
256
+
257
+ `_HOST` is deliberately **not** re-exported: importing a mutable global binds
258
+ its *value*, so a later `set_host()` would rebind it in the owning module and
259
+ leave a stale copy behind forever. The accessors are re-exported instead, and
260
+ a test proves both modules share one cache in both directions.
261
+
262
+ `_hooklib` re-exports every name with a consumer, so the public surface is
263
+ unchanged and parity rests on 1,185 pre-existing hook tests that did not move.
264
+
265
+ No behaviour change.
266
+
267
+ ## [0.1.42] - 2026-07-30
268
+
269
+ ### Changed
270
+
271
+ - **`_hooklib` sheds its path-scope detection (#321, slice 3 of 4).** The hook
272
+ core drops from 880 to 663 lines - **1,263 before the partition began**, so
273
+ three slices have taken nearly half off the god module. `_scopelib` now owns
274
+ which repo paths are database migrations (H-14), CI/CD workflow files (H-15),
275
+ and deployment / IaC manifests (H-16), plus the security-controls.md reader and
276
+ glob compiler they share.
277
+
278
+ The cleanest seam of the four: this cluster referenced NOTHING from the rest of
279
+ `_hooklib`, and nothing referenced it. Its only dependency was `norm_path`,
280
+ already on the `_pathnorm` floor.
281
+
282
+ `_hooklib` re-exports every moved name - including the private ones, which have
283
+ real consumers - so the public surface is unchanged and parity rests on 1,185
284
+ pre-existing hook tests that did not move.
285
+
286
+ No behaviour change.
287
+
288
+ ## [0.1.41] - 2026-07-30
289
+
290
+ ### Changed
291
+
292
+ - **`_hooklib` sheds its protected-path classifiers (#321, slice 2 of 4).** The
293
+ hook core drops from 1,050 to 880 lines - 1,263 before the partition began.
294
+ `_protectedlib` now owns which repo paths are append-only audit logs (H-05),
295
+ ADR decision files (H-11), the activation manifest, and the gate-marker
296
+ directory. `repo_rel` joined `norm_path` on the `_pathnorm` floor, because it
297
+ references no module symbol and the remaining slices need it too.
298
+
299
+ Measured the same way slice 1 was: one outward reference, zero inward.
300
+ `_hooklib` re-exports every moved name, so all consumers are untouched and
301
+ parity rests on 1,185 pre-existing hook tests that did not move. The public
302
+ surface is preserved exactly - nothing lost, nothing gained.
303
+
304
+ No behaviour change.
305
+
306
+ ## [0.1.40] - 2026-07-30
307
+
308
+ ### Changed
309
+
310
+ - **`_hooklib` sheds its H-09b/H-10b sensitive-scan concern (#321, slice 1 of 4).**
311
+ The 1,263-line hook core drops to 1,051. `_sensitivelib` now owns the crypto and
312
+ secret detectors, the pinned security diff argv, the path-aware diff walk, and
313
+ the digests that bind a recorded gate pass to the lines it reviewed;
314
+ `_pathnorm` holds `norm_path` as the dependency floor beneath every path
315
+ classifier.
316
+
317
+ The seam was measured rather than guessed: the cluster referenced exactly ONE
318
+ symbol from the rest of `_hooklib`, and nothing in the rest of `_hooklib`
319
+ referenced the cluster. `_hooklib` re-exports every moved name, so all 59
320
+ consuming files are untouched and behavioural parity rests on 1,185
321
+ pre-existing hook tests that did not move.
322
+
323
+ No behaviour change.
324
+
325
+ ## [0.1.39] - 2026-07-28
326
+
327
+ ### Changed
328
+
329
+ - Projection of the shared surface change in ca 2.10.2: coverage figures are the
330
+ union across a tree's supported hosts, and `tdd` Phase 5 requires the
331
+ measuring host to be named (#521). `plugins/ca-pi/tools` is platform-forked
332
+ and therefore in scope for the rule; its union job is tracked in #537. No
333
+ Pi-specific behaviour changed.
334
+
335
+ ## [0.1.38] - 2026-07-27
336
+
337
+ ### Fixed
338
+
339
+ - Two holes in the #528 arbitration-log reclassification, both found by
340
+ adversarial review before merge, both leaving the append-only log destructible
341
+ from the shell.
342
+
343
+ The H-11 carve-out was case-insensitive while H-05 - the guard taking over for
344
+ that file - is case-sensitive on both flanks, so a case-varied spelling of the
345
+ path was stripped from one guard's view and invisible to the other. On
346
+ Windows/NTFS and default macOS/APFS that spelling resolves to the real file,
347
+ so a delete under it removed the log with no gate firing.
348
+
349
+ And `New-Item -Force`, which truncates an existing file, was covered by H-11
350
+ but not by H-05, so the log lost that verb on reclassification - a gap the flat
351
+ audit logs shared, now closed for all of them.
352
+
353
+ The carve-out also lacked a right-edge anchor, so the log's path shielded any
354
+ token beginning with it, letting the shell create files under `decisions/`
355
+ that the Write/Edit guard still treats as immutable ADR history.
356
+
357
+ ## [0.1.37] - 2026-07-27
358
+
359
+ ### Fixed
360
+
361
+ - The projected `decision-variance` routine could not record a decision. Its
362
+ Phase 4 is required to append every SMARTS arbitration to
363
+ `.codearbiter/decisions/decision-log.md` "immediately, never batched" - and
364
+ H-11 refused every write, because its path rule matched any `.md` under
365
+ `decisions/` and so governed the arbitration log as immutable ADR history
366
+ requiring the `/adr` authoring marker. Only `decision-lifecycle` arms that
367
+ marker, so any arbitration outside an `/adr` session made a decision it could
368
+ not write down (#528).
369
+
370
+ The log is not an ADR - its own format doc states H-05's rule verbatim
371
+ ("strictly append-only ... to supersede, append a new entry") - so it is now
372
+ governed by H-05: append freely, never rewrite. ADR files beside it keep the
373
+ marker gate unchanged, and the carve-out is exactly one path wide.
374
+
375
+ ## [0.1.36] - 2026-07-27
376
+
377
+ ### Fixed
378
+
379
+ - The coverage gate's no-tooling exemption required no evidence. The projected
380
+ `tdd` Phase 5 and `refactor` Phase 2/6 are BLOCK gates that may be passed when
381
+ a surface has no coverage tooling, but the trigger was a bare self-assertion
382
+ by the agent running the phase - and "I could not find the command" is
383
+ indistinguishable, from the inside, from "this surface has none". The two
384
+ demand opposite responses: the first is a STOP under the routines' own hard
385
+ rule, the second is the exemption. An agent that merely failed to locate the
386
+ command could therefore pass a BLOCK gate by describing its own failure as a
387
+ property of the repo, which is the same shape as #507 - a gate that reads as
388
+ satisfied without ever executing.
389
+
390
+ The exemption now requires the record to quote the `tech-stack.md` Coverage
391
+ section it read and name the surface it found no command for. No citation, no
392
+ exemption: the phase STOPs instead. The conditions live in
393
+ `includes/maturity-coverage.md` alone, with `tdd`, `refactor` and the
394
+ `coverage-auditor` agent deferring to it rather than each restating them.
395
+
396
+ ## [0.1.35] - 2026-07-26
397
+
398
+ ### Fixed
399
+
400
+ - The projected `tdd` and `refactor` routines can actually run their coverage
401
+ gate. Both instructed "run the coverage command from `tech-stack.md`" and both
402
+ forbid guessing one - and no such command existed for any tree, so every run
403
+ reached the phase, found nothing to run, and passed through on a gap. A BLOCK
404
+ gate that cannot execute reads as satisfied in every lane, which is worse than
405
+ no gate at all (#507).
406
+ - The maturity threshold now names its metric: lines and branches, both binding.
407
+ Previously it said only "minimum coverage", and a report gives four numbers
408
+ that disagree - so the same tree was compliant or not depending on which
409
+ column the reader picked.
410
+ - The projected `coverage-auditor` no longer carries its own copy of the
411
+ threshold table. The copies drifted the moment the canonical one gained a
412
+ metric rule, leaving the dispatched auditor applying a one-number test the
413
+ dispatching routine had stopped using. It reads the shared table instead.
414
+
415
+ ## [0.1.34] - 2026-07-26
416
+
417
+ ### Fixed
418
+
419
+ - A background job that could not start its shell now says why. `launch` refuses
420
+ with `undefined` on five paths; four are policy decisions the caller can
421
+ predict, and the fifth is an environment failure it cannot - a spawn that
422
+ threw. That error was discarded by a bare `catch {}`, so a Git Bash launch
423
+ that failed on CI surfaced only as `expected undefined to be defined`, and the
424
+ runtime's designed, fail-closed refusal was indistinguishable from a real
425
+ fault. The spawn path now reports a per-launch diagnostic, and the background
426
+ bash tool surfaces it instead of the generic block message (#504).
427
+ - The refusal detail is drawn from a closed vocabulary - a recognized Windows
428
+ containment reason or an errno shape - never from `error.message`, which
429
+ embeds the resolved shell path and working directory. Following the same
430
+ bounded-reason-code convention already used for the child-process diagnostic
431
+ channel (#428) keeps one convention across both layers rather than widening a
432
+ second channel to free text.
433
+
434
+ ## [0.1.33] - 2026-07-26
435
+
436
+ ### Fixed
437
+
438
+ - The projected release routine names the latest-badge trap: a sibling must pass
439
+ `--latest=false` explicitly, because omitting the flag is not declining it -
440
+ GitHub defaults `make_latest` to true for any non-prerelease. This is the
441
+ correction to `ca-pi-v0.1.32`, which took the repository's "Latest" badge on
442
+ publication and displaced `ca`'s release from it.
443
+
444
+ ## [0.1.32] - 2026-07-26
445
+
446
+ ### Added
447
+
448
+ - The projected review routine accepts an inbound pull request as its argument
449
+ (`#123`, a bare number, or a PR URL) and reviews it through the same fleet and
450
+ the same triage funnel as a local diff. Shipped as an ARGUMENT rather than a
451
+ second command, so the Pi command catalog and skill count are unchanged - a
452
+ `review-pr` skill would have been a new public surface whose only difference
453
+ is where the diff came from (#80).
454
+
455
+ ## [0.1.31] - 2026-07-26
456
+
457
+ ### Added
458
+
459
+ - The projected release routine can target `ca-pi`. It documented `ca` only, so
460
+ the one sanctioned path to a version tag could not read ca-pi's manifest, its
461
+ changelog, or its `ca-pi-v*` namespace - and, notably, could not resolve a
462
+ baseline in a series that had no tag at all. It now reads a Targets row per
463
+ plugin, and ca-pi's row carries the two traps specific to it: Pi installs the
464
+ repository ROOT as the package, so the generated root `package.json` is a
465
+ second manifest that must agree with the plugin's before tagging, and
466
+ `plugins/ca-pi/tools/` is outside the shipped payload while the built bundles
467
+ under `extensions/` are inside it (#382).
468
+
469
+ ## [0.1.30] - 2026-07-26
470
+
471
+ ### Fixed
472
+
473
+ - The shared guard and anti-slop libraries pick up two enforcement papercuts.
474
+ `git commit-graph` is no longer gated as a commit - the H-09b/H-10b matcher
475
+ took every `commit-*` verb, so object-database maintenance was told to run the
476
+ crypto-compliance gate and the only escapes were a pass certifying nothing or
477
+ an override covering a coverage hole (#485). And the prose-separator-dash
478
+ detector now reads a paragraph at a time, so a separator at a soft-wrap
479
+ boundary is reported instead of scoring zero in both directions (#484).
480
+ ## [0.1.29] - 2026-07-26
481
+
482
+ ### Added
483
+
484
+ - ca-pi has a sanctioned release lane, and therefore a way to produce the
485
+ `ca-pi-v*` tag the install instructions have always told users to pin. It had
486
+ none: the hosted release workflow published `ca` and `ca-codex` only, CI
487
+ enforced an independent `ca-pi-v*` version guard the whole time, and no tag in
488
+ the series had ever been cut - so the documented install could not be
489
+ satisfied by anything, and the only way to produce one was to hand-cut a tag
490
+ outside the changelog, tag-state, and read-back guarantees. The lane also
491
+ treats the repository-root `package.json` as a companion manifest that must
492
+ already agree with the plugin's, because Pi installs the ROOT as the package:
493
+ a root disagreeing with the tag would install a version the tag does not name
494
+ (#382).
495
+
496
+ ### Changed
497
+
498
+ - The projected release routine named two independently-versioned plugins
499
+ instead of four, and routes a sibling release to its hosted lane (#382).
500
+ ## [0.1.28] - 2026-07-26
501
+
502
+ ### Added
503
+
504
+ - `$ca-add-dep` gains a bounded **Ephemeral tool run** section: a pinned
505
+ developer tool run once against the repository, adopting nothing, is not a
506
+ project dependency and no longer takes dependency review. The distinguishing
507
+ test is the dependency GRAPH, not the download. Version pinning and the
508
+ approved registry still apply at full strength; a manifest or lockfile change
509
+ is prohibited and verified after the run rather than trusted, because a tool
510
+ that writes one has adopted itself (issue #346, ADR-0023).
511
+
512
+ ## [0.1.27] - 2026-07-26
513
+
514
+ ### Fixed
515
+
516
+ - The extension bundles are rebuilt against the widened outbound redactor. The
517
+ bundles EMBED the shared farm redactor, so #487's widening (GitLab PATs,
518
+ OpenAI project keys, basic auth in a clone URL, bearer tokens) reached
519
+ `farm.js` but not `codearbiter.js` or `codearbiter-child.js` - a Pi install
520
+ would have kept redacting on the narrower pattern set. The parent's baked
521
+ child fingerprint is regenerated with them.
522
+
523
+ ## [0.1.26] - 2026-07-25
524
+
525
+ ### Fixed
526
+
527
+ - The anti-slop dash detector no longer flags a definition-list dash
528
+ (`- **term** - meaning`). The rule it enforces is about SENTENCE separators,
529
+ and the style guides are themselves written in that form, so the detector was
530
+ contradicting the guides it exists to serve. A real separator later on the
531
+ same line is still reported: only the definition dash is dropped, never the
532
+ term before it (issue #338).
533
+
534
+ ### Changed
535
+
536
+ - The detector's document scope now covers authored site prose, and recognises
537
+ `.mdx` as prose rather than keying on `.md` alone.
538
+
539
+ ## [0.1.25] - 2026-07-25
540
+
541
+ ### Fixed
542
+
543
+ - The ca-pi test suite no longer reads the operator's real
544
+ `~/.pi/agent/auth.json`. `security-controls.md` states that tests use
545
+ disposable Pi homes and dummy credentials and never inspect the real auth
546
+ store; the request fixtures spread `process.env`, so roughly 25 tests that did
547
+ not set their own overrides resolved the actual store. The suite now loads a
548
+ setup file that repoints every home variable Node consults - including the
549
+ Windows `HOMEDRIVE`/`HOMEPATH` pair - plus `PI_CODING_AGENT_DIR` at a
550
+ disposable root seeded with an obvious dummy, so the control is true by
551
+ construction rather than per test file (issue #464).
552
+ - The Pi security contract now runs the ca-pi suites FROM the package rather
553
+ than from the repository root. `npm --prefix` moves npm, not vitest, so those
554
+ runs never loaded `plugins/ca-pi/tools/vitest.config.ts` - they executed
555
+ without the package's build-time globals and, latterly, without its setup
556
+ file, which is how a green security row could be reported for a suite running
557
+ against the real home.
558
+
559
+ ## [0.1.24] - 2026-07-25
560
+
561
+ ### Fixed
562
+
563
+ - `/ca-doctor` no longer redacts its own diagnostics because of where the
564
+ repository happens to live. The outbound redactor matches secret-shaped
565
+ content by trigger word, and nearly every doctor line embeds a filesystem
566
+ path - so a repository or worktree named `...-secret-...` had its `package`,
567
+ `core` and `child` lines each replaced by a redaction notice. A path the
568
+ process already knows is a structural field to compare against, not a value to
569
+ guess at, so the project cwd and the ca-pi package root are now exempt from
570
+ value-shaped matching in this one report. The exemption is exact-literal and
571
+ nonce-keyed: a real credential on the same line still redacts that line whole,
572
+ and a hostile report cannot forge the internal placeholder (issue #449).
573
+
574
+ ## [0.1.23] - 2026-07-25
575
+
576
+ ### Fixed
577
+
578
+ - A session started inside a linked worktree no longer repoints the MAIN
579
+ repository's git-level enforcement at a path that dies with that worktree.
580
+ The shared enforcer entry lives in the git common dir, so every worktree
581
+ writes the main repo's copy; the SessionStart self-heal happily pinned it to
582
+ the worktree's own plugin root, and pruning the worktree - which is what
583
+ worktrees are for - left the repo silently ungated. An ephemeral enforcer is
584
+ now refused in both the producer and the caller, leaving the previously
585
+ registered install in place. A stale but durable path is still refreshed, so
586
+ the guard is not a kill-switch (issue #441).
587
+
588
+ ## [0.1.22] - 2026-07-25
589
+
590
+ ### Added
591
+
592
+ - `$ca-cleanup` (`post-merge-cleanup`): the already-merged branch transition,
593
+ which no command owned. It fetches, proves `HEAD` is an ancestor of the
594
+ *fetched* default branch, classifies every dirty and untracked artifact as
595
+ unique, redundant, or superseded, resolves each under its own confirmation,
596
+ fast-forwards with `--ff-only`, and deletes the merged local branch with
597
+ `branch -d`. Anything not provably redundant or superseded counts as unique
598
+ and is never discarded unbidden; the remote branch is never touched
599
+ (issue #308).
600
+
601
+ ### Changed
602
+
603
+ - ORCHESTRATOR §6 routes on understood intent instead of asking the user to
604
+ retype a command it has already named. Unambiguous and non-destructive intent
605
+ routes directly; probable intent asks once, naming the command; genuinely
606
+ unclear intent gets the chooser. Clarity and risk are separate axes, so an
607
+ irreversible or gate-bypassing command still asks even when the intent is
608
+ obvious. The invariant §6 protects is unchanged: the orchestrator routes the
609
+ command and never improvises the operation, and a missing owner is a routing
610
+ gap to surface rather than a reason to reach for `$ca-override` (ADR-0022).
611
+
612
+ ## [0.1.21] - 2026-07-25
613
+
614
+ ### Changed
615
+
616
+ - The bundled `release` routine now documents published-tag immutability: a bad
617
+ release is corrected by publishing a new version, never by moving, retargeting,
618
+ or deleting an existing tag, and every newly published tag records where it
619
+ pointed so repository CI can prove it never moved (issue #386). Payload-only
620
+ change to the generated surface; no adapter behavior changes.
621
+
622
+ ## [0.1.20] - 2026-07-25
623
+
624
+ ### Fixed
625
+
626
+ - A hook payload that is valid JSON but not an object (`[]`, `3`, `"str"`,
627
+ `true`, `null`) is normalized to an empty payload at `read_input()` instead of
628
+ being handed to the guards as a non-dict, where the truthy ones raised
629
+ `AttributeError` out of the guard and the falsy ones were only accidentally
630
+ safe. The envelope is host-produced, not model-produced, so an unreadable
631
+ shape is the same compatibility event as unreadable syntax and takes the same
632
+ documented warn-and-proceed path (ADR-0020).
633
+
634
+ ## [0.1.18] - 2026-07-25
635
+
636
+ ### Added
637
+
638
+ - `/ca-doctor` now reports whether MCP servers are configured for the active
639
+ host, and that file writes performed through an MCP tool
640
+ (`mcp__<server>__<tool>`) are outside codeArbiter's write gate. The Pi host
641
+ claims no MCP configuration sources, so the line degrades to silence on Pi
642
+ rather than reporting another host's configuration as this install's.
643
+
644
+ ## [0.1.17] - 2026-07-25
645
+
646
+ ### Fixed
647
+
648
+ - A governed-file notice now names the ADR by its filename stem
649
+ (`ADR-0014-githook-shim-dropin-fail-closed`) instead of its bare number.
650
+ Two ADRs share the number 0014, so the previous notice named two documents
651
+ at once and the reader could tell neither apart.
652
+ - The `governs` cache carries a schema key, so a payload upgrade rebuilds it
653
+ instead of serving the old numeric identifiers until a decision file changes.
654
+
655
+ ## [0.1.16] - 2026-07-25
656
+
657
+ ### Changed
658
+
659
+ - **Breaking (isolation contract):** the isolated Pi child no longer receives
660
+ the operator's provider credential in any form. The parent binds a per-child
661
+ loopback broker on `127.0.0.1:0` and projects a provider configuration whose
662
+ `baseUrl` names that listener and whose `apiKey` references a per-child
663
+ ephemeral token. The child's Pi makes ordinary provider calls to loopback;
664
+ the parent authenticates the token, attaches the real credential, forwards
665
+ upstream, and streams the response back incrementally. `cat`-ing the child's
666
+ projected configuration now yields a token that dies with the child and is
667
+ worthless off-host, which retires the whole encoding-transform exfiltration
668
+ class rather than one instance of it.
669
+ - The `auth.json` projection is deleted outright, not merely unused, and the
670
+ provider credential environment variables are no longer copied into the
671
+ child. The parent still reads the operator store, for its own upstream call.
672
+ - Providers a bearer-substituting broker cannot serve fail the launch closed
673
+ with the new `isolation-broker` stage identifier: `amazon-bedrock` and
674
+ `google-vertex` (SDK request signing), `github-copilot` and `openai-codex`
675
+ (OAuth refresh inside the child), any `oauth` provider record, and any
676
+ provider with neither an operator `baseUrl` nor a pinned built-in endpoint.
677
+ - **Breaking (broker interface):** the broker's upstream authority now requires
678
+ the parent's sensitive-value predicate. Without it the broker cannot tell
679
+ whether a response is handing the operator's own material back to the child,
680
+ so it refuses the authority rather than guessing.
681
+ - Headers the child sends are now an allow list of what a provider call actually
682
+ needs, not a deny list of hop-by-hop names. Previously every unrecognised
683
+ child header rode verbatim onto a request carrying the operator's real
684
+ credential, and the credential could be substituted under any header name the
685
+ child chose. The destination origin is fixed, but the operator's `baseUrl` is
686
+ frequently a routing gateway, and gateways route on request headers.
687
+ - The upstream response is filtered with the same predicate that already
688
+ suppressed a child echoing operator material through its final message. A
689
+ reflected credential in a response header fails closed; a reflected value in
690
+ the body resets the stream. Clean bytes still stream frame by frame, a
691
+ bounded overlap window catches a value split across two writes, and a
692
+ compressed body is refused rather than relayed unread.
693
+
694
+ ### Fixed
695
+
696
+ - A model-level `baseUrl` in the operator's provider record skipped endpoint
697
+ acceptance entirely whenever a provider-level endpoint had already been
698
+ captured, so a credential-bearing model endpoint could cross unvalidated.
699
+ - Operator-configured provider headers could be duplicated, rather than
700
+ overwritten, by a child sending the same header under a different case.
701
+ - A request target carrying an encoded path separator (`/v1/..%2fadmin`) passed
702
+ the route-prefix test and reached the upstream with its encoding intact:
703
+ WHATWG URL normalises encoded dots but not encoded slashes. Encoded
704
+ separators are now refused outright.
705
+
706
+ ## [0.1.15] - 2026-07-25
707
+
708
+ ### Changed
709
+
710
+ - The shared statusline/footer ledger no longer rewrites itself on every render.
711
+ `ledger_update()` used to load the compatibility snapshot plus every live
712
+ session shard, write the session shard, load the snapshot and every shard a
713
+ second time, then atomically rewrite the whole snapshot - on every refresh,
714
+ whether or not anything had changed. Each write is now gated on the record (or
715
+ the snapshot) actually differing from what is on disk, the duplicate load is
716
+ gone, and the pure-liveness `last_ts` stamp is throttled to one refresh per
717
+ five minutes so a quiet render forces no write at all. The 36-hour session TTL
718
+ contract and the on-disk format are unchanged.
719
+ - `parse_iso()` now has one owner. `_ledgerlib` carried a byte-identical second
720
+ copy of `_fmtlib`'s implementation and re-exports it instead.
721
+
722
+ ## [0.1.14] - 2026-07-25
723
+
724
+ ### Fixed
725
+
726
+ - The Pi security contract asserted the exact CodeQL action SHA, so dependabot
727
+ could never land a codeql-action bump on its own - it cannot edit a test, and
728
+ every upgrade failed there until a human hand-edited the literal. The
729
+ assertion now checks the property that matters: both refs are 40-hex commit
730
+ SHAs, and init and analyze pin the same commit, so a split pair cannot
731
+ silently analyse with a different CodeQL than it initialised.
732
+
733
+ ## [0.1.13] - 2026-07-25
734
+
735
+ ### Fixed
736
+
737
+ - Every Pi audit sink is hardened against link and race redirection. The bridge
738
+ failure audit, the child-dispatch audit, and the confirmed-compaction audit
739
+ each resolved the project's `.codearbiter` governance log from a
740
+ caller-supplied cwd and appended to it directly, which follows file symlinks,
741
+ directory junctions, and hardlinks - so a trusted project could redirect those
742
+ records onto another same-user file and leave the real log without them. All
743
+ five producers now share one primitive that canonicalizes the state directory,
744
+ refuses a linked or escaping one, opens the target no-follow and
745
+ create-exclusive, and re-verifies the opened handle's identity on both sides
746
+ of the append. A failed or hostile sink returns false rather than throwing, so
747
+ no producer's enforcement outcome or fail direction changes.
748
+ - Pi native compaction events are validated before they are narrowed. Both host
749
+ records were laundered through a type assertion, and the before-compact
750
+ handler read `event.signal.aborted` and `event.preparation.tokensBefore`
751
+ before its fail-safe block opened, so a malformed or drifted native record
752
+ rejected the host callback with a raw `TypeError` instead of the fixed
753
+ `Pi native compaction failed safely; run /ca-doctor.` diagnostic. Both events
754
+ are now parsed from `unknown` through exact bounded validators covering the
755
+ abort signal, preparation, entry array, reason enum, booleans, and optional
756
+ strings.
757
+
758
+ ## [0.1.12] - 2026-07-25
759
+
760
+ ### Changed
761
+
762
+ - Pi path containment now has a single owner. Nine Pi modules each carried a
763
+ private copy of the same containment predicate and `bridge.ts` carried a tenth
764
+ platform-parameterised variant, so a containment or platform correction had to
765
+ be applied consistently to every trust-boundary module and a partial update
766
+ could make doctor report a path healthy while runtime enforcement rejected it.
767
+ `path-boundary.ts` now owns the semantics as two explicitly named operations -
768
+ lexical (text only) and canonical (both operands resolved through the
769
+ filesystem) - with an injectable win32/posix flavor so both platforms are
770
+ testable from either host. Every caller keeps the exact semantics it had.
771
+ - The 1,033-line Pi command module is split along its three lifecycle seams.
772
+ Generated alias expansion with package-ownership validation, the background-job
773
+ tool and `/ca-jobs` controller, and the `/ca-plan` controller are now separate
774
+ modules with an acyclic import graph, so a change to one no longer forces
775
+ review and re-verification of the other two. No behaviour changed: every moved
776
+ line is byte-identical and every pre-existing suite passes unmodified.
777
+
778
+ ## [0.1.11] - 2026-07-25
779
+
780
+ ### Added
781
+
782
+ - The final-argument authority promotion STOP named by ADR-0014/ADR-0016 is
783
+ now proven against the INSTALLED Pi candidate rather than an in-memory host
784
+ double. A new live fixture loads codeArbiter plus a deliberately later
785
+ trusted extension through Pi's own loader, runner, and tool wrapper, and
786
+ proves the later extension's argument rewrite is re-judged and blocked
787
+ before the governed mutator runs, that it cannot take ownership of that
788
+ mutator, and that real ownership drift fails closed. It runs in every
789
+ blocking supported-version platform cell.
790
+
791
+ ## [0.1.10] - 2026-07-25
792
+
793
+ ### Changed
794
+
795
+ - The farm plan handoff docs shipped with this host now describe the runtime
796
+ plan contract (`parsePlan`, authoritative over `plan.schema.json`) and the
797
+ split setup phases: `setup` runs once per worktree, `setupEachAttempt` reruns
798
+ per attempt, and `setupInputs` invalidates the once-per-worktree cache.
799
+
800
+ ## [0.1.9] - 2026-07-25
801
+
802
+ ### Fixed
803
+
804
+ - The three live-Pi spawns in the package contract test now carry an explicit
805
+ budget. Each `execFileSync`s a real Node process that imports the installed Pi
806
+ host, and each inherited Vitest's bare 5000 ms default against cold hosted
807
+ Windows process creation - the same flat-wall-clock defect as the Job Object
808
+ admission window, in a file that fix did not reach. Measured 5497 ms and
809
+ failing on `windows-latest`. Test-only.
810
+
811
+ ## [0.1.8] - 2026-07-25
812
+
813
+ ### Fixed
814
+
815
+ - Windows Job Object admission is no longer bounded by one flat 15-second
816
+ wall-clock window. Cold admission pays two independent costs - starting the
817
+ PowerShell host, then the one-time Add-Type compilation of the constant C#
818
+ helper - and covering both with a single window made a loaded hosted runner
819
+ indistinguishable from a hung helper, refusing containment twice in one day
820
+ on `windows-latest`. The budget is now a no-progress budget per observable
821
+ phase (the helper announces its host start before the compile) plus a hard
822
+ 30-second ceiling, so a slow-but-advancing helper is admitted while a silent
823
+ one still fails closed. The refusal now names the phase it stalled in and
824
+ how long it waited, while keeping its machine-readable `ready-timeout`
825
+ reason token intact.
826
+
827
+ ## [0.1.7] - 2026-07-25
828
+
829
+ ### Fixed
830
+
831
+ - An abandoned maintainer session's synthetic `DEV: exit` is now durable: the
832
+ owed audit line is staged on disk before the append is attempted and cleared
833
+ only once both the append and the marker removal are confirmed, so a locked
834
+ or failing `overrides.log` no longer erases the close and leaves an unmatched
835
+ `DEV: enter`. The retry record is bounded, and an overflow that has to discard
836
+ an owed close is itself written to the trail rather than dropped silently.
837
+ - The subagent transcript reader honours one result shape on every path, so a
838
+ subagent-directory race no longer raises out of the statusline, and a
839
+ syntactically valid non-object JSONL record is skipped instead of blanking
840
+ every subagent row.
841
+ - Provenance records are validated before admission and each file is loaded
842
+ inside its own error boundary, so one schema-invalid record no longer aborts
843
+ the directory scan and silently drops every later valid record.
844
+
845
+ ## [0.1.6] - 2026-07-25
846
+
847
+ ### Fixed
848
+
849
+ - The SessionStart statusline self-heal no longer pins a NON-DURABLE plugin
850
+ root into the user's global `~/.claude/settings.json`. A session started
851
+ inside a git worktree resolved the plugin root to that worktree and rewrote
852
+ the global pin there; once the worktree was pruned the statusline rendered
853
+ nothing. A non-durable root is now inert - the existing pin is left exactly
854
+ as it is - while a genuinely stale pin from a real plugin-cache update still
855
+ heals. Explicit `wire-statusline.py install` from such a root refuses loudly
856
+ instead of writing a doomed path.
857
+
858
+ ## [0.1.5] - 2026-07-25
859
+
860
+ ### Security
861
+
862
+ - Isolated Pi children now receive a bounded, selected-provider credential
863
+ projection into a fresh private ephemeral root instead of inheriting the
864
+ operator's Pi home. Only the exact provider record a child needs crosses the
865
+ boundary; no other provider record, session, or package state does.
866
+ Credential material never appears in argv, prompts, results, logs,
867
+ telemetry, or `.codearbiter/`, and is scrubbed on every path including
868
+ failure. Ratified as ADR-0016, superseding the opaque-auth clause of
869
+ ADR-0014. Addresses #372.
870
+ - Isolated Pi children also receive a **credential-blind** projection of the
871
+ selected provider's `models.json` record, so a private agent directory no
872
+ longer strips the operator's endpoint, protocol, and model configuration and
873
+ silently sends their key to Pi's built-in endpoint. Only the exactly-selected
874
+ provider record crosses, and within it only structural/protocol configuration;
875
+ `apiKey` and `headers` cross only as whole-value `$NAME`/`${NAME}` environment
876
+ references, which hold no secret and resolve from the already-allowlisted
877
+ child environment, and a `baseUrl` crosses as an endpoint only. A literal
878
+ `apiKey` or header value, a `!command` value, a credential-bearing `baseUrl`,
879
+ and any key or value shape outside the reviewed Pi provider schema all fail
880
+ the launch closed.
881
+ Ratified as ADR-0017, which amends only ADR-0016's "no Pi configuration"
882
+ clause — it permits **configuration** projection and still forbids
883
+ **credential** projection.
884
+ - A projected `baseUrl` is now accepted **positively** instead of being screened
885
+ only for URL userinfo. Screening userinfo alone closed the rare
886
+ credential-in-endpoint shape and left the common one open: a secret in a query
887
+ string (`?api-key=` on Azure, `?key=` on Google), a fragment, or a path
888
+ segment crossed into the child verbatim. Blocklisting parameter names is an
889
+ unbounded list, so a `baseUrl` now crosses only when it is a parseable
890
+ absolute `http`/`https` URL with no userinfo, **no query and no fragment at
891
+ all**, and a bounded route of short unencoded segments. A provider
892
+ endpoint needs neither query nor fragment — Pi's own Azure provider takes
893
+ `api-version` from `AZURE_OPENAI_API_VERSION` — and an endpoint that does not
894
+ meet the rule fails the launch closed rather than projecting material that
895
+ cannot be shown credential-free. Route segments are case-insensitive: an
896
+ operator's Azure deployment or Cloudflare gateway name routinely carries
897
+ capitals, and refusing them bought nothing — a lowercase-only rule admitted
898
+ `sk-querysecret999` while refusing `GPT4-Prod`. The bound that actually
899
+ refuses key material is the per-segment byte limit.
900
+ - Every endpoint the projection accepts is now also registered in the child's
901
+ sensitive-value set and the projected `models.json` is retained behind a scrub
902
+ handle. A bounded route is not *provably* credential-free, and the two controls
903
+ that assumed otherwise were blind to it: an endpoint echoed back by the child
904
+ was not suppressed in the final assistant message, and on the removal-failure
905
+ cleanup path `auth.json` was truncated while the projected `models.json` was
906
+ left intact on disk. Both now behave identically for both files.
907
+ - Projected value SHAPES, not only key names, are pinned to Pi 0.80.10's
908
+ provider schema (`oauth` only `"radius"`, `authHeader` only a boolean, and so
909
+ on). A record that passed the name allowlist but not the declared type used to
910
+ project and then die mutely inside Pi's own validator instead of producing the
911
+ intended fail-closed refusal.
912
+ - A reserved object key (`__proto__`, `constructor`, `prototype`) is now rejected
913
+ as a projected header name, the one place in the projection that skipped the
914
+ module's own reserved-key rule.
915
+ - The isolated child's private root — which holds the operator's real credential
916
+ in cleartext — is now removed from a `try`/`finally` around the whole launch
917
+ rather than threaded manually through every return. An unexpected throw after a
918
+ successful environment prepare previously escaped the runner and stranded that
919
+ root on disk permanently. No such throw was reachable against Pi 0.80.10; the
920
+ change makes the class unreachable by construction rather than by audit of
921
+ every return path.
922
+
923
+ ### Fixed
924
+
925
+ - The isolated child no longer rebinds `PI_PACKAGE_DIR` beneath its private
926
+ root. That variable names Pi's own read-only shipped-asset directory, not
927
+ operator state, so pointing it at an empty private root made Pi's startup
928
+ theme load fail before its RPC loop existed and killed every isolated child
929
+ at exit 1 with zero provider turns.
930
+
931
+ ### Changed
932
+
933
+ - A credential-isolation or config-projection failure now names its stage
934
+ (`isolation-setup`, `isolation-cleanup`, or `isolation-config`) in the
935
+ degraded diagnostic. All three are fixed identifiers chosen by the runner and
936
+ are never derived from child output, error text, paths, configuration values,
937
+ or credential values.
938
+ - **Operator-visible audit-record format change.** `ChildResult` no longer
939
+ carries `stderrHead`, and the dispatch audit line written to
940
+ `.codearbiter/gate-events.log` no longer carries a `STDERR_HEAD:` field.
941
+ Child stderr is now counted, never sampled, so no child-controlled text
942
+ reaches the audit record; `STDERR_BYTES:` remains. Anything parsing
943
+ `STDERR_HEAD:` out of the audit line must be updated.
944
+
945
+ ## [0.1.4] - 2026-07-24
946
+
947
+ ### Changed
948
+
949
+ - Refreshed the bundled farm surface (`includes/farm.md`, the
950
+ `subagent-driven-development` farm-dispatch reference) for run-scoped farm
951
+ receipts: the run's artifact directory is the authoritative receipt, the
952
+ top-level `.farm/` paths are a non-authoritative latest pointer, exit 3 is
953
+ reserved for a failure of the run-scoped report, and the concurrency caveat
954
+ (`FARM_INTEGRATION_BRANCH`, `FARM_WORKTREE_ROOT`, non-overlapping task ids)
955
+ is now stated where operators read it. Prose-only; no Pi adapter code changed.
956
+
957
+ ## [0.1.3] - 2026-07-24
958
+
959
+ ### Security
960
+
961
+ - Governed mutators now re-read live Pi project trust at final execution. Trust
962
+ that is withdrawn, absent, or throwing retires the ready lifecycle: bash,
963
+ write, edit, and custom mutators fail closed, pending approvals become stale,
964
+ and reads fall back to the untrusted native path until a new affirmatively
965
+ trusted session starts.
966
+
967
+ ### Fixed
968
+
969
+ - Pi bridge failures during a governed tool call now record the same hashed
970
+ correlation as that call's permission-audit row, so a failure joins the tool
971
+ call, permission decision, and result event. Lifecycle and doctor requests
972
+ keep a locally minted correlation. Only a SHA-256 digest is accepted on the
973
+ wire; the raw Pi tool-call id never reaches the request JSON or the audit log.
974
+
975
+ ## [0.1.2] - 2026-07-24
976
+
977
+ ### Fixed
978
+
979
+ - The canonical plan-file bridge tests no longer hardcode a Windows-absolute
980
+ repository root, so they exercise `operatePlanFile` on Linux and macOS instead
981
+ of silently asserting the rejected path. Test-only; `plan-mode.ts` is
982
+ unchanged.
983
+
984
+ ## [0.1.1] - 2026-07-18
985
+
986
+ ### Fixed
987
+
988
+ - Shared prune metrics now distinguish model-visible context savings from
989
+ file-only sidecar cleanup, including explicit strategy scopes and corrected
990
+ footer and cold-cache decisions.
991
+ - Shared prune hooks ignore and repair malformed per-session state rather than
992
+ allowing invalid legacy values to escape fail-open handling.
993
+
994
+ ### Changed
995
+
996
+ - Promote the verified Pi host window through exact Pi 0.80.10.
997
+ - Mark the complete adapter as a Feature Forge `preview`: available and welcomed
998
+ for real use, with broader testing still required before stable status or any
999
+ claim of 100% validation.
1000
+
1001
+
1002
+ ## [0.1.0] - 2026-07-14
1003
+
1004
+ ### Added
1005
+
1006
+ - Initial private, dependency-free Git package metadata and an isolated Node
1007
+ 22.19+ TypeScript build/test boundary. The nested and root package versions
1008
+ are synchronized for `ca-pi-v*` tags; there is no npm release.
1009
+ - Descriptor-generated command skills, routines, role charters, catalogs, and
1010
+ byte-identical stdlib-only Python governance core. The public surface provides
1011
+ 38 `/ca-*` aliases with `/skill:ca-*` fallbacks.
1012
+ - Dormant parent activation gated by the repository marker and affirmative Pi
1013
+ project trust, plus package/command ownership checks and compact status.
1014
+ - Final built-in tool wrappers, bounded Python bridge, read/write notices, Git
1015
+ backstop, and `/ca-doctor` diagnostics for package origin, trust, collisions,
1016
+ supported expansion fingerprints, child integrity, and wrapper health.
1017
+ - Enforcement-only child execution with minimal provider-specific environments,
1018
+ bounded RPC/JSONL, attested startup, exact generated roles, cancellation,
1019
+ timeouts, output limits, and Windows/POSIX process-tree containment.
1020
+ - Single, chain, and parallel role dispatch; Pi-native compaction over the
1021
+ shared prune policy; and Feature Forge `--farm` preview routing to the one
1022
+ checked-in shared backend.
1023
+ - Cross-platform fixtures, relative performance measurements, shared-store
1024
+ attribution tests, and a reproducible Pi 0.80.5/0.80.6 promotion runbook.
1025
+
1026
+ ### Deferred
1027
+
1028
+ - npm packaging is a future spike. A Pi-native embedded farm worker is a future
1029
+ spike that must retain the shared farm contract; neither is a current
1030
+ dependency or release path.