@arbiterforge/ca-pi 0.8.1 → 0.10.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 (46) hide show
  1. package/README.md +29 -90
  2. package/package.json +1 -1
  3. package/plugins/ca-pi/CHANGELOG.md +77 -0
  4. package/plugins/ca-pi/COMMANDS.md +141 -64
  5. package/plugins/ca-pi/SKILLS.md +137 -28
  6. package/plugins/ca-pi/agents/INDEX.md +3 -2
  7. package/plugins/ca-pi/agents/checkpoint-aggregator.md +8 -7
  8. package/plugins/ca-pi/agents/finding-triage.md +31 -14
  9. package/plugins/ca-pi/agents/verdict-aggregator.md +64 -0
  10. package/plugins/ca-pi/arbiter.md +12 -3
  11. package/plugins/ca-pi/extensions/codearbiter.js +86 -1
  12. package/plugins/ca-pi/generated/command-catalog.json +386 -186
  13. package/plugins/ca-pi/generated/roles.json +9 -0
  14. package/plugins/ca-pi/hooks/_bashguardlib.py +18 -11
  15. package/plugins/ca-pi/hooks/_gitexec.py +23 -0
  16. package/plugins/ca-pi/hooks/_githooks.py +50 -23
  17. package/plugins/ca-pi/hooks/_hooklib.py +94 -7
  18. package/plugins/ca-pi/hooks/_host.py +9 -1
  19. package/plugins/ca-pi/hooks/_modelib.py +173 -55
  20. package/plugins/ca-pi/hooks/_protectedlib.py +13 -4
  21. package/plugins/ca-pi/hooks/_releaselib.py +278 -48
  22. package/plugins/ca-pi/hooks/_updatelib.py +230 -50
  23. package/plugins/ca-pi/hooks/doctor.py +56 -8
  24. package/plugins/ca-pi/hooks/git-enforce.py +10 -3
  25. package/plugins/ca-pi/hooks/hostapi.py +220 -22
  26. package/plugins/ca-pi/hooks/session-start.py +8 -6
  27. package/plugins/ca-pi/hooks/statusline.py +1 -1
  28. package/plugins/ca-pi/hooks/wire-statusline.py +13 -8
  29. package/plugins/ca-pi/includes/command-compatibility.md +16 -0
  30. package/plugins/ca-pi/includes/routing-table.md +13 -5
  31. package/plugins/ca-pi/routines/INDEX.md +1 -1
  32. package/plugins/ca-pi/routines/decision-lifecycle/SKILL.md +54 -2
  33. package/plugins/ca-pi/routines/decision-lifecycle/references/adr-template.md +9 -1
  34. package/plugins/ca-pi/routines/dispatching-parallel-agents/SKILL.md +4 -4
  35. package/plugins/ca-pi/routines/release/SKILL.md +1 -1
  36. package/plugins/ca-pi/skills/ca-checkpoint/SKILL.md +5 -4
  37. package/plugins/ca-pi/skills/ca-cleanup/SKILL.md +6 -0
  38. package/plugins/ca-pi/skills/ca-context-check/SKILL.md +6 -0
  39. package/plugins/ca-pi/skills/ca-create-context/SKILL.md +6 -0
  40. package/plugins/ca-pi/skills/ca-decompose/SKILL.md +6 -0
  41. package/plugins/ca-pi/skills/ca-doctor/SKILL.md +4 -0
  42. package/plugins/ca-pi/skills/ca-init/SKILL.md +18 -1
  43. package/plugins/ca-pi/skills/ca-pr/SKILL.md +17 -1
  44. package/plugins/ca-pi/skills/ca-review/SKILL.md +3 -4
  45. package/plugins/ca-pi/skills/ca-status/SKILL.md +13 -1
  46. package/plugins/ca-pi/skills/ca-watch/SKILL.md +6 -0
@@ -4,42 +4,151 @@ Generated by tools/build-surface.py — edit core/surface/, never this file.
4
4
  Each entry skill wraps one governance command; a body loads only when its
5
5
  skill is invoked — never bulk-read this directory.
6
6
 
7
+ ## Installed surface
8
+
9
+ | Visibility | Count |
10
+ |---|---:|
11
+ | Core | 18 |
12
+ | Advanced | 12 |
13
+ | Canonical total | 30 |
14
+ | Compatibility aliases | 5 |
15
+ | Internal | 1 |
16
+ | Deprecated | 1 |
17
+ | **Total** | **37** |
18
+
19
+ ## Core
20
+
21
+ ### Evaluate
22
+
23
+ | Skill | Purpose |
24
+ |---|---|
25
+ | `/ca-preview` | Zero-onboarding, read-only dry-run of the reviewer fleet against the current uncommitted diff. Predicts reviewers, runs the state-free secret scan, writes nothing. |
26
+
27
+ ### Initialize
28
+
29
+ | Skill | Purpose |
30
+ |---|---|
31
+ | `/ca-init` | Opt this repo into codeArbiter — scaffold the root-level .codearbiter/ state store. |
32
+
33
+ ### Change
34
+
7
35
  | Skill | Purpose |
8
36
  |---|---|
9
37
  | `/ca-add-dep` | Vet a new or changed third-party dependency for license, provenance, and supply-chain risk before any install runs. |
10
- | `/ca-adr` | Author a numbered, dated, user-attributed Architecture Decision Record under .codearbiter/decisions/. |
11
- | `/ca-adr-status` | Report the health of Architecture Decision Records — aged, unchallenged, supersession candidates, unresolved CONFIRM-NN. Read-only. |
12
- | `/ca-audit` | Assemble the governance record for a range — commits, overrides, ADRs, sprint auto-decisions, open questions, checkpoint findings — into one dated audit packet. Read-only. |
13
- | `/ca-btw` | Lightweight Q&A about the project — answer from context and return, no routing, no state change. |
14
- | `/ca-checkpoint` | Periodic multi-reviewer sweep of the whole codebase — surfaces a triaged checkpoint report. |
15
38
  | `/ca-chore` | Sanctioned lane for non-behavioral work — docs-only edits, dependency bumps, reverts. Type-scaled gates; no TDD demanded of prose. |
16
- | `/ca-cleanup` | Finish an already-merged branch classify the leftover artifacts, return to a fast-forwarded default checkout, and delete the merged local branch. Every discard confirmed per item; containment proven, never assumed. |
17
- | `/ca-commands` | Show the codeArbiter command catalog the public command list and what each routes to. |
18
- | `/ca-commit` | Run the full commit gate — the only sanctioned path to a git commit. |
19
- | `/ca-conflict` | Stop everything and surface a rule conflict — persona vs. docs vs. code. Present both sides and the conflict-hierarchy level; the user resolves. No silent reconciliation. |
20
- | `/ca-context-check` | Optional manual drift audit — report stale provenance-tracked docs, then per stale doc offer re-scout, re-baseline, or defer. Not the daily loop; commit-gate auto-heal owns routine maintenance. |
21
- | `/ca-create-context` | Brownfield back-fill — scout an existing codebase and populate .codearbiter/, then lock it initialized. |
22
- | `/ca-debug` | Investigate-then-decide root-cause analysis for a defect whose cause is unknown. No code changes — exits to /ca-fix, /ca-adr, or a no-action close. |
23
- | `/ca-decompose` | Greenfield decomposition interview — a layered interview that populates .codearbiter/ and locks it initialized. |
24
- | `/ca-doctor` | Verify the active host install, package, command ownership, enforcement, wrapper self-test, and active-dispatch coverage gap. Read-only. |
25
- | `/ca-feature` | "Start a feature: brainstorm a spec, get it approved, then drive it test-first through the pipeline. The one entry to implementation." |
26
- | `/ca-fix` | "Fix a confirmed bug: a failing regression test first, then a minimal fix, then the rest of the tdd gates." |
27
- | `/ca-init` | Opt this repo into codeArbiter — scaffold the root-level .codearbiter/ state store. |
28
- | `/ca-metrics` | Read-only 3-metric governance glance — override rate, small-lane rate, sprint low-confidence ratio — each with a trend arrow vs. the prior 20-commit window. |
29
- | `/ca-new-skill` | "Author a new codeArbiter skill: prove the gap is real, get the spec approved, then write it." |
30
- | `/ca-override` | Sanctioned, logged bypass of a gate or hard rule — one audit line, then proceed. |
31
- | `/ca-pr` | Open a pull request the only sanctioned way — clear every BLOCK-level review finding, then stage the PR. Never a direct write to the default branch. |
32
- | `/ca-preview` | Zero-onboarding, read-only dry-run of the reviewer fleet against the current uncommitted diff. Predicts reviewers, runs the state-free secret scan, writes nothing. |
33
- | `/ca-prune` | Trim transcript clutter to extend session lifetime — analyze, prune a copy, or toggle the after-each-turn service. Dry-run by default; gains land at resume/compaction, not the current turn. |
34
- | `/ca-reconcile` | SMARTS arbitration — reconcile architectural artifacts against the scaffold and prior decisions; every variance resolved by an explicit, user-attributed choice. |
39
+ | `/ca-feature` | Start a feature: brainstorm a spec, get it approved, then drive it test-first through the pipeline. The one entry to implementation. |
40
+ | `/ca-fix` | Fix a confirmed bug: a failing regression test first, then a minimal fix, then the rest of the tdd gates. |
35
41
  | `/ca-refactor` | Restructure code with behavioral parity proven through unmodified pre-existing tests, then refactor. No behavior change. |
36
- | `/ca-release` | Cut a release the only sanctioned way — SemVer bump from the commit log, a CHANGELOG section, an annotated tag. Takes the declared target's name as its only argument, or --dry-run to preview one with no write. The only path to a version tag. |
37
- | `/ca-review` | Review a diff with the reviewer fleet, funneled to one triaged verdict. Targets the current working diff, a path, or an inbound GitHub PR. |
38
42
  | `/ca-spike` | Exploratory spike on a throwaway branch — answer a named question with disposable code. Never merges; exits to a findings note or /ca-feature. |
39
43
  | `/ca-sprint` | Autonomous sprint — one interactive spec gate, then plan-to-PR execution with every auto-decision SMARTS-scored and logged. Hard gates remain true stops. |
40
- | `/ca-standup` | Daily repo hygiene — review the day's repo state, then perform the cleanups under per-action confirmation. Fast-forward only, never destructive without a yes. |
44
+
45
+ ### Review
46
+
47
+ | Skill | Purpose |
48
+ |---|---|
49
+ | `/ca-review` | Review a diff with the reviewer fleet, funneled to one triaged verdict. Targets the current working diff, a path, or an inbound GitHub PR. |
50
+
51
+ ### Decide
52
+
53
+ | Skill | Purpose |
54
+ |---|---|
55
+ | `/ca-adr` | Author a numbered, dated, user-attributed Architecture Decision Record under .codearbiter/decisions/. |
56
+
57
+ ### Ship
58
+
59
+ | Skill | Purpose |
60
+ |---|---|
61
+ | `/ca-commit` | Run the full commit gate — the only sanctioned path to a git commit. |
62
+ | `/ca-pr` | Open a pull request the only sanctioned way — clear every BLOCK-level review finding, then stage the PR. Never a direct write to the default branch. |
63
+ | `/ca-release` | Cut a release the only sanctioned way — SemVer bump from the commit log, a CHANGELOG section, an annotated tag. Takes the declared target's name as its only argument, or --dry-run to preview one with no write. The only path to a version tag. |
64
+
65
+ ### Operate
66
+
67
+ | Skill | Purpose |
68
+ |---|---|
69
+ | `/ca-doctor` | Verify the active host install, package, command ownership, enforcement, wrapper self-test, and active-dispatch coverage gap. Read-only. |
70
+ | `/ca-override` | Sanctioned, logged bypass of a gate or hard rule — one audit line, then proceed. |
41
71
  | `/ca-status` | Show the project's current state at a glance — stage, open tasks, open questions, overrides since the last checkpoint, current branch. Read-only. |
42
72
  | `/ca-task` | The sanctioned task-board mutator — add a queued task, start one (flips to in-progress and stamps the date, minting a dotted ID on pick-up), or mark an in-progress task done. The only blessed write to open-tasks.md. |
73
+
74
+ ## Advanced
75
+
76
+ ### Change
77
+
78
+ | Skill | Purpose |
79
+ |---|---|
80
+ | `/ca-debug` | Investigate-then-decide root-cause analysis for a defect whose cause is unknown. No code changes — exits to /ca-fix, /ca-adr, or a no-action close. |
81
+
82
+ ### Review
83
+
84
+ | Skill | Purpose |
85
+ |---|---|
86
+ | `/ca-checkpoint` | Periodic multi-reviewer sweep of the whole codebase — surfaces a triaged checkpoint report. |
43
87
  | `/ca-threat-model` | Opt-in lightweight STRIDE pass for a sensitive feature before implementation. Not a routine gate — invoke it when a change warrants security thought. |
44
88
  | `/ca-tribunal` | Deep, rarely-convened whole-codebase audit — eleven specialist lenses, a resumable on-disk audit log, findings filed as GitHub issues on approval. Expensive; estimates cost and STOPs before running. Never a required gate. |
45
- | `/ca-watch` | Watch a PR's CI to completion — diagnose on red, notify and offer the merge on green. Never auto-merges. |
89
+
90
+ ### Decide
91
+
92
+ | Skill | Purpose |
93
+ |---|---|
94
+ | `/ca-adr-status` | Report the health of Architecture Decision Records — aged, unchallenged, supersession candidates, unresolved CONFIRM-NN. Read-only. |
95
+ | `/ca-reconcile` | SMARTS arbitration — reconcile architectural artifacts against the scaffold and prior decisions; every variance resolved by an explicit, user-attributed choice. |
96
+
97
+ ### Operate
98
+
99
+ | Skill | Purpose |
100
+ |---|---|
101
+ | `/ca-audit` | Assemble the governance record for a range — commits, overrides, ADRs, sprint auto-decisions, open questions, checkpoint findings — into one dated audit packet. Read-only. |
102
+ | `/ca-metrics` | Read-only 3-metric governance glance — override rate, small-lane rate, sprint low-confidence ratio — each with a trend arrow vs. the prior 20-commit window. |
103
+ | `/ca-prune` | Trim transcript clutter to extend session lifetime — analyze, prune a copy, or toggle the after-each-turn service. Dry-run by default; gains land at resume/compaction, not the current turn. |
104
+ | `/ca-standup` | Daily repo hygiene — review the day's repo state, then perform the cleanups under per-action confirmation. Fast-forward only, never destructive without a yes. |
105
+
106
+ ### Extend
107
+
108
+ | Skill | Purpose |
109
+ |---|---|
110
+ | `/ca-new-skill` | Author a new codeArbiter skill: prove the gap is real, get the spec approved, then write it. |
111
+
112
+ ### Help
113
+
114
+ | Skill | Purpose |
115
+ |---|---|
116
+ | `/ca-commands` | Show the codeArbiter command catalog — the public command list and what each routes to. |
117
+
118
+ ## Compatibility aliases
119
+
120
+ ### Initialize
121
+
122
+ | Skill | Purpose | Replacement |
123
+ |---|---|---|
124
+ | `/ca-create-context` | Brownfield back-fill — scout an existing codebase and populate .codearbiter/, then lock it initialized. | `/ca-init --brownfield` |
125
+ | `/ca-decompose` | Greenfield decomposition interview — a layered interview that populates .codearbiter/ and locks it initialized. | `/ca-init --greenfield` |
126
+
127
+ ### Ship
128
+
129
+ | Skill | Purpose | Replacement |
130
+ |---|---|---|
131
+ | `/ca-cleanup` | Finish an already-merged branch — classify the leftover artifacts, return to a fast-forwarded default checkout, and delete the merged local branch. Every discard confirmed per item; containment proven, never assumed. | `/ca-pr --cleanup` |
132
+ | `/ca-watch` | Watch a PR's CI to completion — diagnose on red, notify and offer the merge on green. Never auto-merges. | `/ca-pr --watch` |
133
+
134
+ ### Operate
135
+
136
+ | Skill | Purpose | Replacement |
137
+ |---|---|---|
138
+ | `/ca-context-check` | Optional manual drift audit — report stale provenance-tracked docs, then per stale doc offer re-scout, re-baseline, or defer. Not the daily loop; commit-gate auto-heal owns routine maintenance. | `/ca-status drift` |
139
+
140
+ ## Internal
141
+
142
+ ### Decide
143
+
144
+ | Skill | Purpose |
145
+ |---|---|
146
+ | `/ca-conflict` | Stop everything and surface a rule conflict — persona vs. docs vs. code. Present both sides and the conflict-hierarchy level; the user resolves. No silent reconciliation. |
147
+
148
+ ## Deprecated
149
+
150
+ ### Help
151
+
152
+ | Skill | Purpose | Replacement |
153
+ |---|---|---|
154
+ | `/ca-btw` | Lightweight Q&A about the project — answer from context and return, no routing, no state change. | ask the question directly |
@@ -14,8 +14,9 @@ An agent is a reviewer or author **dispatched** by a skill — never routed to,
14
14
  | [migration-reviewer](migration-reviewer.md) | on a DB migration file add/modify | Reviews migration safety, data-classification tagging, immutability. | missing classification annotation, irreversible destructive op |
15
15
  | [coverage-auditor](coverage-auditor.md) | `tdd` (Phase 4) | Audits test coverage vs. TDD obligations; flags untested source and logical gaps. | untested source files, coverage below the maturity threshold |
16
16
  | [architecture-drift-reviewer](architecture-drift-reviewer.md) | `/checkpoint` sweep | Read-only; surfaces drift between the codebase and accepted ADRs in `.codearbiter/decisions/`. | — (informational, never blocks) |
17
- | [finding-triage](finding-triage.md) | `/checkpoint` sweep (sequential) | Consolidates reviewer reports; classifies each finding by severity and whether it blocks the current change. | — (post-processor) |
18
- | [checkpoint-aggregator](checkpoint-aggregator.md) | `/checkpoint` sweep (terminal) | Composes triage + challenger output into a dated `.codearbiter/checkpoints/` doc. | — (aggregator) |
17
+ | [finding-triage](finding-triage.md) | `dispatching-parallel-agents` for review, checkpoint, sprint, and generic parallel batches (sequential) | Consolidates reviewer reports and terminal states; classifies each finding by severity and whether it blocks the current change. | — (post-processor) |
18
+ | [verdict-aggregator](verdict-aggregator.md) | review and generic parallel batches (terminal) | Composes the complete triage report into one structured in-memory verdict. Read-only. | — (aggregator) |
19
+ | [checkpoint-aggregator](checkpoint-aggregator.md) | `/checkpoint` after the read-only verdict | Persists the verdict as a dated, non-overwriting `.codearbiter/checkpoints/` doc. | — (aggregator) |
19
20
  | [decision-challenger](decision-challenger.md) | `decision-variance` (optional) | Adversarial red-team of ADRs; confidence 1–5; surfaces disproving evidence. Read-only. | — (surfaces, does not block) |
20
21
  | [scout](scout.md) | `decision-variance`, `context-creation` (INTERNAL) | Scans an assigned code scope, reports decision evidence — paths + line numbers only, no excerpts. Never dispatch directly. | — (internal) |
21
22
  | [grader](grader.md) | `decision-variance` (INTERNAL) | Produces a SMARTS analysis + strength-labeled recommendation for one variance. Never decides. Never dispatch directly. | — (internal) |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: checkpoint-aggregator
3
- description: Composes the finding-triage report and decision-challenger output into a dated checkpoint document under .codearbiter/checkpoints/YYYY-MM-DD.md. Aggregator, not a blocker.
3
+ description: Persists a complete verdict-aggregator output under the selected dated checkpoint filename in .codearbiter/checkpoints/. Writer, not a blocker.
4
4
  tools: Read, Glob, Bash, Write
5
5
  classification: reviewer
6
6
  pi-skills: []
@@ -9,12 +9,12 @@ model: haiku
9
9
 
10
10
  # Checkpoint Aggregator Agent
11
11
 
12
- Final agent in the checkpoint pipeline. Read the finding-triage report, ensure the checkpoints directory exists, and write the dated checkpoint document. Composes; does not block. Runs after `finding-triage` completes.
12
+ Explicit writer in the checkpoint pipeline. Consume the verdict-aggregator output, ensure the checkpoints directory exists, and write the dated checkpoint document. Persists; does not block. Runs only after `verdict-aggregator` returns.
13
13
 
14
14
  ## Required Reading
15
15
 
16
16
  1. `<project-root>/.codearbiter/CONTEXT.md` — the `stage:` value.
17
- 2. The finding-triage report from the current checkpoint run.
17
+ 2. The complete verdict-aggregator output from the current checkpoint run.
18
18
  3. `<project-root>/.codearbiter/checkpoints/` — existing checkpoint documents (to avoid a duplicate).
19
19
 
20
20
  ## Process
@@ -25,15 +25,15 @@ Check `<project-root>/.codearbiter/checkpoints/`. Create it if missing. The chec
25
25
 
26
26
  ### Step 2 — Determine the checkpoint date
27
27
 
28
- Use the current date (YYYY-MM-DD). If a document for today exists, append a suffix: `YYYY-MM-DD-2.md`, `YYYY-MM-DD-3.md`. Never overwrite.
28
+ Use the current date (YYYY-MM-DD). If a document for today exists, append a suffix: `YYYY-MM-DD-2.md`, `YYYY-MM-DD-3.md`. Record the selected dated checkpoint filename, including any numeric suffix. Never overwrite.
29
29
 
30
30
  ### Step 3 — Write the checkpoint document
31
31
 
32
- Write `<project-root>/.codearbiter/checkpoints/YYYY-MM-DD.md` with the structure below.
32
+ Write the document with the structure below to the exact selected path under `<project-root>/.codearbiter/checkpoints/`.
33
33
 
34
34
  ### Step 4 — Report the path
35
35
 
36
- Report: "Checkpoint document written to `<project-root>/.codearbiter/checkpoints/YYYY-MM-DD.md`."
36
+ Report the exact path written in Step 3, including any numeric suffix: "Checkpoint document written to `<selected-path>`."
37
37
 
38
38
  ### Step 5 — Surface DEFERRABLE findings for harvest
39
39
 
@@ -107,5 +107,6 @@ One `###` section per dispatched reviewer. Typical sections:
107
107
  ## Hard Rules
108
108
 
109
109
  - MUST NOT overwrite an existing checkpoint document.
110
- - Every finding from the triage report MUST appear in the checkpoint document. Omit nothing.
110
+ - Every finding and incomplete-unit result from the verdict-aggregator output MUST appear in the checkpoint document. Omit nothing.
111
+ - MUST NOT consume raw reviewer output or the finding-triage report directly.
111
112
  - The `<project-root>/.codearbiter/checkpoints/` directory MUST be created if missing. Do not fail silently.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: finding-triage
3
- description: Post-processes all checkpoint reviewer reports — consolidates findings, classifies each by severity and whether it blocks the current change. Sequential. Produces a unified triage report for the checkpoint-aggregator. Reads project state from .codearbiter/.
3
+ description: Post-processes reviewer reports — consolidates findings, classifies each by severity and whether it blocks the current change. Sequential. Produces a unified read-only triage report for the verdict-aggregator and explicit checkpoint persistence.
4
4
  tools: Read, Grep, Glob
5
5
  classification: reviewer
6
6
  pi-skills: []
@@ -9,12 +9,13 @@ model: haiku
9
9
 
10
10
  # Finding Triage Agent
11
11
 
12
- Runs after all checkpoint reviewer agents complete. Read every reviewer report, consolidate findings, and classify each one. Does not produce its own findings — classifies and unifies what the reviewers found. Runs sequentially; every reviewer report MUST be available before beginning.
12
+ Runs after every unit in a batch reaches a terminal state. Read every reviewer report and the complete batch contract, consolidate findings, and classify each one. Does not produce its own reviewer findings — classifies and unifies what the reviewers found, while representing every `ERRORED` or `DEFERRED` unit as an incomplete-result finding. Runs sequentially; the entire batch MUST be available before beginning.
13
13
 
14
14
  ## Required Reading
15
15
 
16
16
  1. `<project-root>/.codearbiter/CONTEXT.md` — the `stage:` value (1–4 maturity / rigor knob).
17
- 2. Every reviewer report from the current checkpoint run.
17
+ 2. Every reviewer report from the current batch.
18
+ 3. The batch completion contract, including the target kind and every unit's terminal state. Every `ERRORED` and `DEFERRED` unit MUST be present.
18
19
 
19
20
  ## Process
20
21
 
@@ -25,6 +26,10 @@ Read each reviewer report. Collect every finding. For each, record:
25
26
  - Severity (CRITICAL / HIGH / MEDIUM / LOW / CONFIDENCE-RATING)
26
27
  - Description
27
28
  - File and line (if applicable)
29
+ - Remediation (or the next action for an incomplete-result finding)
30
+ - Applicable control (or `n/a` when no control applies)
31
+
32
+ Record an explicit no-finding result for each successful unit with no reviewer findings. Represent each `ERRORED` or `DEFERRED` unit as one `INCOMPLETE_RESULT` finding so the downstream verdict can account for the entire batch.
28
33
 
29
34
  ### Step 2 — Classify each finding
30
35
 
@@ -44,9 +49,13 @@ Assign every finding a severity and a disposition:
44
49
  - The finding is a decision-challenger UPHOLD (confidence 4–5).
45
50
  - The finding is an observation above threshold, not a gap.
46
51
 
52
+ **`INCOMPLETE_RESULT`** — the unit did not produce a complete review result. Assign only when:
53
+ - The batch contract records the unit as `ERRORED` or `DEFERRED`.
54
+ - A required unit result or evidence receipt is absent.
55
+
47
56
  ### Step 3 — Produce the unified triage report
48
57
 
49
- List every finding with source, severity, description, and disposition.
58
+ List every finding with source, severity, location, description, disposition, remediation, and applicable control. Include the explicit no-finding result for every successful unit with no findings.
50
59
 
51
60
  ## Output Format
52
61
 
@@ -55,32 +64,40 @@ List every finding with source, severity, description, and disposition.
55
64
 
56
65
  ### BLOCKS — must resolve before this change lands
57
66
 
58
- | Source | Severity | Finding | Disposition |
59
- |--------|----------|---------|-------------|
60
- | <reviewer> | CRITICAL/HIGH | <description> | BLOCKS |
67
+ | Source | Severity | Location | Finding | Disposition | Remediation | Applicable control |
68
+ |--------|----------|----------|---------|-------------|-------------|--------------------|
69
+ | <reviewer> | CRITICAL/HIGH | <file:line or n/a> | <description> | BLOCKS | <next action> | <control or n/a> |
61
70
 
62
71
  ### DEFERRABLE — real, safe to follow up
63
72
 
64
- | Source | Severity | Finding | Disposition |
65
- |--------|----------|---------|-------------|
66
- | <reviewer> | MEDIUM | <description> | DEFERRABLE |
73
+ | Source | Severity | Location | Finding | Disposition | Remediation | Applicable control |
74
+ |--------|----------|----------|---------|-------------|-------------|--------------------|
75
+ | <reviewer> | MEDIUM | <file:line or n/a> | <description> | DEFERRABLE | <next action> | <control or n/a> |
67
76
 
68
77
  ### NON_BLOCKING — informational
69
78
 
70
- | Source | Severity | Finding | Disposition |
71
- |--------|----------|---------|-------------|
72
- | <reviewer> | LOW | <description> | NON_BLOCKING |
79
+ | Source | Severity | Location | Finding | Disposition | Remediation | Applicable control |
80
+ |--------|----------|----------|---------|-------------|-------------|--------------------|
81
+ | <reviewer> | LOW | <file:line or n/a> | <description> | NON_BLOCKING | <next action or none> | <control or n/a> |
82
+
83
+ ### INCOMPLETE_RESULT — batch result is incomplete
84
+
85
+ | Source | Severity | Location | Finding | Disposition | Remediation | Applicable control |
86
+ |--------|----------|----------|---------|-------------|-------------|--------------------|
87
+ | <unit> | n/a | n/a | <ERRORED, DEFERRED, or missing result> | INCOMPLETE_RESULT | <retry or resolve> | n/a |
73
88
 
74
89
  ### Summary counts
75
90
  - Total findings: N
76
91
  - BLOCKS: N
77
92
  - DEFERRABLE: N
78
93
  - NON_BLOCKING: N
94
+ - INCOMPLETE_RESULT: N
79
95
  ```
80
96
 
81
97
  ## Constraints
82
98
 
83
99
  - Generate no new findings. Classify only.
84
- - Modify no file. The checkpoint-aggregator writes the checkpoint document.
100
+ - Modify no file. The verdict-aggregator consumes this report in memory; only an explicit checkpoint workflow may separately persist it through checkpoint-aggregator.
85
101
  - Skip nothing. Every finding from every reviewer appears in the triage report.
102
+ - Preserve the batch accounting. Every dispatched unit appears as a finding source, an incomplete-result finding, or an explicit no-finding result.
86
103
  - Do not block on your own authority. You classify; downstream acts.
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: verdict-aggregator
3
+ description: Composes a complete finding-triage report into one structured in-memory verdict for the caller. Read-only; never persists a checkpoint or modifies project state.
4
+ tools: Read, Grep, Glob
5
+ classification: reviewer
6
+ pi-skills: []
7
+ model: haiku
8
+ ---
9
+
10
+ # Verdict Aggregator Agent
11
+
12
+ Terminal read-only agent for review and generic parallel batches. Consume the complete finding-triage report and return one structured verdict to the caller. Do not reread raw reviewer output, invent findings, or persist the result.
13
+
14
+ ## Required Input
15
+
16
+ 1. The complete finding-triage report for the current batch.
17
+ 2. The batch completion contract, including the target kind and every unit's terminal state.
18
+
19
+ ## Process
20
+
21
+ ### Step 1 — Verify input completeness
22
+
23
+ Confirm every dispatched unit appears in the triage report as a finding source or an explicit no-finding result. Every `ERRORED` or `DEFERRED` unit must appear as an incomplete-result finding. If any unit is absent, return `INCOMPLETE`; never infer its result.
24
+
25
+ ### Step 2 — Compose one verdict
26
+
27
+ Return exactly one status. INCOMPLETE takes precedence over BLOCKING_FINDINGS; blocking findings remain in the output even when incomplete input determines the status.
28
+
29
+ - `PASS` — no `BLOCKS` finding and no incomplete unit.
30
+ - `INCOMPLETE` — any expected unit, evidence receipt, or terminal result is missing or errored.
31
+ - `BLOCKING_FINDINGS` — one or more `BLOCKS` findings are present and the batch is otherwise complete.
32
+
33
+ Preserve every triaged finding exactly once. Include source, severity, file and line when present, disposition, remediation, and the applicable control supplied by triage.
34
+
35
+ ## Output Format
36
+
37
+ ```markdown
38
+ ## Review verdict — <target>
39
+
40
+ **Status:** PASS | BLOCKING_FINDINGS | INCOMPLETE
41
+
42
+ | Disposition | Count |
43
+ |---|---:|
44
+ | BLOCKS | N |
45
+ | DEFERRABLE | N |
46
+ | NON_BLOCKING | N |
47
+ | INCOMPLETE_RESULT findings | N |
48
+
49
+ ### Findings
50
+
51
+ | Source | Severity | Location | Disposition | Finding | Remediation / control |
52
+ |---|---|---|---|---|---|
53
+ | <reviewer or unit> | <severity> | <file:line or n/a> | <disposition> | <finding> | <next action or control> |
54
+ ```
55
+
56
+ Each `ERRORED`, `DEFERRED`, or missing unit is represented with disposition `INCOMPLETE_RESULT`; the `INCOMPLETE_RESULT findings` count equals the number of those rows.
57
+
58
+ ## Hard Rules
59
+
60
+ - Modify no file. Return the verdict in the agent result only.
61
+ - MUST NOT create or update `.codearbiter/checkpoints/` or any other repository path.
62
+ - MUST NOT omit, downgrade, or reinterpret a finding from the triage report.
63
+ - MUST NOT consume raw reviewer output; the complete finding-triage report is the only finding input.
64
+ - MUST return `INCOMPLETE` when a unit or required receipt is missing instead of manufacturing a pass.
@@ -119,9 +119,18 @@ exists for a genuinely incomplete reading, and for the destructive set below —
119
119
 
120
120
  **Clarity and risk are separate axes.** Tier 1 requires BOTH unambiguous intent AND a non-destructive
121
121
  command. Anything irreversible or gate-bypassing drops to tier 2 and asks, even when the intent is
122
- obvious — there the confirmation *is* the gate, not friction. That set (safety-core's §6): `/ca-override`,
123
- merge to the default branch, branch or worktree deletion, and release and tag publication. A
124
- deterministic mode-token flip (`mode --dangerous`, `mode --ops`) is friction, not a gate, so it is
122
+ obvious — there the confirmation *is* the gate, not friction. The routing table owns the authoritative
123
+ registry; this resident copy is compared item-for-item in CI because classification precedes
124
+ that file load:
125
+
126
+ ### Destructive operations (tier-2 regardless of cue)
127
+
128
+ - Logged bypass (`/override`)
129
+ - Merge to the default branch
130
+ - Branch or worktree deletion
131
+ - Release and tag publication
132
+
133
+ A deterministic mode-token flip (`mode --dangerous`, `mode --ops`) is friction, not a gate, so it is
125
134
  not in this set — ADR-0030 supersedes ADR-0022's tier-2 confirmation clause for dangerous-mode entry
126
135
  alone; the other four members are unchanged.
127
136
 
@@ -9722,6 +9722,88 @@ async function appendPiCompactionAudit(record2) {
9722
9722
  }
9723
9723
 
9724
9724
  // src/extension.ts
9725
+ var COMMAND_VISIBILITY_ORDER = ["core", "advanced", "alias", "internal", "deprecated"];
9726
+ var COMMAND_WORKFLOW_ORDER = [
9727
+ "evaluate",
9728
+ "initialize",
9729
+ "change",
9730
+ "review",
9731
+ "decide",
9732
+ "ship",
9733
+ "operate",
9734
+ "extend",
9735
+ "help"
9736
+ ];
9737
+ function plainRecord2(value) {
9738
+ return value !== null && typeof value === "object" && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
9739
+ }
9740
+ function sameStrings2(actual, expected) {
9741
+ return actual.length === expected.length && actual.every((item, index) => item === expected[index]);
9742
+ }
9743
+ function validLegacyRoutes(value) {
9744
+ return Array.isArray(value) && value.every((item) => typeof item === "string" && /^[a-z][a-z0-9-]*$/u.test(item)) && new Set(value).size === value.length && sameStrings2(value, [...value].sort());
9745
+ }
9746
+ function commandCatalogEntries(value) {
9747
+ const envelopeKeys = ["commands", "compatibility", "schemaVersion", "visibilityOrder", "workflowOrder"];
9748
+ if (!plainRecord2(value) || !sameStrings2(Object.keys(value).sort(), envelopeKeys) || value.schemaVersion !== 1 || !Array.isArray(value.visibilityOrder) || !sameStrings2(value.visibilityOrder, COMMAND_VISIBILITY_ORDER) || !Array.isArray(value.workflowOrder) || !sameStrings2(value.workflowOrder, COMMAND_WORKFLOW_ORDER) || !plainRecord2(value.compatibility) || !plainRecord2(value.commands)) {
9749
+ throw new Error("codeArbiter Pi command catalog envelope is invalid; run /ca-doctor.");
9750
+ }
9751
+ const commands = value.commands;
9752
+ const names = Object.keys(commands);
9753
+ if (!sameStrings2(names, [...names].sort()) || names.length === 0) {
9754
+ throw new Error("codeArbiter Pi command catalog envelope has no sorted commands; run /ca-doctor.");
9755
+ }
9756
+ const entries = [];
9757
+ for (const name of names) {
9758
+ const fail2 = () => {
9759
+ throw new Error(`codeArbiter Pi command catalog entry ${name} is invalid; run /ca-doctor.`);
9760
+ };
9761
+ const value2 = commands[name];
9762
+ if (!plainRecord2(value2)) {
9763
+ throw new Error(`codeArbiter Pi command catalog entry ${name} is invalid; run /ca-doctor.`);
9764
+ }
9765
+ const raw = value2;
9766
+ if (raw.name !== name || typeof raw.description !== "string" || raw.description === "" || raw.skillPath !== `skills/ca-${name}/SKILL.md` || !COMMAND_VISIBILITY_ORDER.includes(raw.visibility) || !COMMAND_WORKFLOW_ORDER.includes(raw.workflow)) {
9767
+ fail2();
9768
+ }
9769
+ const visibility = raw.visibility;
9770
+ const commonKeys = ["description", "name", "skillPath", "visibility", "workflow"];
9771
+ let expectedKeys;
9772
+ if (visibility === "core" || visibility === "advanced" || visibility === "internal") {
9773
+ expectedKeys = [...commonKeys, "canonical", "legacyRoutes"].sort();
9774
+ if (raw.canonical !== name || !validLegacyRoutes(raw.legacyRoutes)) fail2();
9775
+ } else if (visibility === "alias") {
9776
+ expectedKeys = [...commonKeys, "canonical", "replacement"].sort();
9777
+ if (typeof raw.canonical !== "string" || !/^[a-z][a-z0-9-]*$/u.test(raw.canonical) || typeof raw.replacement !== "string" || !raw.replacement.startsWith(`${raw.canonical} `)) fail2();
9778
+ } else {
9779
+ expectedKeys = [...commonKeys, "replacement"].sort();
9780
+ if (typeof raw.replacement !== "string" || raw.replacement === "") fail2();
9781
+ }
9782
+ if (!sameStrings2(Object.keys(raw).sort(), expectedKeys)) fail2();
9783
+ entries.push(Object.freeze({ ...raw }));
9784
+ }
9785
+ const entriesByName = new Map(entries.map((entry) => [entry.name, entry]));
9786
+ const expectedLegacyRoutes = /* @__PURE__ */ new Map();
9787
+ for (const entry of entries) {
9788
+ if (entry.visibility === "alias") {
9789
+ const target = entriesByName.get(entry.canonical);
9790
+ if (target === void 0 || target.visibility === "alias" || target.visibility === "deprecated") {
9791
+ throw new Error(`codeArbiter Pi command catalog entry ${entry.name} has an invalid alias target; run /ca-doctor.`);
9792
+ }
9793
+ const routes = expectedLegacyRoutes.get(entry.canonical) ?? [];
9794
+ routes.push(entry.name);
9795
+ expectedLegacyRoutes.set(entry.canonical, routes);
9796
+ }
9797
+ }
9798
+ for (const entry of entries) {
9799
+ if (entry.visibility === "alias" || entry.visibility === "deprecated") continue;
9800
+ const expected = (expectedLegacyRoutes.get(entry.name) ?? []).sort();
9801
+ if (!sameStrings2(entry.legacyRoutes ?? [], expected)) {
9802
+ throw new Error(`codeArbiter Pi command catalog entry ${entry.name} has broken legacy-route closure; run /ca-doctor.`);
9803
+ }
9804
+ }
9805
+ return Object.freeze(entries);
9806
+ }
9725
9807
  var PI_TRUST_REQUIRED_STATUS = "codeArbiter host: pi waiting for project trust - run /trust in Pi, approve this project, then start a new session";
9726
9808
  function hasAffirmativeProjectTrust(context) {
9727
9809
  try {
@@ -10257,7 +10339,9 @@ async function codeArbiterPi(pi) {
10257
10339
  if (parent === packageRoot) throw new Error("codeArbiter could not locate the ca-pi package; run /ca-doctor.");
10258
10340
  packageRoot = parent;
10259
10341
  }
10260
- const catalog = JSON.parse(await readFile6(resolve15(packageRoot, "generated", "command-catalog.json"), "utf8"));
10342
+ const catalog = commandCatalogEntries(
10343
+ JSON.parse(await readFile6(resolve15(packageRoot, "generated", "command-catalog.json"), "utf8"))
10344
+ );
10261
10345
  const toolClasses = loadPiToolClasses(define_CODEARBITER_PI_TOOL_CLASSES_default);
10262
10346
  const rawPermissionSurfaces = define_CODEARBITER_PI_PERMISSION_POLICY_SURFACES_default;
10263
10347
  if (rawPermissionSurfaces === null || typeof rawPermissionSurfaces !== "object" || Array.isArray(rawPermissionSurfaces)) {
@@ -10532,6 +10616,7 @@ export {
10532
10616
  PERSONA_SENTINEL,
10533
10617
  PI_RUNTIME_DIAGNOSIS,
10534
10618
  boundedPiEnvironment,
10619
+ commandCatalogEntries,
10535
10620
  compatibilityDirection,
10536
10621
  createCodeArbiterPi,
10537
10622
  createPiFooterMetricsLoader,