@arbiterforge/ca-pi 0.18.4 → 0.19.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/README.md +1 -1
- package/package.json +1 -1
- package/plugins/ca-pi/CHANGELOG.md +54 -0
- package/plugins/ca-pi/COMMANDS.md +2 -2
- package/plugins/ca-pi/SKILLS.md +5 -5
- package/plugins/ca-pi/SPRINT.md +43 -230
- package/plugins/ca-pi/agents/backend-author.md +5 -5
- package/plugins/ca-pi/agents/checkpoint-aggregator.md +7 -0
- package/plugins/ca-pi/agents/frontend-author.md +5 -5
- package/plugins/ca-pi/agents/infra-author.md +6 -7
- package/plugins/ca-pi/agents/scout.md +25 -24
- package/plugins/ca-pi/arbiter.md +6 -4
- package/plugins/ca-pi/generated/command-catalog.json +5 -5
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-darwin-amd64 +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-darwin-arm64 +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-linux-amd64 +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-linux-arm64 +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-windows-amd64.exe +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-windows-arm64.exe +0 -0
- package/plugins/ca-pi/helpers/artifacts/release.json +37 -37
- package/plugins/ca-pi/hooks/_approvallib.py +41 -0
- package/plugins/ca-pi/hooks/_artifactlib.py +61 -115
- package/plugins/ca-pi/hooks/_artifactpromptlib.py +12 -12
- package/plugins/ca-pi/hooks/_bashguardlib.py +66 -4
- package/plugins/ca-pi/hooks/_contextselectlib.py +38 -35
- package/plugins/ca-pi/hooks/_contextwriterlib.py +114 -0
- package/plugins/ca-pi/hooks/_host.py +1 -1
- package/plugins/ca-pi/hooks/_prerequisitelib.py +35 -0
- package/plugins/ca-pi/hooks/_provenancelib.py +107 -1
- package/plugins/ca-pi/hooks/_readinjectlib.py +21 -7
- package/plugins/ca-pi/hooks/_reconciliationlib.py +167 -2
- package/plugins/ca-pi/hooks/_releaselib.py +6 -6
- package/plugins/ca-pi/hooks/_sprintapprovallib.py +52 -2
- package/plugins/ca-pi/hooks/artifact-reconcile.py +13 -4
- package/plugins/ca-pi/hooks/hostapi.py +1 -1
- package/plugins/ca-pi/hooks/init-codearbiter.py +34 -5
- package/plugins/ca-pi/includes/artifacts-attestation.md +434 -0
- package/plugins/ca-pi/includes/artifacts.md +133 -492
- package/plugins/ca-pi/includes/author-tdd-workflow.md +32 -21
- package/plugins/ca-pi/includes/fresh-verification.md +14 -12
- package/plugins/ca-pi/includes/harvest.md +3 -3
- package/plugins/ca-pi/includes/reference-map.md +1 -1
- package/plugins/ca-pi/includes/routing-table.md +3 -3
- package/plugins/ca-pi/includes/sprint-authority.md +6 -1
- package/plugins/ca-pi/includes/verification-boundary.md +11 -2
- package/plugins/ca-pi/package.json +1 -1
- package/plugins/ca-pi/routines/INDEX.md +8 -8
- package/plugins/ca-pi/routines/brainstorming/SKILL.md +65 -202
- package/plugins/ca-pi/routines/commit-gate/SKILL.md +60 -25
- package/plugins/ca-pi/routines/context-check/SKILL.md +89 -53
- package/plugins/ca-pi/routines/context-creation/SKILL.md +114 -220
- package/plugins/ca-pi/routines/decompose/SKILL.md +139 -167
- package/plugins/ca-pi/routines/executing-plans/SKILL.md +38 -136
- package/plugins/ca-pi/routines/finishing-a-development-branch/SKILL.md +45 -55
- package/plugins/ca-pi/routines/refactor/SKILL.md +27 -12
- package/plugins/ca-pi/routines/release/SKILL.md +1 -1
- package/plugins/ca-pi/routines/subagent-driven-development/SKILL.md +80 -230
- package/plugins/ca-pi/routines/tdd/SKILL.md +115 -228
- package/plugins/ca-pi/routines/writing-plans/SKILL.md +104 -174
- package/plugins/ca-pi/skills/ca-audit/SKILL.md +2 -2
- package/plugins/ca-pi/skills/ca-checkpoint/SKILL.md +1 -1
- package/plugins/ca-pi/skills/ca-commit/SKILL.md +60 -25
- package/plugins/ca-pi/skills/ca-context-check/SKILL.md +89 -53
- package/plugins/ca-pi/skills/ca-create-context/SKILL.md +114 -220
- package/plugins/ca-pi/skills/ca-decompose/SKILL.md +139 -167
- package/plugins/ca-pi/skills/ca-feature/SKILL.md +21 -38
- package/plugins/ca-pi/skills/ca-fix/SKILL.md +15 -9
- package/plugins/ca-pi/skills/ca-init/SKILL.md +18 -40
- package/plugins/ca-pi/skills/ca-pr/SKILL.md +45 -55
- package/plugins/ca-pi/skills/ca-refactor/SKILL.md +27 -12
- package/plugins/ca-pi/skills/ca-release/SKILL.md +1 -1
- package/plugins/ca-pi/skills/ca-review/SKILL.md +5 -8
- package/plugins/ca-pi/skills/ca-sprint/SKILL.md +11 -25
- package/plugins/ca-pi/skills/ca-status/SKILL.md +15 -6
|
@@ -45,14 +45,14 @@ branch-finish request, assemble state and ask for the terminal choice, not a com
|
|
|
45
45
|
An already-recorded explicit choice remains effective for its unchanged scope;
|
|
46
46
|
revalidate evidence, not the wording of the user's request.
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
PR creation and terminal actions below require applicable current-head verification.
|
|
49
49
|
Watch and cleanup return from their own paths before reaching that requirement.
|
|
50
50
|
|
|
51
51
|
## Pre-flight
|
|
52
52
|
|
|
53
53
|
Read these, or STOP and surface the gap — never guess the branch name or the default branch:
|
|
54
54
|
|
|
55
|
-
- `<project-root>/.codearbiter/CONTEXT.md` — the
|
|
55
|
+
- `<project-root>/.codearbiter/CONTEXT.md` — project context. Resolve the working branch and default target from Git or repository metadata.
|
|
56
56
|
- The discovered authoritative spec/plan pair for the pipeline, when `/feature`
|
|
57
57
|
or `/sprint` produced one. Use the exact selected `.md` or `.html` plan as the
|
|
58
58
|
yardstick for "is the work complete." Re-run the private bridge resolver
|
|
@@ -61,23 +61,21 @@ Read these, or STOP and surface the gap — never guess the branch name or the d
|
|
|
61
61
|
for HTML and obtain HTML plan state only through the installed engine
|
|
62
62
|
`identity`, `index`, and symbol-scoped `read` operations. The finishing step
|
|
63
63
|
must not create, convert, or consult a counterpart.
|
|
64
|
-
-
|
|
64
|
+
- The observed commit/check results for this branch: checked source identity, commands and cwd, outcomes, and applicable review findings.
|
|
65
65
|
- `<plugin-root>/includes/verification-boundary.md` — the exact-head hosted-CI evidence required before merge.
|
|
66
66
|
|
|
67
|
-
For an HTML pair, query
|
|
68
|
-
recreation
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
For an HTML pair, query `identity` and `eligible` after process
|
|
68
|
+
recreation and read the actual work and check results. `eligible` is advisory
|
|
69
|
+
scheduling; `DONE` means implementation progress, not a verified release.
|
|
70
|
+
Report unfinished work, missing or failing tests, and any outstanding
|
|
71
|
+
decisions, rather than requiring an artifact acceptance receipt simply to
|
|
72
|
+
prepare or open an authorized PR. Do not scrape HTML or invent receipts.
|
|
73
|
+
`_preflight_current_acceptance` remains an **explicit historical proof query**,
|
|
74
|
+
not the mandatory permission gate for opening a PR or preparing a branch.
|
|
75
|
+
Real Git/host authorization, current applicable check results, independent security
|
|
76
|
+
controls and exact-head hosted CI before merge still apply.
|
|
73
77
|
|
|
74
|
-
|
|
75
|
-
`_preflight_current_acceptance` with the exact `_resolve_workflow_pair` result,
|
|
76
|
-
repository-bound client, and engine-returned spec/plan IDs. Carry its returned
|
|
77
|
-
identity/receipt proof into state assembly. Any refusal blocks terminal options;
|
|
78
|
-
do not recreate the proof from the PR description, checkpoint prose, or labels.
|
|
79
|
-
|
|
80
|
-
`commit-gate` MUST have cleared on the current HEAD. If it has not, this skill does not run — return to it.
|
|
78
|
+
Establish applicable verification for the current HEAD. Reuse observed results whose checked source and inputs still match. For a committed branch, derive paths and obligations from the explicit base-to-HEAD diff and run missing or affected checks under `verification-boundary.md`, followed by the review matrix below. Bind secrets scanning and specialized security/migration checks to that same base-to-HEAD subject. An empty staged set does not establish branch coverage. Report these read-only readiness results without creating commit markers. This verification does not invoke commit-only phases or create a commit. Authorized uncommitted work uses `commit-gate` before delivery.
|
|
81
79
|
|
|
82
80
|
## Phase 1 — State assembly · gate: BLOCK
|
|
83
81
|
|
|
@@ -85,7 +83,7 @@ Assemble the facts the decision needs. Nothing is presented until all are in han
|
|
|
85
83
|
|
|
86
84
|
- **Branch** — the current branch name and its base. Confirm it is NOT the default branch; if HEAD is the default branch, STOP — there is nothing to finish and merge-to-default is forbidden.
|
|
87
85
|
- **Diff summary** — files changed, insertions/deletions, and the commit list since the base. Read it, do not paraphrase from memory.
|
|
88
|
-
- **
|
|
86
|
+
- **Check results** — observed commands, source identity, outcomes and relevant review conclusions for the current HEAD. Mark missing or inapplicable evidence as pending. Surface any open `[NEEDS-TRIAGE]` findings.
|
|
89
87
|
- **Plan delta** — when a plan exists, state which plan items the branch satisfied and which remain open. Open items are surfaced, not hidden.
|
|
90
88
|
- **ADR source ancestry** — when `.codearbiter/decisions/adr-lifecycle.jsonl` exists, select
|
|
91
89
|
the merge method from the exact fetched target commit and PR head commit. Run the installed verifier:
|
|
@@ -199,18 +197,27 @@ contributor-source, native-qualification and no-bypass requirements above apply.
|
|
|
199
197
|
### Open-PR procedure
|
|
200
198
|
|
|
201
199
|
Run this procedure only for the selected open-PR or merge-via-PR action, after the
|
|
202
|
-
current-head
|
|
200
|
+
current-head verification and authorized commit handling. It is shared by direct PR requests
|
|
203
201
|
and caller handoffs; it is not a second host-command invocation.
|
|
204
202
|
|
|
205
|
-
1. **Confirm the commit
|
|
206
|
-
2. **
|
|
203
|
+
1. **Confirm current-head readiness** from the applicable observed checks and review assembled in Phase 1. If a commit is needed, use `commit-gate` under the existing authorization.
|
|
204
|
+
2. **Review coverage** — inspect the base-to-HEAD diff and identify the required review subjects:
|
|
207
205
|
- auth / crypto / middleware paths → `auth-crypto-reviewer` + `security-reviewer`
|
|
206
|
+
- CI / deployment / infrastructure paths → `security-reviewer`
|
|
208
207
|
- migration files → `migration-reviewer`
|
|
209
208
|
- dependency manifests → `dependency-reviewer`
|
|
210
|
-
-
|
|
211
|
-
|
|
209
|
+
- executable source or verification-contract changes → `coverage-auditor`
|
|
210
|
+
- prose-only changes → applicable documentation/reference checks
|
|
211
|
+
Reuse inspected review conclusions when their source, requirements, findings and
|
|
212
|
+
verification inputs still cover this subject. A commit, PR handoff or new receipt
|
|
213
|
+
identity alone does not require redispatch. A newly failing check or relevant edit
|
|
214
|
+
requires reassessing the affected conclusions. Honor an explicit request for a
|
|
215
|
+
fresh independent review.
|
|
216
|
+
3. **Run missing or affected reviews** in parallel where there are no dependencies.
|
|
217
|
+
If existing reviews cover every required subject, proceed with those results.
|
|
212
218
|
4. **BLOCK check** — any CRITICAL or HIGH finding STOPs the flow; present it and do not draft the PR.
|
|
213
|
-
Correct within existing scope and authority, then
|
|
219
|
+
Correct within existing scope and authority, then rerun affected checks and reviews.
|
|
220
|
+
Reuse unaffected evidence and invoke commit handling only for changes needing a commit.
|
|
214
221
|
Do not require the user to repeat command spellings; no unresolved blocker is waived.
|
|
215
222
|
5. **Stage the PR** once all BLOCK findings clear: concise title; summary of what changed and why; a
|
|
216
223
|
bulleted test plan; a conflict-hierarchy tradeoff citation for any non-obvious tradeoff; a link to
|
|
@@ -231,39 +238,22 @@ and caller handoffs; it is not a second host-command invocation.
|
|
|
231
238
|
`/ca-watch <new-PR>`. When `enabled` is false, do nothing here — the user can still run `/ca-watch`
|
|
232
239
|
ad-hoc. Never enable the flag on the user's behalf.
|
|
233
240
|
|
|
234
|
-
## Phase 4 —
|
|
235
|
-
|
|
236
|
-
The loop has been a chain of gates the user watched clear. End it on its most rewarding beat, not in
|
|
237
|
-
silence. Emit a tight **Receipt** — a win summary that reflects the prevention back, drawn ONLY from
|
|
238
|
-
the state Phase 1 already assembled plus `<project-root>/.codearbiter/last-checkpoint`. This is
|
|
239
|
-
**not a fresh audit-trail crawl** — no new log scan, no `git` archaeology. If a field has no data in
|
|
240
|
-
hand, omit the line rather than go digging.
|
|
241
|
-
|
|
242
|
-
Report only what the assembled state supports:
|
|
243
|
-
|
|
244
|
-
- **Obligations covered** — the count of `tdd` obligations that reached `COVERED` on this branch.
|
|
245
|
-
- **Gates that fired and what each caught** — the gates that BLOCKed and then cleared, named with the
|
|
246
|
-
specific thing caught (an untested seam, a scope-creep file set aside), not a bare gate name.
|
|
247
|
-
- **SMARTS decisions the user made** — the architectural forks the user resolved, one line each.
|
|
248
|
-
- **Secrets / regressions prevented** — credential findings and behavioral-proof mismatches the gates
|
|
249
|
-
stopped before they shipped.
|
|
250
|
-
- **Suite time** — the wall-clock of the verifying run, from the gate results in hand.
|
|
251
|
-
|
|
252
|
-
Close with **exactly one** warm, synthesizing sentence (per the orchestrator register) that reflects
|
|
253
|
-
the run back — synthesized for this branch, not the register's canned example. One sentence, earned,
|
|
254
|
-
never on a no-op close.
|
|
241
|
+
## Phase 4 — Delivery report
|
|
255
242
|
|
|
256
|
-
|
|
257
|
-
|
|
243
|
+
Use the Phase 1 state and the observed action result. Report the commit/PR identity,
|
|
244
|
+
implemented scope, applicable checks and review outcomes, and remaining work.
|
|
245
|
+
Include suite time when observed. Keep implementation, verification, merge and
|
|
246
|
+
publication distinct. Do not perform a fresh audit-trail crawl to embellish the
|
|
247
|
+
report or infer verification from a checkpoint counter.
|
|
258
248
|
|
|
259
249
|
## Hard rules
|
|
260
250
|
|
|
261
|
-
-
|
|
262
|
-
-
|
|
263
|
-
- MUST NOT
|
|
264
|
-
- MUST NOT
|
|
265
|
-
- MUST NOT
|
|
266
|
-
-
|
|
267
|
-
-
|
|
268
|
-
-
|
|
269
|
-
-
|
|
251
|
+
- Preserve the selected branch and exact reviewed head; every merge goes through a PR.
|
|
252
|
+
- Merge requires explicit authorization. Never force-push.
|
|
253
|
+
- MUST NOT auto-merge under `/sprint`; its terminal action is an open PR.
|
|
254
|
+
- MUST NOT discard a branch without explicit user confirmation naming it.
|
|
255
|
+
- MUST NOT delete un-pushed commits silently.
|
|
256
|
+
- Required current-head checks and review must pass before claiming readiness. Missing evidence stays pending.
|
|
257
|
+
- Merge requires the repository's passing merge-readiness aggregate for the PR's current exact head.
|
|
258
|
+
- Read branch and target identities from Git; do not guess them.
|
|
259
|
+
- Report only observed actions and applicable evidence.
|
|
@@ -8,13 +8,13 @@ argument-hint: "<surface and motivation>"
|
|
|
8
8
|
|
|
9
9
|
Select this owning procedure for a behavior-preserving restructure, whether requested
|
|
10
10
|
in plain language or through `/refactor`. Entry syntax is not an additional gate;
|
|
11
|
-
the
|
|
11
|
+
the authorized scope, parity, and verification requirements below still apply.
|
|
12
12
|
Externally observable behavior before equals after, proven rather than assumed.
|
|
13
13
|
|
|
14
14
|
## Entry boundaries
|
|
15
15
|
|
|
16
16
|
- Identify both the surface and the motivation. Phase 1 owns the precise surface
|
|
17
|
-
table
|
|
17
|
+
table under existing authorization. Ask only about a missing consequential scope decision.
|
|
18
18
|
- New behavior, including a new error path, side effect, or public method beyond
|
|
19
19
|
a Phase 3 seam, belongs to `/feature`. Incorrect existing behavior belongs to `/fix`.
|
|
20
20
|
- An explanation-only question stays in the non-mutating question-answer path,
|
|
@@ -36,7 +36,9 @@ The working tree MUST be clean over the named surface before Phase 1. A dirty su
|
|
|
36
36
|
|
|
37
37
|
## Phase 1 — Surface identification · gate: BLOCK
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
Inspect the requested refactor and record its precise surface before restructuring.
|
|
40
|
+
Present the table and continue when the existing request covers it; no second
|
|
41
|
+
signoff is required. Ask only about a genuinely unresolved scope or outcome:
|
|
40
42
|
|
|
41
43
|
- Files (repo-relative paths).
|
|
42
44
|
- Top-level symbols touched — function, class, and exported member names.
|
|
@@ -45,7 +47,10 @@ Enumerate the exact blast radius before any other work. Restate the planned refa
|
|
|
45
47
|
|
|
46
48
|
Reject vague surfaces. "the auth module", "the user service", "some helpers in utils" are categories, not surfaces. A surface is acceptable only when a reader could grep the repo for the listed symbols and arrive at the same file set. The table is the parity contract for Phases 2–6.
|
|
47
49
|
|
|
48
|
-
Gate: a precise, complete surface table
|
|
50
|
+
Gate: a precise, complete surface table covered by existing user authorization.
|
|
51
|
+
Resolve category-level requests through source inspection where their outcome is
|
|
52
|
+
clear. Ask only when inspection exposes a consequential missing choice. Include
|
|
53
|
+
necessary consumer updates within the requested restructure and record their scope.
|
|
49
54
|
|
|
50
55
|
## Phase 2 — Behavioral parity coverage proof · gate: BLOCK
|
|
51
56
|
|
|
@@ -65,7 +70,7 @@ Where the surface has no coverage tooling, take the no-tooling exemption in
|
|
|
65
70
|
section that omits a command for this surface — and the per-symbol direct-test proof stands alone.
|
|
66
71
|
Without that citation the phase STOPs rather than passing on an unverifiable claim.
|
|
67
72
|
|
|
68
|
-
If surface coverage is below the maturity threshold on any required metric,
|
|
73
|
+
If surface coverage is below the maturity threshold on any required metric, or a public method has no direct test, use the characterization/backfill approach in `<plugin-root>/routines/tdd/SKILL.md`. Add tests for the existing behavior and run them before restructuring; initially passing tests establish the baseline. Use a meaningful isolated negative control where needed to check the oracle. Record the passing post-backfill baseline, including test identities and assertions. Resume with that measured coverage and preserve the baseline assertions through implementation.
|
|
69
74
|
|
|
70
75
|
Gate: surface coverage at or above the maturity threshold on every required metric in the declared coverage profile, the shared critical-path evidence present, AND every public method backed by a direct test. Otherwise backfill via `tdd` Phase 1 before retrying.
|
|
71
76
|
|
|
@@ -83,29 +88,39 @@ Apply the restructure with zero behavior change, to the conventions in `coding-s
|
|
|
83
88
|
|
|
84
89
|
Unacceptable inside a refactor: adding a behavior, branch, error path, or side effect; changing the value any public method returns for any pre-existing input; adding a public method beyond a Phase 3 seam; changing observable order of operations (event emission, logging, IO). Classify the resulting staged diff against `commit-gate` classification criteria — a diff that classifies as `feat` is not a refactor; halt and route to `tdd`.
|
|
85
90
|
|
|
86
|
-
Gate: the refactor
|
|
91
|
+
Gate: the refactor remains within the authorized outcome, with any Phase 3 seam
|
|
92
|
+
tests now green. Maintain the surface table for discovered consumer updates within
|
|
93
|
+
that scope. BLOCK if the diff classifies as `feat` or requires a scope expansion
|
|
94
|
+
without the actual owner's authorization.
|
|
87
95
|
|
|
88
96
|
## Phase 5 — Parity verification · gate: BLOCK
|
|
89
97
|
|
|
90
|
-
Run
|
|
98
|
+
Run the impact-bounded parity tests recorded in the post-backfill Phase 2 baseline,
|
|
99
|
+
following `verification-boundary.md`. Compare test changes made during implementation
|
|
100
|
+
against that baseline, including characterization cases added to existing test files.
|
|
101
|
+
Preserve their assertions. Necessary import or symbol-reference updates must retain
|
|
102
|
+
the same behavioral oracle. If implementation requires changing an expected result,
|
|
103
|
+
resolve the behavior change through the feature or fix owner. Phase 3 seam tests
|
|
104
|
+
must also pass. Record current results and any permitted mechanical test changes.
|
|
91
105
|
|
|
92
|
-
Gate:
|
|
106
|
+
Gate: baseline parity and new seam checks pass with preserved behavioral assertions.
|
|
107
|
+
The exhaustive pre-existing suite remains an exact-head hosted-CI merge requirement.
|
|
93
108
|
|
|
94
109
|
## Phase 6 — Lint and coverage · gate: BLOCK
|
|
95
110
|
|
|
96
111
|
Run lint, the type-check if the project is statically typed, and coverage, all from `tech-stack.md`. Resolve every lint and type error. Confirm surface coverage remains at or above the maturity threshold on every required metric in the same declared coverage profile. A refactor MUST NOT reduce coverage of the surface it touched on any required metric or drop its critical-path evidence.
|
|
97
112
|
|
|
98
|
-
Where the surface has no coverage tooling, the same clause as Phase 2 applies — the no-tooling exemption in `<plugin-root>/includes/maturity-coverage.md`, citation included — and parity is verified through Phase 5's
|
|
113
|
+
Where the surface has no coverage tooling, the same clause as Phase 2 applies — the no-tooling exemption in `<plugin-root>/includes/maturity-coverage.md`, citation included — and parity is verified through Phase 5's post-backfill baseline and preserved behavioral assertions. Phase 2 and Phase 6 MUST NOT give different answers about the same surface, which is why both defer to the one shared clause rather than restating its conditions.
|
|
99
114
|
|
|
100
115
|
Gate: clean lint and type-check, zero errors, and no coverage regression on the named surface. "Mostly passes" is not passing — this is what clears the path to `commit-gate`.
|
|
101
116
|
|
|
102
117
|
## Hard rules
|
|
103
118
|
|
|
104
|
-
- MUST
|
|
119
|
+
- MUST identify the precise surface and existing authorization before Phase 2; do not request duplicate signoff.
|
|
105
120
|
- MUST NOT proceed past Phase 2 if surface coverage is below the maturity threshold or any public method has zero direct tests — route to `tdd` Phase 1 to backfill.
|
|
106
121
|
- MUST NOT introduce new behavior in Phase 4. A diff that classifies as `feat` under `commit-gate` is not a refactor.
|
|
107
|
-
- MUST NOT
|
|
122
|
+
- MUST NOT weaken a baseline assertion to make the refactor pass. Mechanical test-reference changes must preserve the behavioral oracle.
|
|
108
123
|
- MUST NOT reduce coverage of the named surface during the refactor.
|
|
109
|
-
- MUST
|
|
124
|
+
- MUST keep the surface table current and obtain authorization for a material scope expansion or changed outcome.
|
|
110
125
|
- MUST NOT inline-suppress a lint rule to clear Phase 6, and never to bypass a security-relevant rule.
|
|
111
126
|
- MUST NOT guess the test, coverage, lint, or type-check command — read `tech-stack.md` or STOP.
|
|
@@ -342,7 +342,7 @@ Derive the bump mechanically from the commit log; do not guess it.
|
|
|
342
342
|
**For the footer-completeness rule below, an accepted `[RECONCILED]` row counts as footer-complete.** That is not an auto-fill or a relaxation for ordinary missing footers: it is an explicit repository declaration bound to one exact commit already on the freshly fetched default branch, and every unlisted or unprovable commit remains `[NEEDS-TRIAGE]`. An unpublished commit must be amended or rebased instead and MUST NOT be added to the ledger. A reconciliation for a published commit lands through a normal reviewed commit, after which this lane restarts so its clean-tree and fresh-origin gates cover the policy change. When step 5 composes the changelog, it uses the exact helper-printed reconciliation text in the group selected by the commit's unchanged type; it does not reword or re-derive the note.
|
|
343
343
|
3. **Verify footer completeness for the already-established `$EFFECTIVE_WINDOW` before touching anything else — never after.** On a first release, step 0 has already proposed and confirmed the adoption floor before classification; do not classify the raw full-history `$WINDOW` first and then try to narrow it here. The sole sanctioned exception is Back-fill's own canonical first-release shape (step 0's note, step 1's check): there, `$EFFECTIVE_WINDOW` may still be substituted to `HEAD` at step 1, but only through that step's OWN presented confirm-or-replace gate, before this step ever runs — a confirmed widen at the documented point of use, not an unconfirmed narrowing performed HERE. `adoption-commit` takes the oldest line of its newest-first input, so considering both candidate files identifies whichever adoption happened first. The confirmed boundary commit itself remains included, including when it is the root commit. Over that effective window, every `feat`/`fix`/`perf`/`refactor` commit (the full harvested set step 5 rolls into the changelog, not just `feat`/`fix`) MUST carry a `CHANGELOG:` footer. **This obligation is wider than those four types, regardless of type: any commit `classify_commit` marks `breaking` — an unfootered `chore!:`, `docs!:`, `test!:`, or `ci!:` included — is caught here too**, because `classify_window`'s `missing_footer` set keys on each row's own `bump != "none"`, not a fixed type list, so a footer-incomplete breaking commit of any type is already BLOCKed at this step, before step 5 ever composes a changelog. **A missing footer on any one of them is a BLOCK**, not a soft finding: surface EVERY offending commit as its own `[NEEDS-TRIAGE]` line in the release report presented to the user (one line per commit missing the footer, `<short-sha> <subject>` — never a single collapsed `[NEEDS-TRIAGE]` when more than one commit is at fault, and never written to any file: the report is its only destination) and STOP here — never auto-fill it, and never tag a changelog that silently drops a user-visible change. **The remedy is the operator's to choose:** first check whether the commit is already published with `git -C "$PROJECT_ROOT" merge-base --is-ancestor <sha> "origin/$DEFAULT_BRANCH"`. An unpublished commit may be amended or rebased; a published one must not be rewritten or force-pushed. If a listed commit genuinely has nothing user-facing to say, reclassify its type instead of leaving it half-classified. Never invent footer text on the author's behalf. Checking before step 4 bumps any file means a blocked release leaves no partial manifest bump. A `CHANGELOG:` footer on a `test`/`docs`/`chore`/`ci` commit is harvested by step 5 rather than silently discarded, but does not by itself create a bump.
|
|
344
344
|
4. **Apply the step-2 classification to `$BASE_VERSION` through the policy-aware helper, never by eye.** Capture step 2's first line verbatim as `$BUMP`. For `LAST_TAG=<none>` with the numeric-sequence manifest exactly at `$INITIAL_VERSION`, run `DERIVATION_BASE="<none>"; COMPARISON_BASE="<none>"`; otherwise run `DERIVATION_BASE=$BASE_VERSION; COMPARISON_BASE=$BASE_VERSION`. Then run `VERSION=$("$PY" "<plugin-root>/hooks/_releaselib.py" derive-version "$DERIVATION_BASE" "$BUMP" "$VERSION_POLICY" "$INITIAL_VERSION")` and set `RELEASE_TAG=${TAG_PREFIX}${VERSION}` once for every later tag, notes, asset, and publication command. This preserves SemVer's patch/minor/major arithmetic while `numeric-sequence` advances its final component exactly once for any bumping classification; `none`, an unknown policy, or an invalid base STOPs. Confirm the result mechanically with `"$PY" "<plugin-root>/hooks/_releaselib.py" version-greater "$VERSION" "$COMPARISON_BASE" "$VERSION_POLICY" "$INITIAL_VERSION"`. The helper treats `<none>` as the empty numeric sequence only for this first-release comparison. Exit 1 means equal or lower; exit 2 means policy-invalid input. For compatibility, this is the policy-general replacement for the legacy `semver-greater <derived> $BASE_VERSION` check and keeps its remedy: re-derive from `$BASE_VERSION` rather than raising the bump. `$BASE_VERSION` already accounts for the tag and every manifest, including the first-release sentinel case. Bringing every manifest to the derived version still happens once in step 6; describing that write here too would be one action described two ways. Present the version and per-commit classification to the user for confirmation.
|
|
345
|
-
5. Derive the release date **once** — `RELEASE_DATE=$(date +%F)` — and reuse that single value for the changelog header, the Phase-2 `Released-at:` footer, and the Phase-3 Release; never hand-type the date a second time (`release_dates_consistent` verifies the changelog-header date equals the `Released-at:` date). Roll the `CHANGELOG:` footers from each `feat` / `fix` / `perf` / `refactor` commit into a new `## [${VERSION}] — $RELEASE_DATE` section in `$CHANGELOG` (the Keep-a-Changelog bracket heading this guard matches, not the bare `v`-prefixed form), grouped Added (`feat`) / Fixed (`fix`) / Performance (`perf`) / Changed (`refactor`, matching this repository's own changelog convention for non-user-facing-but-notable work). **A commit whose classification marks `breaking` true — the `!` bang after the type/scope or a `BREAKING CHANGE:`/`BREAKING-CHANGE:` footer, exactly the flag `classify-window` already computes and never re-derived here — rolls into its own `### Breaking` group instead of its type group, placed first among the section's groups.** A `feat!` no longer lands under `### Added` indistinguishable from an ordinary feature, and a breaking `chore!:` (which has no type group of its own) still gets one; an ordinary nonbreaking commit is never placed in `### Breaking`, and a commit already in `### Breaking` is never also duplicated into its type group. This is the same composed section text Phase 2's `<message-file>` and Phase 3's `<Phase-1 section file>` both read back (below), so `### Breaking` is visible in the changelog, the tag message, and the Release notes without a second composition pass. **Also harvest a `CHANGELOG:` footer from any `test`/`docs`/`chore`/`ci` commit that carries one**, into the same section's Changed group: its type says "not user-visible" but its footer is the more specific, deliberately-authored signal, and dropping it because of the type would be exactly the silent discard this guard exists to prevent (measured against this repository's own history, where such footers are a recurring, intentional pattern, not a mistake to reject). This harvesting rule does not by itself force a release — if the whole window is non-bumping, step 2's STOP still applies even when a non-bumping commit in it carries a footer; widening what a bare footer alone can trigger is out of scope here. Prior sections stay intact. Create the file with a `# Changelog` heading if absent. The changelog is a user-facing deliverable: apply `<plugin-root>/includes/anti-slop-design/core.md` §3.A (no prose-separator em-dashes in the entry prose) and §3.B (copy self-audit), and `<plugin-root>/includes/anti-slop-design/medium-documents.md` §7.A.1 changelog guidance, to each rolled entry. **Home for the composed section (MEDIUM, adversarial review 2026-07-31, previously unspecified):** besides landing in `$CHANGELOG` itself, this same section text is what Phase 2's `<message-file>` and Phase 3's `<Phase-1 section file>` both read back — write it to a scratch file created OUTSIDE the working tree (e.g. `mktemp`), never anywhere under the repo. A copy left inside the tree would either dirty the clean-tree state Pre-flight already required (this skill never re-runs Pre-flight mid-phase to notice) or, under a `payload: .` row, be swept straight into the very release window it is composing. Discard the scratch file once Phase 3 no longer needs it; it is working state, not a deliverable. **This scratch file is not required to survive across a session boundary** (HIGH, blind exercise run 19): `resume_publish` below explicitly permits Phase 3 to run in a LATER invocation than the one that composed this section — by design, since a fresh publish and a resumed one share the same Phase-3 authorization gate — and by then a `mktemp` file from a prior session is normally already gone. Phase 3 step 2 does not assume it survived; it reconstructs the same text mechanically from `$CHANGELOG` instead.
|
|
345
|
+
5. Derive the release date **once** — `RELEASE_DATE=$(date +%F)` — and reuse that single value for the changelog header, the Phase-2 `Released-at:` footer, and the Phase-3 Release; never hand-type the date a second time (`release_dates_consistent` verifies the changelog-header date equals the `Released-at:` date). Roll the `CHANGELOG:` footers from each `feat` / `fix` / `perf` / `refactor` commit into a new `## [${VERSION}] — $RELEASE_DATE` section in `$CHANGELOG` (the Keep-a-Changelog bracket heading this guard matches, not the bare `v`-prefixed form), grouped Added (`feat`) / Fixed (`fix`) / Performance (`perf`) / Changed (`refactor`, matching this repository's own changelog convention for non-user-facing-but-notable work). **A commit whose classification marks `breaking` true — the `!` bang after the type/scope or a `BREAKING CHANGE:`/`BREAKING-CHANGE:` footer, exactly the flag `classify-window` already computes and never re-derived here — rolls into its own `### Breaking` group instead of its type group, placed first among the section's groups.** A `feat!` no longer lands under `### Added` indistinguishable from an ordinary feature, and a breaking `chore!:` (which has no type group of its own) still gets one; an ordinary nonbreaking commit is never placed in `### Breaking`, and a commit already in `### Breaking` is never also duplicated into its type group. This is the same composed section text Phase 2's `<message-file>` and Phase 3's `<Phase-1 section file>` both read back (below), so `### Breaking` is visible in the changelog, the tag message, and the Release notes without a second composition pass. **Also harvest a `CHANGELOG:` footer from any `test`/`docs`/`chore`/`ci` commit that carries one**, into the same section's Changed group: its type says "not user-visible" but its footer is the more specific, deliberately-authored signal, and dropping it because of the type would be exactly the silent discard this guard exists to prevent (measured against this repository's own history, where such footers are a recurring, intentional pattern, not a mistake to reject). This harvesting rule does not by itself force a release — if the whole window is non-bumping, step 2's STOP still applies even when a non-bumping commit in it carries a footer; widening what a bare footer alone can trigger is out of scope here. Keep an existing `## [Unreleased]` section at the top of the release sections. Insert the new version section below its complete body and above prior released versions; never place a released version above the Unreleased marker. Prior sections stay intact. Create the file with a `# Changelog` heading if absent. The changelog is a user-facing deliverable: apply `<plugin-root>/includes/anti-slop-design/core.md` §3.A (no prose-separator em-dashes in the entry prose) and §3.B (copy self-audit), and `<plugin-root>/includes/anti-slop-design/medium-documents.md` §7.A.1 changelog guidance, to each rolled entry. **Home for the composed section (MEDIUM, adversarial review 2026-07-31, previously unspecified):** besides landing in `$CHANGELOG` itself, this same section text is what Phase 2's `<message-file>` and Phase 3's `<Phase-1 section file>` both read back — write it to a scratch file created OUTSIDE the working tree (e.g. `mktemp`), never anywhere under the repo. A copy left inside the tree would either dirty the clean-tree state Pre-flight already required (this skill never re-runs Pre-flight mid-phase to notice) or, under a `payload: .` row, be swept straight into the very release window it is composing. Discard the scratch file once Phase 3 no longer needs it; it is working state, not a deliverable. **This scratch file is not required to survive across a session boundary** (HIGH, blind exercise run 19): `resume_publish` below explicitly permits Phase 3 to run in a LATER invocation than the one that composed this section — by design, since a fresh publish and a resumed one share the same Phase-3 authorization gate — and by then a `mktemp` file from a prior session is normally already gone. Phase 3 step 2 does not assume it survived; it reconstructs the same text mechanically from `$CHANGELOG` instead.
|
|
346
346
|
6. **Sync `$TARGET`'s release surfaces to the repo — mechanically derived, never typed.** In this order; each sub-step depends on the one before it.
|
|
347
347
|
|
|
348
348
|
**6a. Update the manifests.** Set every path in `$MANIFEST` to the derived version, **except a path also listed in `$GENERATED_MANIFEST`** — that one is never hand-edited; run the row's declared `generate` command (when declared) to regenerate it instead.
|