claude-dev-env 1.62.1 → 1.64.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/agents/code-advisor.md +22 -0
- package/agents/code-verifier.md +42 -0
- package/bin/install.mjs +1 -1
- package/hooks/blocking/code_rules_dead_argparse_argument.py +554 -0
- package/hooks/blocking/code_rules_enforcer.py +6 -0
- package/hooks/blocking/config/verified_commit_constants.py +16 -0
- package/hooks/blocking/test_code_rules_enforcer_dead_argparse_argument.py +534 -0
- package/hooks/blocking/test_verification_verdict_store.py +232 -0
- package/hooks/blocking/test_verified_commit_gate.py +43 -0
- package/hooks/blocking/test_verifier_verdict_minter.py +139 -0
- package/hooks/blocking/verification_verdict_store.py +165 -10
- package/hooks/blocking/verified_commit_gate.py +8 -2
- package/hooks/blocking/verifier_verdict_minter.py +59 -9
- package/hooks/hooks_constants/dead_argparse_argument_constants.py +28 -0
- package/package.json +1 -1
- package/skills/autoconverge/SKILL.md +26 -1
- package/skills/autoconverge/workflow/converge.contract.test.mjs +82 -18
- package/skills/autoconverge/workflow/converge.mjs +46 -18
- package/skills/verified-build/SKILL.md +38 -0
|
@@ -141,15 +141,33 @@ const STANDARDS_EDIT_SCHEMA = {
|
|
|
141
141
|
required: ['issueUrl', 'hardeningRepoPath', 'hardeningBranch', 'hardeningEdited', 'summary'],
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
144
|
+
/**
|
|
145
|
+
* Build the verdict-fence step instructions for a verify agent, binding the
|
|
146
|
+
* surface hash by branch name rather than by a self-resolved cwd. Resolving
|
|
147
|
+
* the branch via `gh pr view` is cwd-immune: it does not matter which worktree
|
|
148
|
+
* the verify agent runs in, so a launcher session whose cwd is a different
|
|
149
|
+
* worktree cannot poison the binding hash.
|
|
150
|
+
* @param {string} prOwner GitHub owner of the repo that holds the branch
|
|
151
|
+
* @param {string} prRepo GitHub repo name
|
|
152
|
+
* @param {number|string} prNumber PR number used to resolve the head branch
|
|
153
|
+
* @returns {string} binding-hash and verdict-fence instructions for a verify prompt
|
|
154
|
+
*/
|
|
155
|
+
function buildVerdictFenceSteps(prOwner, prRepo, prNumber) {
|
|
156
|
+
return (
|
|
157
|
+
`Compute the binding hash for the live surface:\n` +
|
|
158
|
+
` a. Resolve the PR head branch (cwd-immune): run exactly\n` +
|
|
159
|
+
` gh pr view ${prNumber} --repo ${prOwner}/${prRepo} --json headRefName -q .headRefName\n` +
|
|
160
|
+
` Capture the branch name printed on stdout.\n` +
|
|
161
|
+
` b. Run exactly:\n` +
|
|
162
|
+
` "C:\\Python313\\python.exe" "<REPO>/packages/claude-dev-env/hooks/blocking/verification_verdict_store.py" --manifest-hash-for-branch "<that branch>"\n` +
|
|
163
|
+
` (substitute the REPO path you resolved for the script path, and the branch name for <that branch>). That prints a single 64-char hex hash on stdout — capture it.\n` +
|
|
164
|
+
`Then END your message with a fenced verdict block exactly in this shape, on its own, carrying that hash:\n` +
|
|
165
|
+
" ```verdict\n" +
|
|
166
|
+
` {"all_pass": true, "findings": [], "manifest_sha256": "<that hash>"}\n` +
|
|
167
|
+
" ```\n" +
|
|
168
|
+
` When verification fails, set all_pass to false and list the unresolved concerns in findings; still include the manifest_sha256. The verdict fence must be the last thing in your message.`
|
|
169
|
+
)
|
|
170
|
+
}
|
|
153
171
|
|
|
154
172
|
const CONVERGENCE_SUMMARY_SCHEMA = {
|
|
155
173
|
type: 'object',
|
|
@@ -713,9 +731,9 @@ function verifyFixesInWorkingTree(head, findings, sourceLabel) {
|
|
|
713
731
|
`You are the VERIFY step for ${findings.length} finding(s) (${sourceLabel}) on ${prCoordinates}, HEAD ${head}. The edit step left fixes in the working tree, uncommitted. Do NO edits of any kind — verification only; any edit invalidates the verdict you are about to emit.\n\n` +
|
|
714
732
|
`Findings the working-tree fixes must address:\n${findingsBlock}\n\n` +
|
|
715
733
|
`Steps:\n` +
|
|
716
|
-
`1. Resolve the worktree repo root: REPO=$(git rev-parse --show-toplevel).\n` +
|
|
734
|
+
`1. Resolve the worktree repo root for running tests: REPO=$(git rev-parse --show-toplevel).\n` +
|
|
717
735
|
`2. Verify the uncommitted working-tree changes resolve every finding above: run the relevant tests and the named gates against the working tree. Read the diff (git diff) and confirm each finding is fixed test-first per CODE_RULES.\n` +
|
|
718
|
-
`3. ${
|
|
736
|
+
`3. ${buildVerdictFenceSteps(input.owner, input.repo, input.prNumber)}`,
|
|
719
737
|
{ label: `fix-verify:${sourceLabel}`, phase: 'Converge', agentType: 'code-verifier' },
|
|
720
738
|
)
|
|
721
739
|
}
|
|
@@ -935,9 +953,9 @@ function verifyRepairChanges(head, failures) {
|
|
|
935
953
|
`You are the VERIFY step for the convergence repair on ${prCoordinates}, HEAD ${head}. The edit step left its repair in the working tree (a bot-thread fix uncommitted, and/or a rebase onto origin/main), unpushed. Do NO edits of any kind — verification only; any edit invalidates the verdict you are about to emit.\n\n` +
|
|
936
954
|
`Concerns the working-tree repair must resolve (the gates the convergence check flagged):\n${failureBlock}\n\n` +
|
|
937
955
|
`Steps:\n` +
|
|
938
|
-
`1. Resolve the worktree repo root: REPO=$(git rev-parse --show-toplevel).\n` +
|
|
956
|
+
`1. Resolve the worktree repo root for running tests: REPO=$(git rev-parse --show-toplevel).\n` +
|
|
939
957
|
`2. Verify the working tree against origin/main: any bot-thread code fix is correct test-first per CODE_RULES, and a rebase (if any) left a clean, conflict-free tree. Read the diff (git diff origin/main) and run the relevant tests and named gates.\n` +
|
|
940
|
-
`3. ${
|
|
958
|
+
`3. ${buildVerdictFenceSteps(input.owner, input.repo, input.prNumber)}`,
|
|
941
959
|
{ label: 'repair-verify', phase: 'Finalize', agentType: 'code-verifier' },
|
|
942
960
|
)
|
|
943
961
|
}
|
|
@@ -1044,22 +1062,32 @@ function standardsFollowUpEdit(head, findings, sourceLabel) {
|
|
|
1044
1062
|
/**
|
|
1045
1063
|
* Standards-hardening verify step: a code-verifier confirms the uncommitted
|
|
1046
1064
|
* hooks/rules change staged in the hardening repo blocks the deferred violation
|
|
1047
|
-
* classes, computes the binding surface hash for that repo
|
|
1048
|
-
* verdict fence as plain assistant text (NO schema) — unlocking the
|
|
1065
|
+
* classes, computes the binding surface hash for that repo by branch (cwd-immune),
|
|
1066
|
+
* and ends with a verdict fence as plain assistant text (NO schema) — unlocking the
|
|
1049
1067
|
* verified-commit gate for the cross-repo hardening commit. The verifier makes
|
|
1050
1068
|
* no edits.
|
|
1051
1069
|
* @param {string} hardeningRepoPath absolute path of the hardening repo checkout the edit staged
|
|
1070
|
+
* @param {string} hardeningBranch the branch in the hardening repo that the edit staged the change on
|
|
1052
1071
|
* @param {string} sourceLabel short description of where the findings came from
|
|
1053
1072
|
* @returns {Promise<string>} the verifier transcript carrying the verdict fence
|
|
1054
1073
|
*/
|
|
1055
|
-
function verifyHardeningChanges(hardeningRepoPath, sourceLabel) {
|
|
1074
|
+
function verifyHardeningChanges(hardeningRepoPath, hardeningBranch, sourceLabel) {
|
|
1056
1075
|
return convergeAgent(
|
|
1057
1076
|
`You are the VERIFY step for an environment-hardening change (${sourceLabel}) staged in the working tree of ${hardeningRepoPath}. The edit step left the hooks/rules edits uncommitted there. Do NO edits of any kind — verification only; any edit invalidates the verdict you are about to emit.\n\n` +
|
|
1058
1077
|
`Concern the working-tree change must resolve: the edited hooks/rules block the code-standard violation classes from the deferred round at Write/Edit time, and a hook change carries a passing test per CODE_RULES.\n\n` +
|
|
1059
1078
|
`Steps:\n` +
|
|
1060
1079
|
`1. cd into ${hardeningRepoPath}, then resolve its repo root: REPO=$(git rev-parse --show-toplevel).\n` +
|
|
1061
1080
|
`2. Verify the uncommitted working-tree change in REPO: read the diff (git diff) and run the hook/rule tests in that repo, confirming each violation class is now blocked.\n` +
|
|
1062
|
-
`3.
|
|
1081
|
+
`3. Compute the binding hash for the live surface:\n` +
|
|
1082
|
+
` The hardening branch is: ${hardeningBranch}\n` +
|
|
1083
|
+
` Run exactly:\n` +
|
|
1084
|
+
` "C:\\Python313\\python.exe" "<REPO>/packages/claude-dev-env/hooks/blocking/verification_verdict_store.py" --manifest-hash-for-branch "${hardeningBranch}"\n` +
|
|
1085
|
+
` (substitute the REPO path you resolved for the script path). That prints a single 64-char hex hash on stdout — capture it.\n` +
|
|
1086
|
+
` Then END your message with a fenced verdict block exactly in this shape, on its own, carrying that hash:\n` +
|
|
1087
|
+
" ```verdict\n" +
|
|
1088
|
+
` {"all_pass": true, "findings": [], "manifest_sha256": "<that hash>"}\n` +
|
|
1089
|
+
" ```\n" +
|
|
1090
|
+
` When verification fails, set all_pass to false and list the unresolved concerns in findings; still include the manifest_sha256. The verdict fence must be the last thing in your message.`,
|
|
1063
1091
|
{ label: `standards-verify:${sourceLabel}`, phase: 'Converge', agentType: 'code-verifier' },
|
|
1064
1092
|
)
|
|
1065
1093
|
}
|
|
@@ -1123,7 +1151,7 @@ async function spawnStandardsFollowUp(head, findings, sourceLabel) {
|
|
|
1123
1151
|
if (editResult?.hardeningEdited !== true || !editResult?.hardeningRepoPath) {
|
|
1124
1152
|
return { hardeningPrOpened: false }
|
|
1125
1153
|
}
|
|
1126
|
-
const verifyTranscript = await verifyHardeningChanges(editResult.hardeningRepoPath, sourceLabel)
|
|
1154
|
+
const verifyTranscript = await verifyHardeningChanges(editResult.hardeningRepoPath, editResult.hardeningBranch, sourceLabel)
|
|
1127
1155
|
if (!verdictPassed(verifyTranscript)) {
|
|
1128
1156
|
return { hardeningPrOpened: false }
|
|
1129
1157
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: verified-build
|
|
3
|
+
description: >-
|
|
4
|
+
Runs a code task through the two-phase verified workflow: scoped coder
|
|
5
|
+
agents write the changes (consulting the tool-less code-advisor when
|
|
6
|
+
stuck on a decision), then a fresh-context code-verifier agent re-derives
|
|
7
|
+
and runs every check itself. The verifier's fenced verdict is minted by
|
|
8
|
+
the verifier_verdict_minter hook and unlocks the verified_commit_gate for
|
|
9
|
+
git commit/push. Use for feature implementations, refactors, and bug
|
|
10
|
+
fixes that land behind verification. Triggers: 'verified build', 'run
|
|
11
|
+
this verified', 'two-phase build', 'build and verify', 'verified
|
|
12
|
+
implementation'.
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Verified Build
|
|
16
|
+
|
|
17
|
+
Two phases, hook-enforced: coders write, a fresh-context verifier grades, and `git commit`/`git push` open only on a clean verdict bound to the live change surface.
|
|
18
|
+
|
|
19
|
+
## Workflow
|
|
20
|
+
|
|
21
|
+
Copy this checklist and check items off as you go:
|
|
22
|
+
|
|
23
|
+
- [ ] **Record baselines.** Before any coder runs: the test command and its exact failure set, plus any other gates the repo names. Scope the test command to the modules the task touches (their test files plus tests importing the changed modules); record a full-suite baseline only when the assignments span multiple modules or multiple coders. The verifier compares against these.
|
|
24
|
+
- [ ] **Scope assignments.** Split the task into file-disjoint assignments; write each as a task text with named checks.
|
|
25
|
+
- [ ] **Spawn coders.** One agent per assignment (`clean-coder` or Sonnet). Tell each: on a decision it can't reasonably solve, consult the tool-less `code-advisor` agent — it returns a plan, a correction, or a stop signal — then resume.
|
|
26
|
+
- [ ] **Settle the tree.** After coders finish: run formatters and any file-rewriting hooks, stage nothing, change nothing more.
|
|
27
|
+
- [ ] **Spawn the verifier last.** Agent tool, `subagent_type: "code-verifier"`, with the task texts, the diff scope, and the recorded baselines. When it stops, the SubagentStop hook mints its verdict.
|
|
28
|
+
- [ ] **Repair only reported findings.** On a failing verdict, spawn repair agents scoped to the findings, then re-spawn the verifier. Repeat until clean.
|
|
29
|
+
- [ ] **Land right away.** One commit, push, draft PR — before anything else touches a file.
|
|
30
|
+
|
|
31
|
+
## Gotchas
|
|
32
|
+
|
|
33
|
+
- Any file change after the verifier stops moves the surface hash and re-locks the gate — formatter rewrites included. Settle the tree first; land right after the clean verdict.
|
|
34
|
+
- The verdict covers the whole branch surface (merge base to work tree, untracked files included). There is no "verify just my part."
|
|
35
|
+
- The verifier must end with a ```` ```verdict ```` fence. No fence means nothing is minted and the gate stays closed.
|
|
36
|
+
- The minter keys on the agent type string `code-verifier` — spawning the same prompt under another agent type mints nothing.
|
|
37
|
+
- A surface whose every change is a docs/image file (by extension), a Python file whose docstring-stripped AST is unchanged (docstring-, comment-, or formatting-only Python edits), or a pytest test file (`test_*.py`, `*_test.py`, `conftest.py`) is exempt automatically; skip the verifier for those. Comment-only edits in non-Python files are not exempt.
|
|
38
|
+
- Record the test baseline before coders start. Without the exact pre-existing failure set, new breakage hides inside old noise.
|