@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.
- package/LICENSE +661 -0
- package/README.md +558 -0
- package/package.json +35 -0
- package/plugins/ca-pi/CHANGELOG.md +1030 -0
- package/plugins/ca-pi/COMMANDS.md +90 -0
- package/plugins/ca-pi/ORCHESTRATOR.md +159 -0
- package/plugins/ca-pi/SKILLS.md +47 -0
- package/plugins/ca-pi/SPRINT.md +142 -0
- package/plugins/ca-pi/agents/INDEX.md +31 -0
- package/plugins/ca-pi/agents/architecture-drift-reviewer.md +86 -0
- package/plugins/ca-pi/agents/auth-crypto-reviewer.md +60 -0
- package/plugins/ca-pi/agents/backend-author.md +60 -0
- package/plugins/ca-pi/agents/checkpoint-aggregator.md +111 -0
- package/plugins/ca-pi/agents/coverage-auditor.md +71 -0
- package/plugins/ca-pi/agents/decision-challenger.md +116 -0
- package/plugins/ca-pi/agents/dependency-reviewer.md +79 -0
- package/plugins/ca-pi/agents/design-quality-reviewer.md +80 -0
- package/plugins/ca-pi/agents/finding-triage.md +86 -0
- package/plugins/ca-pi/agents/frontend-author.md +64 -0
- package/plugins/ca-pi/agents/grader.md +173 -0
- package/plugins/ca-pi/agents/infra-author.md +64 -0
- package/plugins/ca-pi/agents/map-deps.md +35 -0
- package/plugins/ca-pi/agents/map-structure.md +37 -0
- package/plugins/ca-pi/agents/migration-reviewer.md +65 -0
- package/plugins/ca-pi/agents/scout.md +127 -0
- package/plugins/ca-pi/agents/security-reviewer.md +72 -0
- package/plugins/ca-pi/agents/tribunal-lens-reviewer.md +65 -0
- package/plugins/ca-pi/extensions/codearbiter-child.js +1885 -0
- package/plugins/ca-pi/extensions/codearbiter.js +9802 -0
- package/plugins/ca-pi/generated/command-catalog.json +197 -0
- package/plugins/ca-pi/generated/roles.json +213 -0
- package/plugins/ca-pi/helpers/windows-supervisor.js +205 -0
- package/plugins/ca-pi/hooks/_activationlib.py +196 -0
- package/plugins/ca-pi/hooks/_arbiterstatelib.py +208 -0
- package/plugins/ca-pi/hooks/_babysitlib.py +76 -0
- package/plugins/ca-pi/hooks/_bashguardlib.py +1667 -0
- package/plugins/ca-pi/hooks/_boxlib.py +131 -0
- package/plugins/ca-pi/hooks/_colorlib.py +304 -0
- package/plugins/ca-pi/hooks/_durabilitylib.py +186 -0
- package/plugins/ca-pi/hooks/_entrylib.py +41 -0
- package/plugins/ca-pi/hooks/_fmtlib.py +161 -0
- package/plugins/ca-pi/hooks/_gitexec.py +45 -0
- package/plugins/ca-pi/hooks/_githooks.py +920 -0
- package/plugins/ca-pi/hooks/_gitlib.py +110 -0
- package/plugins/ca-pi/hooks/_hooklib.py +595 -0
- package/plugins/ca-pi/hooks/_host.py +115 -0
- package/plugins/ca-pi/hooks/_intentlib.py +242 -0
- package/plugins/ca-pi/hooks/_ledgerlib.py +1035 -0
- package/plugins/ca-pi/hooks/_metricslib.py +709 -0
- package/plugins/ca-pi/hooks/_pathnorm.py +74 -0
- package/plugins/ca-pi/hooks/_planfilelib.py +664 -0
- package/plugins/ca-pi/hooks/_previewlib.py +193 -0
- package/plugins/ca-pi/hooks/_protectedlib.py +312 -0
- package/plugins/ca-pi/hooks/_protectedstatelib.py +411 -0
- package/plugins/ca-pi/hooks/_provenancelib.py +971 -0
- package/plugins/ca-pi/hooks/_prunelib.py +1398 -0
- package/plugins/ca-pi/hooks/_prunepolicy.py +235 -0
- package/plugins/ca-pi/hooks/_readinjectlib.py +1080 -0
- package/plugins/ca-pi/hooks/_releaselib.py +2657 -0
- package/plugins/ca-pi/hooks/_scopelib.py +262 -0
- package/plugins/ca-pi/hooks/_segmentslib.py +278 -0
- package/plugins/ca-pi/hooks/_sensitivelib.py +270 -0
- package/plugins/ca-pi/hooks/_sessionlib.py +78 -0
- package/plugins/ca-pi/hooks/_sloplib.py +244 -0
- package/plugins/ca-pi/hooks/_standuplib.py +214 -0
- package/plugins/ca-pi/hooks/_subagentslib.py +219 -0
- package/plugins/ca-pi/hooks/_taskboardlib.py +1088 -0
- package/plugins/ca-pi/hooks/_updatelib.py +278 -0
- package/plugins/ca-pi/hooks/babysit.py +47 -0
- package/plugins/ca-pi/hooks/boardsync.py +129 -0
- package/plugins/ca-pi/hooks/doctor.py +420 -0
- package/plugins/ca-pi/hooks/git-enforce.py +325 -0
- package/plugins/ca-pi/hooks/hostapi.py +460 -0
- package/plugins/ca-pi/hooks/init-codearbiter.py +225 -0
- package/plugins/ca-pi/hooks/metrics.py +62 -0
- package/plugins/ca-pi/hooks/migration-pass.py +129 -0
- package/plugins/ca-pi/hooks/pi-bridge.py +543 -0
- package/plugins/ca-pi/hooks/post-write-edit.py +231 -0
- package/plugins/ca-pi/hooks/pre-bash.py +90 -0
- package/plugins/ca-pi/hooks/pre-edit.py +284 -0
- package/plugins/ca-pi/hooks/pre-read.py +81 -0
- package/plugins/ca-pi/hooks/pre-write.py +217 -0
- package/plugins/ca-pi/hooks/preview.py +69 -0
- package/plugins/ca-pi/hooks/prune-transcript.py +232 -0
- package/plugins/ca-pi/hooks/releasehash.py +216 -0
- package/plugins/ca-pi/hooks/security-pass.py +139 -0
- package/plugins/ca-pi/hooks/session-start.py +1218 -0
- package/plugins/ca-pi/hooks/statusline.py +736 -0
- package/plugins/ca-pi/hooks/taskwrite.py +351 -0
- package/plugins/ca-pi/hooks/update-refresh.py +51 -0
- package/plugins/ca-pi/hooks/wire-statusline.py +435 -0
- package/plugins/ca-pi/includes/anti-slop-design/INDEX.md +55 -0
- package/plugins/ca-pi/includes/anti-slop-design/color.md +43 -0
- package/plugins/ca-pi/includes/anti-slop-design/core.md +244 -0
- package/plugins/ca-pi/includes/anti-slop-design/images.md +32 -0
- package/plugins/ca-pi/includes/anti-slop-design/layout.md +45 -0
- package/plugins/ca-pi/includes/anti-slop-design/medium-cli.md +39 -0
- package/plugins/ca-pi/includes/anti-slop-design/medium-dataviz.md +43 -0
- package/plugins/ca-pi/includes/anti-slop-design/medium-diagram.md +35 -0
- package/plugins/ca-pi/includes/anti-slop-design/medium-documents.md +70 -0
- package/plugins/ca-pi/includes/anti-slop-design/medium-slides.md +30 -0
- package/plugins/ca-pi/includes/anti-slop-design/medium-web.md +39 -0
- package/plugins/ca-pi/includes/anti-slop-design/typography.md +51 -0
- package/plugins/ca-pi/includes/author-tdd-workflow.md +14 -0
- package/plugins/ca-pi/includes/compaction-charter.md +16 -0
- package/plugins/ca-pi/includes/cut-docs.md +16 -0
- package/plugins/ca-pi/includes/dev-mode.md +30 -0
- package/plugins/ca-pi/includes/farm.md +237 -0
- package/plugins/ca-pi/includes/fresh-verification.md +14 -0
- package/plugins/ca-pi/includes/harvest.md +69 -0
- package/plugins/ca-pi/includes/maturity-coverage.md +102 -0
- package/plugins/ca-pi/includes/pi-host-notes.md +69 -0
- package/plugins/ca-pi/includes/redirect.md +69 -0
- package/plugins/ca-pi/includes/reference-map.md +22 -0
- package/plugins/ca-pi/includes/review-matrix.md +14 -0
- package/plugins/ca-pi/includes/reviewer-contract.md +53 -0
- package/plugins/ca-pi/includes/routing-table.md +47 -0
- package/plugins/ca-pi/includes/security-gate-record.md +22 -0
- package/plugins/ca-pi/includes/smarts/core.md +90 -0
- package/plugins/ca-pi/includes/smarts/decision-log-format.md +56 -0
- package/plugins/ca-pi/routines/INDEX.md +32 -0
- package/plugins/ca-pi/routines/brainstorming/SKILL.md +122 -0
- package/plugins/ca-pi/routines/commit-gate/SKILL.md +151 -0
- package/plugins/ca-pi/routines/context-check/SKILL.md +85 -0
- package/plugins/ca-pi/routines/context-creation/SKILL.md +171 -0
- package/plugins/ca-pi/routines/crypto-compliance/SKILL.md +41 -0
- package/plugins/ca-pi/routines/debug/SKILL.md +99 -0
- package/plugins/ca-pi/routines/decision-lifecycle/SKILL.md +104 -0
- package/plugins/ca-pi/routines/decision-lifecycle/references/adr-template.md +74 -0
- package/plugins/ca-pi/routines/decision-variance/SKILL.md +147 -0
- package/plugins/ca-pi/routines/decompose/SKILL.md +168 -0
- package/plugins/ca-pi/routines/dispatching-parallel-agents/SKILL.md +76 -0
- package/plugins/ca-pi/routines/executing-plans/SKILL.md +83 -0
- package/plugins/ca-pi/routines/finishing-a-development-branch/SKILL.md +91 -0
- package/plugins/ca-pi/routines/post-merge-cleanup/SKILL.md +233 -0
- package/plugins/ca-pi/routines/refactor/SKILL.md +91 -0
- package/plugins/ca-pi/routines/release/SKILL.md +315 -0
- package/plugins/ca-pi/routines/secret-handling/SKILL.md +67 -0
- package/plugins/ca-pi/routines/security-architecture/SKILL.md +63 -0
- package/plugins/ca-pi/routines/skill-author/SKILL.md +108 -0
- package/plugins/ca-pi/routines/skill-author/references/skill-template.md +58 -0
- package/plugins/ca-pi/routines/subagent-driven-development/SKILL.md +149 -0
- package/plugins/ca-pi/routines/subagent-driven-development/references/farm-dispatch.md +145 -0
- package/plugins/ca-pi/routines/tdd/SKILL.md +139 -0
- package/plugins/ca-pi/routines/tribunal/SKILL.md +109 -0
- package/plugins/ca-pi/routines/tribunal/references/ai-markers.md +29 -0
- package/plugins/ca-pi/routines/tribunal/references/cost-and-models.md +64 -0
- package/plugins/ca-pi/routines/tribunal/references/finding-record.md +27 -0
- package/plugins/ca-pi/routines/tribunal/references/issue-filing.md +47 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/appsec.md +22 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/architecture.md +23 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/coverage.md +20 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/infra.md +24 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/migration.md +22 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/observability.md +21 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/performance.md +22 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/reliability.md +23 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/secrets-supply.md +22 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/test-fidelity.md +24 -0
- package/plugins/ca-pi/routines/tribunal/references/lenses/typesafety.md +21 -0
- package/plugins/ca-pi/routines/tribunal/references/report.md +19 -0
- package/plugins/ca-pi/routines/tribunal/references/schemas.md +58 -0
- package/plugins/ca-pi/routines/tribunal/references/telemetry.md +28 -0
- package/plugins/ca-pi/routines/tribunal/references/triage.md +53 -0
- package/plugins/ca-pi/routines/using-git-worktrees/SKILL.md +85 -0
- package/plugins/ca-pi/routines/writing-plans/SKILL.md +129 -0
- package/plugins/ca-pi/routines/writing-plans/references/farm-plan.md +50 -0
- package/plugins/ca-pi/skills/ca-add-dep/SKILL.md +88 -0
- package/plugins/ca-pi/skills/ca-adr/SKILL.md +30 -0
- package/plugins/ca-pi/skills/ca-adr-status/SKILL.md +30 -0
- package/plugins/ca-pi/skills/ca-arbiter/SKILL.md +36 -0
- package/plugins/ca-pi/skills/ca-audit/SKILL.md +51 -0
- package/plugins/ca-pi/skills/ca-btw/SKILL.md +23 -0
- package/plugins/ca-pi/skills/ca-checkpoint/SKILL.md +50 -0
- package/plugins/ca-pi/skills/ca-chore/SKILL.md +58 -0
- package/plugins/ca-pi/skills/ca-cleanup/SKILL.md +55 -0
- package/plugins/ca-pi/skills/ca-commands/SKILL.md +21 -0
- package/plugins/ca-pi/skills/ca-commit/SKILL.md +27 -0
- package/plugins/ca-pi/skills/ca-conflict/SKILL.md +61 -0
- package/plugins/ca-pi/skills/ca-context-check/SKILL.md +32 -0
- package/plugins/ca-pi/skills/ca-create-context/SKILL.md +32 -0
- package/plugins/ca-pi/skills/ca-debug/SKILL.md +42 -0
- package/plugins/ca-pi/skills/ca-decompose/SKILL.md +30 -0
- package/plugins/ca-pi/skills/ca-dev/SKILL.md +42 -0
- package/plugins/ca-pi/skills/ca-doctor/SKILL.md +44 -0
- package/plugins/ca-pi/skills/ca-feature/SKILL.md +105 -0
- package/plugins/ca-pi/skills/ca-fix/SKILL.md +42 -0
- package/plugins/ca-pi/skills/ca-init/SKILL.md +56 -0
- package/plugins/ca-pi/skills/ca-metrics/SKILL.md +80 -0
- package/plugins/ca-pi/skills/ca-new-skill/SKILL.md +34 -0
- package/plugins/ca-pi/skills/ca-override/SKILL.md +72 -0
- package/plugins/ca-pi/skills/ca-pr/SKILL.md +61 -0
- package/plugins/ca-pi/skills/ca-preview/SKILL.md +86 -0
- package/plugins/ca-pi/skills/ca-prune/SKILL.md +100 -0
- package/plugins/ca-pi/skills/ca-reconcile/SKILL.md +43 -0
- package/plugins/ca-pi/skills/ca-refactor/SKILL.md +43 -0
- package/plugins/ca-pi/skills/ca-release/SKILL.md +57 -0
- package/plugins/ca-pi/skills/ca-review/SKILL.md +63 -0
- package/plugins/ca-pi/skills/ca-spike/SKILL.md +41 -0
- package/plugins/ca-pi/skills/ca-sprint/SKILL.md +44 -0
- package/plugins/ca-pi/skills/ca-standup/SKILL.md +112 -0
- package/plugins/ca-pi/skills/ca-status/SKILL.md +56 -0
- package/plugins/ca-pi/skills/ca-task/SKILL.md +61 -0
- package/plugins/ca-pi/skills/ca-threat-model/SKILL.md +45 -0
- package/plugins/ca-pi/skills/ca-tribunal/SKILL.md +44 -0
- package/plugins/ca-pi/skills/ca-watch/SKILL.md +78 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Orchestrator schemas & artifact layout
|
|
2
|
+
|
|
3
|
+
The finding record (what agents emit) is in `finding-record.md`. This file holds the orchestrator-only logs and the run layout. Source of truth = the per-finding files (`findings/<lens>/<finding-id>.json`) plus the two append-only logs (`triage.jsonl`, `run.jsonl`); everything else is a projection regenerable from them. Write each record as it is produced — never batch.
|
|
4
|
+
|
|
5
|
+
## Artifact tree
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
.codearbiter/reports/<run-id>/ # run-id = <UTC-date>-<scope-slug>
|
|
9
|
+
run.jsonl # APPEND-ONLY run-state events; resume source of truth
|
|
10
|
+
manifest.yaml # projection of run.jsonl (regenerable snapshot)
|
|
11
|
+
inventory.md # map + risk/boundary/marker overlay
|
|
12
|
+
findings/<lens>/<finding-id>.json # one finding per file, written on discovery
|
|
13
|
+
# (crash-durable: a kill risks only the in-flight file;
|
|
14
|
+
# per-lens dirs, so no write contention)
|
|
15
|
+
triage.jsonl # APPEND-ONLY, one decision/line
|
|
16
|
+
bodies/<finding-id>.md # issue body, lazy, approved-only
|
|
17
|
+
plans/phase-<n>.md # per-wave path plan (projection)
|
|
18
|
+
report.md # final human-readable (projection)
|
|
19
|
+
issue-commands.sh # ready-to-run gh issue create commands
|
|
20
|
+
telemetry.json # KPI payload, opt-in
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## triage/v1 — one object per line in `triage.jsonl`
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{"schema":"triage/v1","id":"<finding-id>","decision":"keep|combine|duplicate|false-positive|defer|accept-risk|decision-required|investigate","final_severity":"critical|high|medium|low","final_confidence":0.0,"counter_argument":"<steelman; required for critical+high>","rationale":"<why>","group_id":"<when combine>","duplicate_of":"<finding-id, when duplicate>","issue_ref":"<filled after filing>","decided_at":"<iso8601>"}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`final_*` override the provisional self-scores everywhere downstream. `issue_ref` closes the finding→issue loop and makes re-runs idempotent.
|
|
30
|
+
|
|
31
|
+
## run/v1 — one state event per line in `run.jsonl`
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{"schema":"run/v1","event":"run-started|lens-launched|lens-skipped|lens-completed|wave-flushed|wave-triaged|report-written|issues-filed|telemetry-sent|run-aborted","wave":1,"lens":"<lens>","detail":"<optional>","surface_seen":0,"findings":0,"model":"<model>","tokens":0,"at":"<iso8601>"}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`run-aborted` records a deliberate abandon (optional `detail` = reason) and marks the run terminal.
|
|
38
|
+
|
|
39
|
+
A `lens-completed` event carries `surface_seen` (int — the lens's Exposure denominator), `findings` (int — count the lens emitted), and `model` (the model the lens ran on, as dispatched); `model` also appears on `lens-launched`. `tokens` (int, optional) records the lens's observed token spend when the orchestrator can see it; null/omitted when unobserved.
|
|
40
|
+
|
|
41
|
+
The `run-started` event's `detail` carries the chosen wave partition — the lens list per wave (default or repartitioned-for-cause, per `cost-and-models.md`). This is the single record of the partition; nothing else derives or re-derives it.
|
|
42
|
+
|
|
43
|
+
## Resume — read the cursor, never the finding bodies
|
|
44
|
+
|
|
45
|
+
`run.jsonl` is the coarse state log — one line per wave/lens transition, tens of lines even across retries, not the per-finding logs. Resume reads the cursor, not the whole run, and never re-hydrates completed work:
|
|
46
|
+
|
|
47
|
+
0. **No `run-started`.** A run dir present but with no `run-started` event in `run.jsonl` is a Phase-0/1 death — restart Phase 0/1 fresh (`inventory.md` and lens selection are cheap to rebuild); any finding files already on disk stand and are deduped at triage as normal.
|
|
48
|
+
1. **Position.** The resume point is fixed by the last triaged wave: `grep '"event":"wave-triaged"' run.jsonl | tail -1` returns it while reading only matching lines. If none, resume at wave 1.
|
|
49
|
+
2. **Plan.** Read the wave partition from the `run-started` event's `detail` — the recorded partition, never re-derived — via `manifest.yaml` (a small projection) or, if it is missing or stale, `run.jsonl` directly. Both are bounded reads — never a full-file scan for the plan.
|
|
50
|
+
3. **Re-enter** Phase 2/3 for waves after the last triaged one only.
|
|
51
|
+
4. **Do not load** already-triaged waves' `findings/<lens>/` files or `triage.jsonl` into context — they are authoritative on disk. A later wave's dedup that needs a specific prior id fetches it by targeted `grep` across `findings/`, never a full read.
|
|
52
|
+
5. **Ordering.** `plans/phase-<n>.md` is written before the `wave-triaged` event for that wave is emitted — the event asserts the plan exists.
|
|
53
|
+
|
|
54
|
+
`manifest.yaml` is a convenience snapshot regenerated from `run.jsonl`; it accelerates the plan read but is never authoritative — a corrupt or stale manifest falls back to the append-only log.
|
|
55
|
+
|
|
56
|
+
## dedup_key & ids
|
|
57
|
+
|
|
58
|
+
`id`: `<lens>-NNN`, sequential per lens. `dedup_key`: `<lens>:<path-normalized-to-repo-root>:<short-slug-of-title>`. Dedup matches on `dedup_key` and overlapping `locations`.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Telemetry (opt-in, KPI-only)
|
|
2
|
+
|
|
3
|
+
Optional feedback that refines the skill and calibrates the estimator, pooled across contributors. The target is the public codeArbiter repo, so a shared corpus needs a shared destination — which is safe only because the payload is boring by construction: aggregates and per-lens exposure counts, never anything that identifies a codebase or exposes a weakness. Off by default; sent only on explicit per-run authorization.
|
|
4
|
+
|
|
5
|
+
## Hard scrubbing
|
|
6
|
+
|
|
7
|
+
The payload carries integers and enums only. It MUST NOT contain code, file paths, finding titles or text, commit hashes, or remote URLs. Repo identity is omitted by default; a contributor who wants to self-tag their submission for their own cross-run tracking may add `--tag <label>`, and only then does `tag` appear. `run_id` is a fresh random value, not derived from the repo.
|
|
8
|
+
|
|
9
|
+
## Why exposure counts, not raw findings
|
|
10
|
+
|
|
11
|
+
A raw finding count is uninterpretable alone: it is base-rate x detector-sensitivity x exposure, and you cannot invert the product from one number. "0 SQL-injection findings" reads as both "nobody concatenates SQL" and "our appsec lens is blind" — and those resolve oppositely. The per-lens `surface_seen` denominator disambiguates: 0 against a large surface is a blind-spot alarm; 0 against no surface is correctly uninformative. `false_positives` (from the decision log) separates a silent lens from a noisy one. These fields let the corpus *flag* blind-vs-rare; they cannot *confirm* it — that needs ground truth (a seeded-vulnerability canary or a semgrep/CodeQL cross-check), which is a separate self-test, not a payload field.
|
|
12
|
+
|
|
13
|
+
Reading the corpus is the maintainer's judgment, not skill behavior — and a suspicious zero in a security lens defaults to suspecting the detector, never to dialing the lens back, because those costs are asymmetric.
|
|
14
|
+
|
|
15
|
+
## Payload — `telemetry.json`
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{"schema":"telemetry/v1","skill_version":"<x.y.z>","run_id":"<random>","at":"<iso8601>","tag":"<omitted unless --tag>","loc_total":0,"loc_by_language":{"<lang>":0},"files_scanned":0,"primary_language":"<lang>","lenses_run":0,"lenses_skipped":0,"model_orchestrator":"<api-string>","models_by_tier":{"opus":0,"sonnet":0,"haiku":0},"tokens_estimated":0,"tokens_actual":null,"lens_exposure":{"<lens>":{"ran":true,"surface_seen":0,"findings":0,"false_positives":0}},"issues_found":0,"severity_breakdown":{"critical":0,"high":0,"medium":0,"low":0},"decision_breakdown":{"keep":0,"combine":0,"duplicate":0,"false_positive":0,"defer":0,"accept_risk":0,"decision_required":0,"investigate":0},"issues_filed":0,"run_duration_sec":0}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`lens_exposure` is the field that makes the corpus interpretable; `surface_seen` and `model_orchestrator`/`models_by_tier` are sourced from `run.jsonl` `lens-launched`/`lens-completed` events, not hand-tallied. `tokens_estimated` vs `tokens_actual` calibrates the cost estimate (a guardrail, not a measure of review quality); `tokens_actual` sums `run.jsonl` `lens-completed` `tokens` when present, and is otherwise optional/best-effort — null when the orchestrator could not observe subagent spend. `issues_found` is the post-triage kept count (the `keep` + `combine` decision groups), distinct from the per-lens raw `findings` counts in `lens_exposure`. `skill_version` is read from `plugin.json`, not hand-set.
|
|
22
|
+
|
|
23
|
+
## Send procedure
|
|
24
|
+
|
|
25
|
+
- Write `telemetry.json`; show it in full.
|
|
26
|
+
- State plainly, in one line: these aggregates post publicly to the codeArbiter repo; they carry no code, paths, or finding text, and no repo identity unless you added `--tag`.
|
|
27
|
+
- **Default:** print `gh issue create --repo arbiterForge/codeArbiter --label telemetry --title "run-metrics <at>" --body-file telemetry.json`. Stop.
|
|
28
|
+
- **On explicit approval:** run it; record a `telemetry-sent` event in `run.jsonl`.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Triage & calibration
|
|
2
|
+
|
|
3
|
+
Triage per wave from disk. The orchestrator's calibrated values are final and override every provisional self-score downstream.
|
|
4
|
+
|
|
5
|
+
## Dedup
|
|
6
|
+
|
|
7
|
+
Before calibrating, dedup each new finding against all findings already on disk — match by `dedup_key` and by overlapping locations. A match decides as `duplicate` (`duplicate_of` set), distinct from `combine`.
|
|
8
|
+
|
|
9
|
+
## Severity rubric (impact x likelihood)
|
|
10
|
+
|
|
11
|
+
- **critical** — exploitable security hole, data loss/corruption, or an outage path reachable with realistic input.
|
|
12
|
+
- **high** — serious correctness/security weakness, latent but plausible; or a systemic architectural defect amplifying other risk.
|
|
13
|
+
- **medium** — real defect/debt, limited blast radius or lower likelihood.
|
|
14
|
+
- **low** — minor quality, polish, or DX improvement.
|
|
15
|
+
|
|
16
|
+
## Calibration
|
|
17
|
+
|
|
18
|
+
For each finding, set `final_severity`/`final_confidence` from the evidence directly — the lens's values are provisional input. For every critical/high, record a `counter_argument` — the strongest case it is lower or a false positive; if compelling, downgrade or reclassify. Calibration is bidirectional: promote under-rated findings too. Optional for criticals: dispatch a fresh-context adversary that sees only the finding + code and tries to refute it, to defeat anchoring.
|
|
19
|
+
|
|
20
|
+
## Severity priors
|
|
21
|
+
|
|
22
|
+
Apply as priors on findings that already cleared evidence-or-drop, never to manufacture one: resource-level authz / IDOR → high or critical; injection with reachable user input → high or critical; literal secret → high or critical; async operation with no handler on a critical path → high. A high-marker/high-iteration location (per `ai-markers.md`) nudges one level at most.
|
|
23
|
+
|
|
24
|
+
## Confidence gate
|
|
25
|
+
|
|
26
|
+
The bar a finding's `final_confidence` must clear to file, tiered by severity — an uncertain critical is too costly to bury silently, so it gets a lower bar and a softer landing than a low:
|
|
27
|
+
|
|
28
|
+
| `final_severity` | gate | below the gate |
|
|
29
|
+
| --- | --- | --- |
|
|
30
|
+
| critical / high | ≥0.5 | → `decision-required`, framed as a question, never dropped silently |
|
|
31
|
+
| medium | ≥0.7 | → `investigate` |
|
|
32
|
+
| low | ≥0.75 | → `investigate` |
|
|
33
|
+
|
|
34
|
+
## Low-severity discipline
|
|
35
|
+
|
|
36
|
+
A `low` is kept only above the confidence gate (≥0.75, see above) with a concrete, actionable remediation. Beyond ~5 lows per lens, aggregate the remainder into a single rollup finding that still lists each `path:line`.
|
|
37
|
+
|
|
38
|
+
## Decision vocabulary (into `triage.jsonl`)
|
|
39
|
+
|
|
40
|
+
- **keep** — actionable fix; files as its own issue.
|
|
41
|
+
- **combine** — real, merged with siblings under a shared `group_id`; one issue.
|
|
42
|
+
- **duplicate** — identical to a recorded finding (`duplicate_of`); distinct from combine.
|
|
43
|
+
- **false-positive** — not real; `rationale` required (this tunes future-run noise down — keep it).
|
|
44
|
+
- **defer** — real, out of scope/priority now; preserved, not filed this run.
|
|
45
|
+
- **accept-risk** — real, consciously not fixing; the risk-acceptance trail.
|
|
46
|
+
- **decision-required** — real and significant, but the response is an ADR-grade design choice, not a clear fix; files as a discussion, not a fix ticket.
|
|
47
|
+
- **investigate** — undecided, or a medium/low below the confidence gate after calibration; never filed.
|
|
48
|
+
|
|
49
|
+
Below the confidence gate after calibration: medium/low → `investigate`; critical/high → `decision-required` (see Confidence gate above — never dropped silently). ADR-grade questions also → `decision-required`.
|
|
50
|
+
|
|
51
|
+
## Per-wave plan
|
|
52
|
+
|
|
53
|
+
`plans/phase-<n>.md` covers only `keep`/`combine`, grouped by type (lens/category/`group_id`): shared remediation approach, ordered sequence, cross-group `depends_on`, rolled-up acceptance criteria. Roadmap level only — no per-finding code steps. A `decision-required` item gets a one-line "ADR-candidate — resolve via `/ca-adr`" pointer, never an authored ADR.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: using-git-worktrees
|
|
3
|
+
description: OPTIONAL per-task isolation for autonomous parallel work. Routed to only on explicit opt-in by subagent-driven-development or dispatching-parallel-agents, so parallel units mutate files without colliding. Stands up one worktree per unit, works it in isolation, then integrates each unit back onto the caller's working branch for the caller's single commit-gate + finishing-a-development-branch exit. Never on the default path; it does not bypass a gate or finish per unit.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# using-git-worktrees
|
|
8
|
+
|
|
9
|
+
OPTIONAL. Per-task filesystem isolation for parallel agent work — opt-in only, never the default path.
|
|
10
|
+
Routed to by `subagent-driven-development` and `dispatching-parallel-agents` when, and only when, the
|
|
11
|
+
caller requests isolation. If no isolation is requested, this skill does not run; parallel units share
|
|
12
|
+
the working tree under their own discipline.
|
|
13
|
+
|
|
14
|
+
Isolation is convenience, not soul. It lets concurrent units edit files without collision. It changes
|
|
15
|
+
nothing about the gates — the consolidated work still clears `commit-gate` and the single
|
|
16
|
+
`finishing-a-development-branch` terminal step, run by the caller. What it MUST NOT do is multiply
|
|
17
|
+
that terminal step into one PR per unit.
|
|
18
|
+
|
|
19
|
+
## Pre-flight
|
|
20
|
+
|
|
21
|
+
Read these, or STOP and surface the gap — never guess:
|
|
22
|
+
|
|
23
|
+
- `<project-root>/.codearbiter/CONTEXT.md` — confirm the repo is a git repo and the base/working branch.
|
|
24
|
+
|
|
25
|
+
Confirm the caller passed an explicit isolation opt-in AND the parallel unit list (from `plans/<slug>.md`). Absent either, do not stand up worktrees.
|
|
26
|
+
|
|
27
|
+
## Phase 1 — Provision · gate: BLOCK
|
|
28
|
+
|
|
29
|
+
Stand up one worktree per parallel unit. For each unit, create a worktree on a fresh branch off the
|
|
30
|
+
current base, under a dedicated parent directory outside the main working tree
|
|
31
|
+
(e.g. `../.codearbiter-worktrees/<slug>`):
|
|
32
|
+
|
|
33
|
+
- One worktree, one branch, one unit. Never share a worktree across units.
|
|
34
|
+
- Branch name MUST be unique and traceable to its unit's task ID.
|
|
35
|
+
- Record each worktree path and branch in a dedicated manifest `<project-root>/.codearbiter/.worktrees.json` (gitignored scratch — NOT the `open-tasks.md` backlog) so a crash leaves no untracked isolation.
|
|
36
|
+
|
|
37
|
+
Gate: every unit has a distinct worktree on a distinct branch, all rooted at the same clean base, all
|
|
38
|
+
recorded. A reused branch or a missing record does not pass.
|
|
39
|
+
|
|
40
|
+
## Phase 2 — Isolated work · gate: BLOCK
|
|
41
|
+
|
|
42
|
+
Each parallel unit works entirely inside its own worktree. Dispatch is unchanged — the caller still
|
|
43
|
+
dispatches its author and reviewer agents; they simply operate on the isolated path.
|
|
44
|
+
|
|
45
|
+
- A unit MUST NOT read or write outside its assigned worktree.
|
|
46
|
+
- A unit MUST NOT touch `main` or any other unit's branch.
|
|
47
|
+
- All implementation inside a worktree still flows through `tdd` — isolation is not a TDD bypass.
|
|
48
|
+
|
|
49
|
+
Gate: each unit's work is contained to its own worktree, with no cross-worktree or base-branch writes.
|
|
50
|
+
|
|
51
|
+
## Phase 3 — Fold back · gate: BLOCK
|
|
52
|
+
|
|
53
|
+
Integrate each isolated unit's work back onto the caller's single working branch — do NOT finish each
|
|
54
|
+
unit on its own. Per unit, in order:
|
|
55
|
+
|
|
56
|
+
1. Confirm the unit was accepted by the caller (its per-task review and verification passed in
|
|
57
|
+
`subagent-driven-development`, or its result cleared the funnel in `dispatching-parallel-agents`).
|
|
58
|
+
An unaccepted unit does not fold back.
|
|
59
|
+
2. Integrate its branch onto the caller's working branch (merge or rebase), resolving any conflict
|
|
60
|
+
here, in the open. Never integrate onto `main` or the default branch.
|
|
61
|
+
|
|
62
|
+
The consolidated working branch then takes the caller's normal single exit — ONE `commit-gate` pass
|
|
63
|
+
and ONE `finishing-a-development-branch` decision, run by the caller, not per unit. This skill
|
|
64
|
+
integrates; it never opens N PRs or finishes N branches. A unit that cannot integrate cleanly is
|
|
65
|
+
surfaced as a conflict for resolution — never force-merged, never dropped silently.
|
|
66
|
+
|
|
67
|
+
Gate: every accepted unit integrated onto the caller's working branch with conflicts resolved; no
|
|
68
|
+
per-unit PR or finish was opened.
|
|
69
|
+
|
|
70
|
+
## Phase 4 — Teardown · gate: BLOCK
|
|
71
|
+
|
|
72
|
+
Remove every worktree this skill created, prune its administrative metadata, and clear the manifest at
|
|
73
|
+
`<project-root>/.codearbiter/.worktrees.json`. A unit whose branch was integrated onto the
|
|
74
|
+
working branch (Phase 3) has its worktree torn down; an unaccepted or abandoned unit's worktree and
|
|
75
|
+
branch are removed together.
|
|
76
|
+
|
|
77
|
+
Gate: zero worktrees created by this skill remain, and the manifest is empty. An orphaned worktree is a failure.
|
|
78
|
+
|
|
79
|
+
## Hard rules
|
|
80
|
+
|
|
81
|
+
- MUST NOT run on the default path — isolation requires an explicit caller opt-in.
|
|
82
|
+
- MUST NOT share a worktree or a branch across parallel units.
|
|
83
|
+
- MUST NOT let a unit read or write outside its assigned worktree, or touch `main`.
|
|
84
|
+
- MUST NOT open a per-unit PR or run `finishing-a-development-branch` per unit — integrate accepted units onto the caller's working branch, which takes the single `commit-gate` + finishing exit.
|
|
85
|
+
- MUST NOT leave an orphaned worktree behind — every worktree this skill creates is torn down before the skill returns.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: writing-plans
|
|
3
|
+
description: The spec-to-plan bridge. Routed to by /feature once the brainstormed spec is approved, and by /sprint before execution. Decomposes the spec into 2–5 minute tasks, each carrying its exact file path(s) and a concrete verification step that maps to a tdd obligation. Writes the plan to .codearbiter/plans/<slug>.md, ordered with dependencies flagged and an MVP slice identifiable. Nothing executes until every task has a path and a verification and the task set covers every acceptance criterion.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# writing-plans
|
|
8
|
+
|
|
9
|
+
Turn an approved spec into an executable plan. Routed to by `/feature` (after spec approval) and `/sprint`.
|
|
10
|
+
|
|
11
|
+
## Pre-flight
|
|
12
|
+
|
|
13
|
+
Read these, or STOP and surface the gap — never plan against an unapproved or missing spec:
|
|
14
|
+
|
|
15
|
+
- `<project-root>/.codearbiter/specs/<slug>.md` — the approved brainstorming spec. The single source of acceptance criteria. Absent or unapproved → STOP and route back to `/feature`.
|
|
16
|
+
- `<project-root>/.codearbiter/CONTEXT.md` — the `stage:` frontmatter (the maturity value) and project context.
|
|
17
|
+
- `<project-root>/.codearbiter/tech-stack.md` — file layout, build/test/lint invocations. A verification step cites a real command from here, never a guess.
|
|
18
|
+
- `<project-root>/.codearbiter/coding-standards.md` — structure and naming, so a task names the right path.
|
|
19
|
+
|
|
20
|
+
**If `--farm` was requested:** check that `FARM_API_KEY` is set in the environment of the Pi parent process. If absent, BLOCK immediately — cite `<plugin-root>/includes/farm.md` for setup instructions. Do not proceed; the farm dispatcher cannot run without an API key. Model selection happens later (at dispatch time in `subagent-driven-development`), so no model research is needed here.
|
|
21
|
+
|
|
22
|
+
## Phase 1 — Criterion extraction · gate: BLOCK
|
|
23
|
+
|
|
24
|
+
Lift every acceptance criterion from the spec verbatim and assign each a stable ID (`AC-01`,
|
|
25
|
+
`AC-02`, …). This list is the coverage ledger for the whole plan — Phase 4 checks the task set
|
|
26
|
+
against it.
|
|
27
|
+
|
|
28
|
+
A criterion the spec leaves ambiguous is a `[CONFIRM-NN]` against
|
|
29
|
+
`<project-root>/.codearbiter/open-questions.md` — surface it, do not invent the intent.
|
|
30
|
+
|
|
31
|
+
**Backstop the ledger against the spec's own stated intent, mechanically, before trusting it — this
|
|
32
|
+
runs even when `brainstorming` already ran the same check, because a hole that survived Phase 3
|
|
33
|
+
survives Phase 4's bijection too, silently** (#566): run `"$PY" "<plugin-root>/hooks/_intentlib.py"
|
|
34
|
+
uncovered-intent <project-root>/.codearbiter/specs/<slug>.md [--issue-body <scratch-file>]` —
|
|
35
|
+
`<scratch-file>` holds the linked issue's body when one exists (`gh issue view <N> --json body -q
|
|
36
|
+
.body > <scratch-file>`, written outside the working tree), omitted when none does. A non-empty
|
|
37
|
+
result names an in-scope bullet or an acceptance checkbox the criteria never cited — BLOCK and route
|
|
38
|
+
back to `brainstorming` (`<plugin-root>/routines/brainstorming/SKILL.md`) to add the missing criterion or record a `[CONFIRM-NN]`; never paper over a
|
|
39
|
+
missing criterion by authoring a task for it here instead. This is the LAST point before a hole gets
|
|
40
|
+
laundered through Phase 4's bijection, which only checks the ledger against itself and cannot see
|
|
41
|
+
past it.
|
|
42
|
+
|
|
43
|
+
Then ask the half this tool cannot mechanize: **if every `AC-NN` passed and nothing else changed,
|
|
44
|
+
what would still be broken?** A real answer names a criterion the ledger is missing even though
|
|
45
|
+
every scope bullet and checkbox is technically cited — judgment, not mechanizable, and not satisfied
|
|
46
|
+
by a rhetorical "nothing." Finding nothing broken is a reportable result, stated in one line, never a
|
|
47
|
+
silent skip.
|
|
48
|
+
|
|
49
|
+
Gate: every acceptance criterion in the spec captured as a numbered `AC-NN`; the `uncovered_intent`
|
|
50
|
+
backstop above returns empty or every finding is resolved; and the negative question has been asked
|
|
51
|
+
and answered. A partial ledger does not pass.
|
|
52
|
+
|
|
53
|
+
## Phase 2 — Task decomposition · gate: BLOCK
|
|
54
|
+
|
|
55
|
+
Break the work into the smallest honest units. Each **task** is ~2–5 minutes of work and carries:
|
|
56
|
+
|
|
57
|
+
- **id** — `T-01`, `T-02`, … stable.
|
|
58
|
+
- **path(s)** — the exact file(s) the task touches, resolved against `coding-standards.md`. "Some files" is not a path.
|
|
59
|
+
- **verification** — one concrete command or observable that proves the task done (e.g., `<test cmd> -k test_token_expiry passes`, `endpoint returns 401 on missing header`). It cites a real `tech-stack.md` invocation or a directly observable behavior — never "looks right".
|
|
60
|
+
- **maps-to** — the `tdd` obligation this verification corresponds to. The verification *maps to* a tdd obligation; it does NOT replace tdd's own gates. `tdd` Phase 1 still derives and Phase 4 still verifies obligations against passing tests.
|
|
61
|
+
- **covers** — the `AC-NN`(s) this task advances.
|
|
62
|
+
|
|
63
|
+
Split anything that won't fit ~5 minutes or touches unrelated paths. Reject the trap of one
|
|
64
|
+
monolithic "implement the feature" task — that defeats the plan.
|
|
65
|
+
|
|
66
|
+
Gate: every task has at least one path AND a verification AND a `maps-to`. A task missing any of the
|
|
67
|
+
three blocks the plan.
|
|
68
|
+
|
|
69
|
+
## Phase 3 — Order & MVP slice · gate: BLOCK
|
|
70
|
+
|
|
71
|
+
Order tasks so each runs only after what it depends on. Flag every dependency explicitly
|
|
72
|
+
(`T-07 depends on T-03`). A cycle is a decomposition error — return to Phase 2 and split.
|
|
73
|
+
|
|
74
|
+
Group the ordered tasks so the **MVP slice** is identifiable: the minimal contiguous task set that
|
|
75
|
+
satisfies the spec's core acceptance criteria and is shippable on its own. Everything past the slice
|
|
76
|
+
is incremental.
|
|
77
|
+
|
|
78
|
+
Gate: a complete dependency order with no cycle, and an explicitly marked MVP slice.
|
|
79
|
+
|
|
80
|
+
## Phase 4 — Bijection proof & write · gate: BLOCK
|
|
81
|
+
|
|
82
|
+
Cross the ledger against the task set, both directions. **This proves the plan and the ledger AGREE
|
|
83
|
+
with each other — it does not prove the ledger itself is COMPLETE relative to the spec's stated
|
|
84
|
+
intent.** A criterion missing from the ledger entirely was never a candidate for either check below;
|
|
85
|
+
that completeness gap is caught earlier, by Phase 1's `uncovered_intent` backstop (and by
|
|
86
|
+
`brainstorming` Phase 3 before that) — never re-derived here, and never implied by this phase's name
|
|
87
|
+
(#566: a prior version of this gate read "coverage proof", which a bijective check does not earn).
|
|
88
|
+
|
|
89
|
+
- Every `AC-NN` is covered by at least one task's `covers`. An uncovered criterion blocks — author the missing task.
|
|
90
|
+
- Every task advances at least one `AC-NN`. A task that covers nothing is scope creep — cut it or surface it.
|
|
91
|
+
|
|
92
|
+
Then write the plan to `<project-root>/.codearbiter/plans/<slug>.md` — `<slug>` matching the
|
|
93
|
+
spec — with the `AC-NN` ledger, the ordered task table (id · path(s) · verification · maps-to ·
|
|
94
|
+
covers · depends-on · **status**, initialized `PENDING`), the marked MVP slice, and any out-of-scope
|
|
95
|
+
item tagged inline `[NEEDS-TRIAGE]`.
|
|
96
|
+
|
|
97
|
+
The status column is the pipeline's resume ledger: `subagent-driven-development` flips a task to
|
|
98
|
+
`ACCEPTED` the moment it accepts it, so an interrupted run (crash, compaction, closed session) is
|
|
99
|
+
re-entered by `/feature` at the first non-`ACCEPTED` task instead of restarted from brainstorming.
|
|
100
|
+
|
|
101
|
+
Gate: bijection proven between the plan and the ledger — no criterion without a task, no task without
|
|
102
|
+
a criterion — and the plan written to disk. This proves the two are mutually consistent, nothing more;
|
|
103
|
+
completeness of the ledger itself was Phase 1's gate, not this one. This clears the path to execution:
|
|
104
|
+
`executing-plans` (checkpointed, via `/feature`) or `subagent-driven-development` (autonomous, via
|
|
105
|
+
`/sprint`) — each routes every task through `tdd`. The plan never hands off to `tdd` directly.
|
|
106
|
+
|
|
107
|
+
### Phase 4-farm extension (only when `--farm` was requested)
|
|
108
|
+
|
|
109
|
+
When `--farm` was requested, after the bijective coverage gate passes and the `.md` plan is written,
|
|
110
|
+
produce the farm artifact (`plan.json`) — **one MVP slice at a time** — per
|
|
111
|
+
`<plugin-root>/routines/writing-plans/references/farm-plan.md`. Load that leaf and follow it;
|
|
112
|
+
it owns the per-task failing-test + schema-valid `plan.json` procedure.
|
|
113
|
+
|
|
114
|
+
Gate: all failing tests written and confirmed failing; `plan.json` written and schema-valid. Both
|
|
115
|
+
artifacts exist before handing off to `subagent-driven-development` (`<plugin-root>/routines/subagent-driven-development/SKILL.md`).
|
|
116
|
+
|
|
117
|
+
## Hard rules
|
|
118
|
+
|
|
119
|
+
- MUST NOT plan against an absent or unapproved spec — STOP and route back to `/feature`.
|
|
120
|
+
- MUST NOT emit a task without an exact path AND a concrete verification step.
|
|
121
|
+
- MUST NOT let a task's verification stand in for a `tdd` gate — it maps to a tdd obligation, it does not replace one.
|
|
122
|
+
- MUST NOT write the plan while any acceptance criterion is uncovered or any task covers nothing.
|
|
123
|
+
- MUST NOT guess a verification command — cite `tech-stack.md` or STOP.
|
|
124
|
+
- MUST NOT resolve an ambiguous criterion by guessing — raise a `[CONFIRM-NN]`.
|
|
125
|
+
- MUST run the `uncovered_intent` backstop and ask the negative-judgment question in Phase 1, and MUST NOT treat Phase 4's bijection proof as a substitute — bijection proves the plan and the ledger agree with each other, never that the ledger is complete (#566).
|
|
126
|
+
- MUST NOT emit `plan.json` in `--farm` mode without writing and confirming each failing test first.
|
|
127
|
+
- MUST NOT set `meta.model` or `meta.apiBaseUrl` in `plan.json` — these belong to the dispatch step.
|
|
128
|
+
- MUST NOT proceed with `--farm` if `FARM_API_KEY` is absent — cite `<plugin-root>/includes/farm.md` and BLOCK.
|
|
129
|
+
- MUST, at exit, run the follow-up harvest (`<plugin-root>/includes/harvest.md`) over any `[NEEDS-TRIAGE]` out-of-scope items — batch-confirm promoting them to `open-tasks.md` (work) or `open-questions.md` (decisions) so they don't die in the plan file.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# writing-plans — `--farm` plan.json extension
|
|
2
|
+
|
|
3
|
+
Loaded by `writing-plans` Phase 4 only when `--farm` was requested. The base plan (Phases 1–4) is
|
|
4
|
+
unchanged; this leaf adds the machine artifact the farm dispatcher needs.
|
|
5
|
+
|
|
6
|
+
After the bijective coverage gate passes and the `.md` plan is written, produce the farm artifact —
|
|
7
|
+
**one MVP slice at a time, not the whole plan up front.** Front-loading every failing test for the
|
|
8
|
+
entire plan would be the waterfall this skill otherwise rejects (Phase 3), and it maximizes the cost
|
|
9
|
+
of a mid-flight spec change. So the farm artifact is scoped to the **current slice** (the MVP slice on
|
|
10
|
+
the first pass; the next contiguous group on later passes). For each task in the current slice, in
|
|
11
|
+
dependency order:
|
|
12
|
+
|
|
13
|
+
1. Route through `tdd` Phase 1 (derive obligations) + Phase 2 (write the failing test). The test file
|
|
14
|
+
must exist on disk and fail before continuing. Record the test file path for this task.
|
|
15
|
+
2. Confirm the test is actually failing (run the gate command from `tech-stack.md`; it must exit
|
|
16
|
+
non-zero). A test that passes before implementation means the obligation is wrong — STOP and revisit
|
|
17
|
+
Phase 2.
|
|
18
|
+
|
|
19
|
+
Then write `<project-root>/.codearbiter/plans/<slug>.plan.json` (the current slice's tasks only)
|
|
20
|
+
conforming to `<plugin-root>/tools/plan.schema.json`:
|
|
21
|
+
|
|
22
|
+
- `meta.name` ← slug
|
|
23
|
+
- `meta.repo` ← project name from CONTEXT.md
|
|
24
|
+
- `meta.model` and `meta.apiBaseUrl` — **leave unset**. These are written by
|
|
25
|
+
`subagent-driven-development`'s model research step at dispatch time. Writing them here would bake in
|
|
26
|
+
a potentially stale selection.
|
|
27
|
+
- Per task: `id` ← T-NN (normalized to kebab-case), `description` ← task description,
|
|
28
|
+
`filesInScope` ← path(s) from the task table, `test.path` ← the failing test written above,
|
|
29
|
+
`gate.commands` ← verification command from task table plus full-suite and lint/typecheck from
|
|
30
|
+
`tech-stack.md`, `deps` ← dependency ids (empty array if none), `context` ← a minimal slice of
|
|
31
|
+
relevant types/interfaces (omit if the test file plus task description is self-contained),
|
|
32
|
+
`maxRetries` ← omit to use the farm default.
|
|
33
|
+
- **`gate.commands[0]` MUST be the task's narrow behavioral test** (the command that runs just
|
|
34
|
+
`test.path`), with the full suite and lint/typecheck following. The farm's mutation guard re-runs
|
|
35
|
+
`gate.commands[0]` per mutant; if the first command were the full suite, mutation testing would be
|
|
36
|
+
prohibitively slow.
|
|
37
|
+
|
|
38
|
+
Validate the JSON against the schema before writing (load the schema from
|
|
39
|
+
`<plugin-root>/tools/plan.schema.json` and check). A schema-invalid plan BLOCKS.
|
|
40
|
+
|
|
41
|
+
`plan.schema.json` is the **authoring** contract. The dispatcher enforces its own **runtime** contract
|
|
42
|
+
(`PLAN_SHAPE` / `parsePlan()` in `farm.ts`) on the parsed JSON before it touches a single field, and
|
|
43
|
+
that one is authoritative: a plan that fails it exits before any worktree, branch, report, or network
|
|
44
|
+
call. The two are kept identical key-for-key and type-for-type by a parity test, so a plan that
|
|
45
|
+
satisfies the schema is accepted at runtime — with one deliberate exception, the kebab-case `id`
|
|
46
|
+
pattern, which is stricter here than the runtime path-safety rule. Both objects are closed: an
|
|
47
|
+
undeclared property is an error, not an ignored extra.
|
|
48
|
+
|
|
49
|
+
Gate: all failing tests written and confirmed failing; `plan.json` written and schema-valid. Both
|
|
50
|
+
artifacts exist before handing off to `subagent-driven-development`.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ca-add-dep
|
|
3
|
+
description: Vet a new or changed third-party dependency for license, provenance, and supply-chain risk before any install runs.
|
|
4
|
+
argument-hint: "<package[@version]>"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /ca-add-dep — dependency review
|
|
8
|
+
|
|
9
|
+
Gate a new or changed third-party dependency through review before it lands. When you route through
|
|
10
|
+
this command, the orchestrator runs no install until the `dependency-reviewer` agent clears the
|
|
11
|
+
package. Specify the exact version if you have one; without one, the reviewer evaluates the latest
|
|
12
|
+
available version.
|
|
13
|
+
|
|
14
|
+
## Routes to
|
|
15
|
+
|
|
16
|
+
The `dependency-reviewer` agent (`<plugin-root>/agents/dependency-reviewer.md`). The agent
|
|
17
|
+
reads `<project-root>/.codearbiter/security-controls.md` (allowed/denied licenses, provenance
|
|
18
|
+
and supply-chain policy) and `<project-root>/.codearbiter/tech-stack.md` (stack fit, dependency
|
|
19
|
+
manager) to judge the package.
|
|
20
|
+
|
|
21
|
+
After the agent clears it, the orchestrator surfaces the install command for confirmation. The lock
|
|
22
|
+
file change is committed alongside the manifest change — never one without the other.
|
|
23
|
+
|
|
24
|
+
## When NOT to use
|
|
25
|
+
|
|
26
|
+
- Removing a dependency → `/ca-fix` or `/ca-feature` with the change described.
|
|
27
|
+
- Updating an existing dependency as part of a code change → `/ca-feature` / `/ca-fix`; manifest
|
|
28
|
+
changes route to review at `/ca-pr`.
|
|
29
|
+
- Asking about a package without installing it → `/ca-btw`.
|
|
30
|
+
|
|
31
|
+
## Ephemeral tool run — one invocation, nothing adopted
|
|
32
|
+
|
|
33
|
+
A one-time developer tool is not a dependency, and reviewing it as one is what
|
|
34
|
+
issue #346 records going wrong: a duplicate-code investigation was interrupted
|
|
35
|
+
and pushed toward project-dependency review for `jscpd`, which the operator had
|
|
36
|
+
explicitly said must never be listed as a dependency. The redirect loop then
|
|
37
|
+
reached for `/ca-override`, a bypass invented to cover missing coverage. This
|
|
38
|
+
section is that coverage.
|
|
39
|
+
|
|
40
|
+
**The distinction is the dependency GRAPH, not the download.** Adopting or
|
|
41
|
+
changing anything that enters `package.json`, a lockfile, or a base image is the
|
|
42
|
+
review above, unchanged. Running a pinned tool once, against the repository,
|
|
43
|
+
adopting nothing, is this.
|
|
44
|
+
|
|
45
|
+
Route here when ALL of these hold. If any is unclear, it is a dependency and
|
|
46
|
+
takes the full review:
|
|
47
|
+
|
|
48
|
+
1. The operator asked for this specific tool, by name, in this session.
|
|
49
|
+
2. It runs ONCE, for inspection or analysis. It is not wired into a script, a
|
|
50
|
+
hook, or CI.
|
|
51
|
+
3. Nothing it does may change a manifest, a lockfile, or a committed artifact.
|
|
52
|
+
|
|
53
|
+
Then:
|
|
54
|
+
|
|
55
|
+
- **Pin the exact version.** `npx jscpd@4.0.5 .`, never bare `npx jscpd` — an
|
|
56
|
+
unpinned invocation resolves to whatever was published this morning, which is
|
|
57
|
+
the supply-chain exposure the review exists for and the one part of it that
|
|
58
|
+
still applies at full strength.
|
|
59
|
+
- **Use the approved registry.** `https://registry.npmjs.org` is the only one
|
|
60
|
+
(`security-controls.md`); no `git+`, no `file:`, no non-TLS source.
|
|
61
|
+
- **Confirm before running**, naming the exact command. One approval, not a
|
|
62
|
+
review — the operator has already made the adoption decision, which is "no".
|
|
63
|
+
- **Isolate what you can.** Prefer a cache directory under the system temp dir
|
|
64
|
+
over the project tree, and write any report there too, so the run leaves no
|
|
65
|
+
residue a later commit could pick up.
|
|
66
|
+
- **Report what ran** — the pinned command and where its output went.
|
|
67
|
+
|
|
68
|
+
**Hard gate: MUST NOT modify a manifest or a lockfile.** If the tool writes one,
|
|
69
|
+
that is adoption, and it stops here and routes to the review above. Verify
|
|
70
|
+
rather than trust: `git status --porcelain` over the manifest and lockfile paths
|
|
71
|
+
must be unchanged after the run. A tool that requires adoption to run at all is
|
|
72
|
+
a dependency, and saying so is the correct answer.
|
|
73
|
+
|
|
74
|
+
This is a bounded carve-out inside this command, not a command of its own
|
|
75
|
+
(ADR-0023). A new command would add a public surface — the catalog, the Pi
|
|
76
|
+
command catalog, the README counts, the site sidebar — to govern an action whose
|
|
77
|
+
whole definition is that it changes nothing.
|
|
78
|
+
|
|
79
|
+
## Hard gate
|
|
80
|
+
|
|
81
|
+
MUST NOT install before `dependency-reviewer` clears the package. BLOCK on a denied license or any
|
|
82
|
+
unresolved supply-chain or provenance concern.
|
|
83
|
+
|
|
84
|
+
This gate is **orchestrator-enforced, not hook-enforced**: unlike the crypto/secret gate
|
|
85
|
+
(`pre-bash.py` H-09b/H-10b), there is no pre-bash rule that blocks a bare `npm`/`pip`/`yarn`/`pnpm
|
|
86
|
+
install` typed outside this command. The discipline depends on routing installs through `/ca-add-dep`.
|
|
87
|
+
A hook-level install block (parallel to the security-gate marker) would be a stronger posture, but is a
|
|
88
|
+
deliberate behavior change — a possible future enhancement, not the current contract.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ca-adr
|
|
3
|
+
description: Author a numbered, dated, user-attributed Architecture Decision Record under .codearbiter/decisions/.
|
|
4
|
+
argument-hint: "<decision title>"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /ca-adr — author an ADR
|
|
8
|
+
|
|
9
|
+
Record an architectural decision as a numbered, dated ADR. Title the decision clearly — name what was
|
|
10
|
+
decided, not what was considered (`"Use PostgreSQL as the primary database"`, not
|
|
11
|
+
`"Database selection"`). This is the only sanctioned path to author an ADR.
|
|
12
|
+
|
|
13
|
+
## Routes to
|
|
14
|
+
|
|
15
|
+
The `decision-lifecycle` skill (`<plugin-root>/routines/decision-lifecycle/SKILL.md`). The skill
|
|
16
|
+
owns numbering, the file template, the `proposed → accepted → superseded | rejected` status lifecycle,
|
|
17
|
+
and writes the file to `<project-root>/.codearbiter/decisions/`. Status transitions require
|
|
18
|
+
explicit user instruction; the orchestrator never advances an ADR on its own.
|
|
19
|
+
|
|
20
|
+
## When NOT to use
|
|
21
|
+
|
|
22
|
+
- Check the health of existing ADRs → `/ca-adr-status`.
|
|
23
|
+
- Reconcile or challenge a suspect ADR → `/ca-reconcile`.
|
|
24
|
+
- Ask about a decision without recording it → `/ca-btw`.
|
|
25
|
+
|
|
26
|
+
## Hard gate
|
|
27
|
+
|
|
28
|
+
An ADR is authored ONLY via `/ca-adr` with explicit user attribution. MUST NOT author an ADR as the
|
|
29
|
+
disposition of a routine finding — decision-worthy findings surface to the user or to
|
|
30
|
+
`open-questions.md` as a `[CONFIRM-NN]`. MUST NOT resolve a `[CONFIRM-NN]` in the ADR by guessing.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ca-adr-status
|
|
3
|
+
description: Report the health of Architecture Decision Records — aged, unchallenged, supersession candidates, unresolved CONFIRM-NN. Read-only.
|
|
4
|
+
argument-hint: "(none) | --adr N"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /ca-adr-status — ADR health scan
|
|
8
|
+
|
|
9
|
+
Survey the health of recorded ADRs. Read-only — no file is modified. With `--adr N` the scan focuses
|
|
10
|
+
on a single ADR; with no argument it scans every ADR under
|
|
11
|
+
`<project-root>/.codearbiter/decisions/`.
|
|
12
|
+
|
|
13
|
+
## Routes to
|
|
14
|
+
|
|
15
|
+
The `decision-lifecycle` skill (`<plugin-root>/routines/decision-lifecycle/SKILL.md`) in its
|
|
16
|
+
health-scan mode. For each ADR it flags: aged decisions, `proposed` ADRs never challenged,
|
|
17
|
+
supersession candidates (a newer ADR or code pattern contradicts the decision), and unresolved
|
|
18
|
+
`[CONFIRM-NN]` placeholders. Findings aggregate into a structured report; nothing is changed.
|
|
19
|
+
|
|
20
|
+
## When NOT to use
|
|
21
|
+
|
|
22
|
+
- Author a new ADR → `/ca-adr`.
|
|
23
|
+
- Challenge or reconcile a specific ADR in depth → `/ca-reconcile`.
|
|
24
|
+
- Ask what a specific ADR says → `/ca-btw`.
|
|
25
|
+
|
|
26
|
+
## Hard gate
|
|
27
|
+
|
|
28
|
+
Read-only — MUST NOT modify any file. MUST NOT resolve a `[CONFIRM-NN]` found during the scan —
|
|
29
|
+
surface it and stop. A supersession candidate that contradicts an accepted ADR is flagged for
|
|
30
|
+
`/ca-conflict`.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ca-arbiter
|
|
3
|
+
description: Exit maintainer dev mode — restore orchestration, remove the dev marker, log the exit.
|
|
4
|
+
argument-hint: (none)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /ca-arbiter — restore orchestration
|
|
8
|
+
|
|
9
|
+
The exit door for `/ca-dev`. No-op if dev mode is not active.
|
|
10
|
+
|
|
11
|
+
## Flow
|
|
12
|
+
|
|
13
|
+
1. **Log exit** — append to `<project-root>/.codearbiter/overrides.log` (append-only, `>>`):
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
[ISO-8601 timestamp] | BY: <email> | DEV: exit
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
2. **Marker** — remove `<project-root>/.codearbiter/.markers/dev-active`.
|
|
20
|
+
3. **Resume** — re-present the startup state (stage, blocking `CONFIRM-NN`, in-flight tasks) and
|
|
21
|
+
await a slash command. Orchestration, routing, and all gates are back in force.
|
|
22
|
+
|
|
23
|
+
## Hard gate
|
|
24
|
+
|
|
25
|
+
MUST write the `DEV: exit` line to `overrides.log` and remove the `dev-active` marker before resuming
|
|
26
|
+
orchestration — the exit is on the audit trail like the entry. MUST NOT rewrite or truncate
|
|
27
|
+
`overrides.log` — the append-only rule has no dev exception, on entry or exit. If a prior session
|
|
28
|
+
ended mid-dev, SessionStart has already appended the synthetic `BY: session-cleanup | DEV: exit` close
|
|
29
|
+
line and cleared the marker (`session-start.py`, observability-001). In that case MUST NOT write a
|
|
30
|
+
second `DEV: exit` for that orphaned entry — the close is already on the trail.
|
|
31
|
+
|
|
32
|
+
Session-scoped clearing (#271): SessionStart's synthetic close is now conditional on the marker
|
|
33
|
+
plausibly being abandoned rather than owned by a different, still-live session — it will NOT clobber
|
|
34
|
+
another concurrently-running session's live `/dev` marker or write a false `DEV: exit` for it.
|
|
35
|
+
`/ca-arbiter` remains the ONLY way to cleanly close your OWN `/dev` session's audit pair; do not
|
|
36
|
+
rely on a future SessionStart to do it for you.
|