Make development workflow risk-based and verification proportionate

This commit is contained in:
jb
2026-10-07 17:43:19 -04:00
parent 284fdd638d
commit 0cc0e82bbc
13 changed files with 265 additions and 173 deletions
@@ -0,0 +1,24 @@
# Disposable and protected data
Pre-production is a lifecycle stage, not permission to discard data. Disposable means the owner authorizes replacement of specified data and it can be reproduced. Idempotent describes an operation's repeated effect; it does not establish disposability.
## Establish authority
Read the repository's existing instructions for a standing data policy. It must identify:
- named disposable environments and how to verify the actual connection target;
- the data/resources that may be deleted or rebuilt;
- the authorized reset/reseed procedure and source of required fixtures;
- protected environments, valuable/shared data, and external compatibility obligations.
Treat this as scoped authorization, not a reason to reset unnecessarily. Before each operation, verify the actual target matches the declaration, the operation stays within the allowed resources, and required data can be recreated. Stop and ask when identity, scope, or reproducibility is uncertain. Do not infer permission from a branch name, `NODE_ENV`, a database name containing “dev,” or the absence of production users.
When no policy exists, ask for the intended preservation contract and explicit authority before schema/data changes. Record any approved standing policy in the repository's established instructions; never label an environment disposable on the agent's own authority. Production/live-database access remains explicitly gated even if another target is disposable.
## Implement the smallest sufficient change
For a verified, authorized disposable target, prefer a direct schema change plus reset/reseed over compatibility adapters, phased backfills, dual writes, or bespoke rollback machinery. Keep migration files when the framework needs them to create a fresh database. Verify initialization/rebuild and affected behavior with representative data.
For protected data or external consumers, preserve the actual contract. Design migration, backup/recovery, compatibility, and verification around demonstrated risks and obtain scoped approval. Shared staging data with valuable manual QA state is protected unless its owner explicitly authorizes replacing it.
Example: a required field in an authorized throwaway database may need an updated schema and seed data, a rebuild, and a feature check. It does not automatically need tests for upgrading every historic schema. The same field in a customer-backed service may require a staged migration and compatibility checks.
@@ -2,7 +2,7 @@
## Checkpoint records
Keep one concise Markdown record in the repository's established plan location; otherwise use `docs/plans/<feature-branch-slug>.md`. Require a unique path before creation. Store status/current phase, request/scope, Git identity, acceptance criteria, exact approved plan and gate decisions, assignment ownership, verification outcomes, review identities/findings/fingerprint, integration, blockers, and the next safe action.
Keep one concise Markdown record in the repository's established plan location; otherwise use `docs/plans/<feature-branch-slug>.md`. Require a unique path before creation. Store status/current phase, request/scope, Git identity, acceptance criteria, the plan and its authority (clear user request, standing policy, or explicit decision), ownership, verification outcomes, review identity/findings/fingerprint, integration, blockers, and the next safe action. Retain the template's headings for helper compatibility; use short entries or “not applicable” rather than inventing ceremony for every section.
Keep transcripts, leases, heartbeats, notification receipts, full command output, and model-authored execution graphs out of the record. Link durable artifacts or commits instead. Update only at meaningful boundaries; task tools hold high-frequency progress.
@@ -13,7 +13,7 @@ node skills/develop/develop-workflow/scripts/checkpoint-record.mjs \
<record.md> --input <candidate.md> --expected-sha256 <current-digest>
```
Omit `--expected-sha256` only for first creation; require an absent target. Commit the initial record and every approved gate before dependent product mutation. The exclusive lock serializes cooperating helper invocations; external mutation of its pathname is outside the contract. A stale digest, lock, temporary artifact with no valid record, validation failure, or filesystem error blocks progress. Preserve artifacts for inspection; never hand-delete recovery evidence to make a command pass.
Omit `--expected-sha256` only for first creation; require an absent target. Save the initial plan and scoped decisions before dependent mutation; batch record changes with meaningful commits instead of committing every gate. The exclusive lock serializes cooperating helper invocations; external mutation of its pathname is outside the contract. A stale digest, lock, temporary artifact with no valid record, validation failure, or filesystem error blocks dependent progress. Preserve artifacts for inspection; never hand-delete recovery evidence to make a command pass.
## Assignment evidence
@@ -21,11 +21,11 @@ Before every mutating assignment, record:
- display name, profile, stable child/session IDs when exposed;
- deadline and exclusive owned paths;
- branch, HEAD, clean/dirty status, changed paths, and patch artifact.
- branch, HEAD, clean/dirty status, and changed paths; retain a patch artifact when needed to distinguish concurrent or interrupted edits.
After delivery, capture the same Git evidence and inspect the patch. Treat the entire ambiguous profile/run as a mutator when stable identity is unavailable. Reject unexpected commits and paths outside ownership.
On an ownership or Git invariant failure, freeze mutation and present evidence-backed choices: inspect, accept and replan, restore with a non-destructive patch, or abort. Obtain a user decision before proceeding.
On an ownership or Git invariant failure, freeze affected mutation and inspect the evidence. Resume automatically only when ownership is re-established, prior children are terminal, and the next action preserves all work within existing authority. Ask with evidence-backed options when recovery would discard work, change agreed behavior, accept uncertain ownership, or broaden scope.
On deadline expiry or missing delivery, request stop through the available control surface and prove the process/session terminal before reassignment. A completed UI indicator is not output or liveness proof. Keep the workflow blocked for human termination/takeover when liveness remains unknown.
@@ -37,9 +37,9 @@ Reconstruct observed reality before trusting prose:
2. Discover candidate records from observed branches/worktrees and repository conventions.
3. Treat a workflow branch/worktree without a record as an orphan. Preserve it; inspect branch, base, reflog, status, commits, and diff; ask whether to adopt it with a record, quarantine it, or remove it after separate cleanup approval.
4. Compare the record's base, branch, and checkpoint with Git evidence.
5. Preserve atomic-update temporary files. Use the last committed valid record until recovery is approved.
5. Preserve atomic-update temporary files. Prefer the latest valid saved record only after reconciling it with Git; distinguish saved from committed checkpoints. When interrupted-write evidence conflicts, use a committed valid record as a fallback if available, then inspect and resolve uncertainty before mutation. Absence of an initial record commit alone is not an orphan or approval gate.
6. Rebuild task state from completed evidence and the recorded next action.
7. Freeze interrupted mutation until its diff is inspected and prior child liveness is terminal.
8. Resume from the last proven checkpoint.
Ask when evidence conflicts, scope may have changed, child liveness is unknown, or recovery needs risk. Treat the record as a recovery map, not a transaction log.
Ask when conflicting evidence remains unresolved, scope needs a new decision, child liveness cannot be proven, or recovery crosses an approval boundary. Resume routine work automatically when inspection restores the evidence within existing authority. Treat the record as a recovery map, not a transaction log.
@@ -2,39 +2,28 @@
## Isolation
Record the source branch and exact base before creating `./.worktrees/<feature>` on `feature/<feature>`. Prove every shell location with explicit `cd` or `git -C`; verify `git rev-parse --show-toplevel` before mutation. Block on collisions, unmerged paths, unexpected ownership, or an unignored worktree root. Never rename, reset, clean, stash, copy source changes, or remove an orphan silently.
Record the source branch and exact base before creating `./.worktrees/<feature>` on `feature/<feature>`. Prove shell locations with explicit `cd` or `git -C`; verify `git rev-parse --show-toplevel` before mutation. Block on collisions, unmerged paths, unexpected ownership, or an unignored worktree root. Never rename, reset, clean, stash, copy source changes, or remove an orphan silently.
A dirty source checkout requires bounded status/path evidence and explicit approval because its changes are omitted. Preserve that evidence in the record.
A dirty source checkout requires bounded status/path evidence and explicit approval because its changes are omitted. Preserve that evidence in the record. Do not disturb another workflow's worktree or changes.
## Synchronize and pin review
After focused commits and verification:
Fetch the latest source branch when a remote exists and rebase onto the intended latest source commit before final verification where practical. Inspect any resulting delta and apply [verification invalidation](verification.md#reuse-and-invalidation); rerun affected checks rather than restarting all phases automatically. Ask before resolving conflicts that change agreed behavior, rewriting shared history, force operations, or non-fast-forward integration.
1. Fetch the latest source branch when a remote exists.
2. Rebase the feature branch onto the latest source commit.
3. Rerun affected checks and full required verification whenever rebase changes the effective tree or resolves conflicts.
4. Record the review base, product HEAD, clean status, tree hash, and commit list.
5. Generate exact review bytes:
Create focused commits after their applicable checks pass. Pin the review base, product HEAD, clean status, tree hash, commit list, exact binary diff command, and digest using [review policy](review-and-remediation.md). Keep product approval attached to immutable evidence, including targeted follow-up on subsequent fixes.
```bash
git diff --binary --full-index --find-renames <base>...<product-head> --
```
6. Hash those bytes with SHA-256 and record the command and digest. Regenerate from the durable commits rather than committing a duplicate patch.
Ask before conflict resolution changes approved behavior, history rewrite of shared work, force operations, or non-fast-forward integration.
Update the record at meaningful boundaries and batch it with related commits. Neither an initial record-only commit nor a commit per decision is mandatory. A saved, uncommitted record is recovery evidence, but verify it against Git rather than assuming it was previously committed.
## Fast-forward integration
After both review axes approve the exact fingerprint:
After independent review and final required verification:
1. Confirm the source branch still equals the final rebase base. Return to synchronize, verify, and review if it advanced.
1. Confirm the source branch still equals the integration base. If it advanced, inspect the delta, synchronize, invalidate affected checks, and refresh review coverage for changed interactions. Reuse unaffected evidence only with justification.
2. Confirm the source checkout exists, is clean, and is safe to update. Stop when dirty or missing.
3. Fast-forward the source branch to the reviewed feature branch; create no merge commit.
4. In the source checkout, update only the workflow record with bound review and integration evidence.
5. Prove the closure diff touches only that record, run applicable documentation checks, and create one metadata-only closure commit.
6. Run a cheap final sanity check.
7. Prove the product and closure commits reachable from the source branch.
8. Remove the completed worktree, then delete its feature branch.
3. Confirm the final product changes are covered by review and verification. Evidence-only updates to the workflow record may follow review only after proving they change results/status, not scope, acceptance, policy, or executable instructions. Review other changes normally.
4. Fast-forward the source branch to the feature branch; create no merge commit.
5. Save integration evidence in the record. Batch it with a pending evidence update or use an optional record-only commit when needed to retain final results. Prove any post-review evidence commit touches only the record and run its applicable checks; there is no mandatory separate closure-commit gate.
6. Run a cheap sanity check, prove all product and retained evidence commits reachable from the source branch, and verify clean source/worktree state.
7. Remove only the workflow-owned worktree, then delete its feature branch.
Treat cleanup in step 8 as pre-authorized only after every preceding clean-state and reachability proof. Ask before any other destructive cleanup. Pushing, publishing, deployment, and production access remain separate user actions.
Cleanup in step 7 is pre-authorized only after the ownership, reachability, and clean-state proofs. Ask before other destructive cleanup. Push, publish, deployment, and production access remain separate scoped actions.
@@ -1,33 +1,9 @@
# Independent review and remediation
## Identity and capability
Use the shared [code-review skill](../../code-review/SKILL.md) as the single source of truth for reviewer selection, pinned evidence, both review axes, findings, and follow-up. One non-author reviewer is the default; additional reviewers require distinct risk or repository policy.
Exclude every identity that authored or mutated the reviewed diff. Record reviewer display name, profile, child ID, and session ID when available. When stable identity is unavailable, exclude the entire ambiguous profile/run. Keep reviewers read-only and separate for:
For workflow reviews, supply the retained record and originating request as the specification, along with repository standards, mutator identities, immutable base/product commits, tree/status evidence, exact binary diff command, and SHA-256. Record the delivered identity and verdict. Leave fixes to an implementer, never the reviewer.
- **Standards:** repository instructions and documented conventions.
- **Specification:** the approved workflow record and linked source plan/spec.
Review after focused checks and synchronization, before the final full-suite boundary. For a bounded fix, run affected checks and obtain targeted follow-up from the same independent reviewer covering the new fingerprint and interactions. Broaden review when prior conclusions no longer apply. Keep verification evidence and code-review approval separate: neither substitutes for the other.
Use Git-capable reviewer profiles with repository read access and no declared `write` or `edit` tools. Shell access can still mutate; capture status, tree, HEAD, and changed paths before and after review. Any mutation invalidates the verdict and marks that identity as a mutator.
## Review brief
Generate the brief in the parent. Include:
- pinned base and product HEAD;
- clean status and product tree hash;
- commit list;
- exact `git diff --binary --full-index --find-renames <base>...<product-head> --` command;
- SHA-256 of those exact bytes;
- approved record/specification sources;
- repository standards sources;
- all excluded mutator identities.
Launch standards and specification reviewers through separate direct subagent calls. Avoid wrapped parallel launch until its delivery defect is proven fixed. Require each reviewer to regenerate the pinned diff, confirm its digest before review, remain read-only, and bind every finding to file/hunk evidence and severity. Treat a missing result or digest mismatch as no verdict.
Approval binds to base, product HEAD, clean status, tree hash, and diff digest. Permit a later closure commit outside that fingerprint only after proving it changes the workflow record alone.
## Findings and remediation
Validate findings against repository evidence. Send accepted fixes to an original implementer or another non-reviewer, never the reviewer. Preserve exclusive path ownership and assignment evidence. Rerun affected checks and the full required suite, create focused commits, and generate a new fingerprint.
Launch fresh independent reviewers for the changed diff. Escalate after two unsuccessful remediation cycles or whenever a finding requires material scope, acceptance, ownership, verification, or architecture changes; return to plan approval before further production mutation.
After review, record-only evidence updates may be excluded only under the narrow [integration rule](git-and-integration.md#fast-forward-integration). Scope, specification, policy, and executable-instruction changes are not evidence-only updates.
@@ -0,0 +1,36 @@
# Proportionate verification
## Choose tests by the changed contract
Cover meaningful behavior, important boundaries, and credible failure modes. Prefer existing test seams and realistic minimal fixtures.
- Unit tests establish logic and regressions through public interfaces.
- Integration tests establish contracts unit tests cannot, such as persistence or process boundaries.
- E2E tests establish important user journeys and changed wiring. Avoid replaying every unit-level permutation through the UI.
- Validate changed UI in its real interface. One realistic scenario may supply both automated and interface-validation evidence when it actually establishes both.
- Simple straightforward code does not need a test for every branch. Avoid assertions that restate implementation, snapshots of incidental details, and regression tests preserving intentionally removed behavior.
- For authorized disposable data, verify fresh initialization/reset, representative seed data, and affected behavior. Add historical upgrade/rollback coverage only when data or compatibility must be preserved.
When test infrastructure threatens to become larger than the feature, reassess the seam and failure cost before expanding it. Do not impose a coverage percentage or time cap that leaves consequential behavior untested. Security, valuable data, and broad shared-code changes can warrant more testing than implementation.
## Development and final checks
Run focused checks during implementation and after review fixes. Schedule one full required suite after review/remediation and synchronization, together with applicable static/build checks. Reuse an already completed check instead of running it again merely because a new phase started.
Before a commit, run the checks appropriate to its changes; earlier review commits may rely on focused checks. The final integration boundary still requires the full suite. Repository or CI rules requiring stricter pre-commit checks take precedence. Pure documentation changes may use documentation checks when repository policy permits; executable skill instructions need policy validation, not arbitrary prose snapshots.
## Reuse and invalidation
Record the command, working directory, exit/result, tested commit or tree, and relevant environment/configuration. Evidence is reusable only when the command and relevant code, tests, dependencies, configuration, and environment remain applicable and the process actually completed.
- A commit-only change, record evidence update, or unrelated prose edit does not automatically invalidate product tests. Check documentation links/formatting as applicable.
- A bounded behavior fix requires affected tests and targeted review. Preserve other results only with an evidence-backed impact assessment.
- Shared code, dependency/build configuration, conflicting rebases, or uncertain impact require broader checks, including the full suite when its coverage may be affected.
- If the source branch advanced, inspect the actual delta. Do not equate a new commit ID with changed test inputs, or assume disjoint filenames imply no interaction.
- Failed, aborted, stale, or environmental checks remain visible. Retry with a reason; never convert a failure to a pass by inference.
“One final full run” removes scheduled duplication, not legitimate reruns after failures or invalidation. If new fixes affect the verified state, rerun the required checks and make the review cover the changed diff before integration.
## External verification gates
Inspect repository scripts, CI requirements, and active hook policy before promising evidence reuse. An exact-command hook may require a standalone full command even when a focused command passes. Its requirements remain binding until explicitly changed or waived under its own policy. Record a waiver as skipped, never passed; avoid routine waivers as a substitute for aligning policy. Scope hook/config changes separately rather than inventing a workflow verification cache.