claude-dev-env 1.94.0 → 1.95.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/_shared/advisor/CLAUDE.md +2 -2
  2. package/_shared/advisor/advisor-protocol.md +35 -27
  3. package/_shared/advisor/scripts/config/advisor_scripts_constants/model_tier_run_validator_constants.py +3 -2
  4. package/_shared/advisor/scripts/model_tier_run_validator.py +23 -15
  5. package/_shared/advisor/scripts/tests/test_model_tier_run_validator.py +81 -17
  6. package/bin/CLAUDE.md +10 -1
  7. package/bin/ever-shipped-skills.mjs +70 -0
  8. package/bin/install.mjs +136 -6
  9. package/bin/install.prune.test.mjs +457 -0
  10. package/docs/CODE_RULES.md +1 -1
  11. package/hooks/blocking/code_rules_enforcer.py +4 -0
  12. package/hooks/blocking/code_rules_shared.py +82 -0
  13. package/hooks/blocking/code_rules_test_layout.py +9 -3
  14. package/hooks/blocking/plain_language_blocker.py +138 -4
  15. package/hooks/blocking/sensitive_file_protector.py +114 -48
  16. package/hooks/blocking/tdd_enforcer.py +9 -2
  17. package/hooks/blocking/test_code_rules_enforcer_scratchpad.py +105 -0
  18. package/hooks/blocking/test_code_rules_shared.py +181 -0
  19. package/hooks/blocking/test_plain_language_blocker_allowlist.py +184 -0
  20. package/hooks/blocking/test_sensitive_file_protector.py +185 -0
  21. package/hooks/blocking/test_tdd_enforcer_scratchpad.py +105 -0
  22. package/hooks/hooks_constants/CLAUDE.md +2 -0
  23. package/hooks/hooks_constants/harness_scratchpad_constants.py +17 -0
  24. package/hooks/hooks_constants/plain_language_blocker_constants.py +5 -0
  25. package/hooks/hooks_constants/sensitive_file_protector_constants.py +42 -0
  26. package/hooks/pyproject.toml +75 -4
  27. package/hooks/validators/CLAUDE.md +1 -1
  28. package/hooks/validators/README.md +2 -0
  29. package/hooks/validators/python_style_checks.py +114 -136
  30. package/hooks/validators/python_style_helpers.py +95 -0
  31. package/hooks/validators/test_python_style_checks.py +0 -164
  32. package/hooks/validators/test_python_style_checks_decorator_gap.py +119 -0
  33. package/hooks/validators/test_python_style_fixes.py +251 -0
  34. package/hooks/validators/test_python_style_helpers.py +125 -0
  35. package/package.json +1 -1
  36. package/rules/CLAUDE.md +1 -0
  37. package/rules/anti-corollary-tests.md +69 -0
  38. package/rules/bdd.md +1 -3
  39. package/rules/code-reviews.md +1 -1
  40. package/rules/gh-paginate.md +1 -1
  41. package/rules/plain-language.md +2 -0
  42. package/skills/CLAUDE.md +4 -3
  43. package/skills/autoconverge/workflow/converge.mjs +2 -2
  44. package/skills/bugteam/reference/README.md +2 -3
  45. package/skills/closeout/SKILL.md +153 -0
  46. package/skills/closeout/reference/handoff-prompt-template.md +72 -0
  47. package/skills/closeout/reference/issue-body-templates.md +108 -0
  48. package/skills/closeout/reference/pii-redaction-checklist.md +36 -0
  49. package/skills/orchestrator/SKILL.md +27 -21
  50. package/skills/orchestrator-refresh/SKILL.md +12 -8
  51. package/skills/pr-converge/CLAUDE.md +1 -1
  52. package/skills/pr-fix-protocol/SKILL.md +65 -0
  53. package/skills/skill-builder/references/skill-modularity.md +1 -1
  54. package/skills/team-advisor/SKILL.md +15 -11
  55. package/system-prompts/software-engineer.xml +7 -6
  56. package/hooks/validators/test_verify_paths.py +0 -32
  57. package/hooks/validators/verify_paths.py +0 -57
@@ -0,0 +1,36 @@
1
+ # PII redaction checklist
2
+
3
+ The PII pass runs on every closeout run, over every issue body and over the handoff prompt, before the confirmation gate. Repository visibility changes how aggressive the redaction is — public repos get the strictest pass — never whether the pass runs.
4
+
5
+ ## The pass
6
+
7
+ Read each drafted body and the handoff prompt line by line. For every match below, swap the real value for the placeholder. When a value is load-bearing for the fix (a hook needs the exact path shape), keep the shape and drop the private part — `~/.claude/hooks/<hook>.py`, not the full home path.
8
+
9
+ | Category | What to catch | Swap |
10
+ |---|---|---|
11
+ | Email | Any address | `<email>` |
12
+ | Real name | A person's name in a path, log line, or account | `<name>` |
13
+ | Home path | A user home directory | `~/` or `<home>/` |
14
+ | Private host / IP | A LAN host, NAS name, private IP | `<host>` |
15
+ | SSH user / port | A login user or non-standard port | `<user>`, `<port>` |
16
+ | Account id | A store, cloud, app, or master-user id | `<account-id>` |
17
+ | Token / secret | An API key, token, or credential | `<redacted>` |
18
+ | Private repo name | An unpublished owner/repo | `<owner>/<repo>` |
19
+ | Sheet / DB / script id | A Neon, Sheet, or Apps Script id | `<id>` |
20
+
21
+ ## Public versus private aggression
22
+
23
+ | Target repo | Aggression |
24
+ |---|---|
25
+ | Public (ships to a public host, open source) | Strictest: redact every category above, and any value a stranger could tie to a person or a private system. When in doubt, redact. |
26
+ | Private (internal, team-only) | Redact tokens, secrets, credentials, and emails without exception. Keep internal host and path shapes only when the fix needs them. |
27
+
28
+ ## After the pass
29
+
30
+ - List every redaction made, so the confirmation gate shows the user what changed.
31
+ - When a redaction removes a value the fix needs, note it as an open question for the user in the gate — do not guess a replacement.
32
+ - A body that still holds a match after the pass does not reach the gate. Re-run the pass until every match is swapped.
33
+
34
+ ## Why the pass is unconditional
35
+
36
+ An issue is a durable post on a shared server. A private value in an issue body outlives the session and the person who typed it. Running the pass on every body, public or private, keeps a leak from landing where it cannot be pulled back.
@@ -30,7 +30,7 @@ communication flows through it. It spawns and resumes executor subagents
30
30
  — `clean-coder` and the like — and those executors do every bit of the
31
31
  execution: the code edits, the build runs, the test runs. The orchestrating
32
32
  session drives the plan and routes hard decisions to the shared advisor
33
- (Claude: warm `session-advisor`; Grok: this session self-as-advisor).
33
+ (Claude: warm `session-advisor`; Grok: Claude CLI advisor via the chain runner).
34
34
 
35
35
  ## Gotchas
36
36
 
@@ -43,7 +43,7 @@ session drives the plan and routes hard decisions to the shared advisor
43
43
  wasted. Hand every code edit and every build or test run to an executor; keep
44
44
  the orchestrating session's own tool use to orchestration and light
45
45
  verification reads. Hard decisions go to the shared advisor (Claude:
46
- `session-advisor` via SendMessage; Grok: this session inline).
46
+ `session-advisor` via SendMessage; Grok: Claude CLI advisor via the chain).
47
47
  - **Flat ad hoc spawns bypass routing.** Every execution task goes through a
48
48
  workflow-backed spawn or workflow resume so the required agent type, model,
49
49
  prompt packet, and sidecar metadata stay attached to the work.
@@ -54,15 +54,15 @@ session drives the plan and routes hard decisions to the shared advisor
54
54
  spawn returns an `agentId` (format `a...-...`); keep it so `SendMessage` can
55
55
  reach that agent later. A named agent is reachable by name.
56
56
  - **Only the orchestrating session owns the shared advisor's lifecycle.** An
57
- executor that finds the advisor unreachable (Claude warm agent, or this
58
- session on Grok) reports that upward; it never spawns a replacement itself.
57
+ executor that finds the advisor unreachable (Claude warm agent, or Claude
58
+ CLI bind on Grok) reports that upward; it never spawns a replacement itself.
59
59
 
60
60
  ## Process
61
61
 
62
62
  1. **Check whether the refresh loop is already running this
63
63
  session.** If it is, do not schedule a second loop. Reuse any live
64
- shared advisor bind (Claude warm `session-advisor`, or Grok self-bind
65
- run step 3 only when none exists yet), then skip straight to step 4.
64
+ shared advisor bind (Claude warm `session-advisor`, or Grok Claude CLI
65
+ bind — run step 3 only when none exists yet), then skip straight to step 4.
66
66
 
67
67
  2. **Register the discipline reminder.** By default, schedule it with
68
68
  `ScheduleWakeup` at `delaySeconds: 1200`, prompt `/orchestrator-refresh`,
@@ -85,15 +85,18 @@ session drives the plan and routes hard decisions to the shared advisor
85
85
  [`_shared/advisor/advisor-protocol.md`](../../_shared/advisor/advisor-protocol.md);
86
86
  it is not a "spawn only at the floor" rule. Paste the **Claude host**
87
87
  Advisor block from that doc, with the resolved agent name filled in, into
88
- every executor's spawn prompt. On a **Grok host**, skip that spawn — use
89
- the protocol's self-as-advisor path (this session *is* the advisor; single
90
- tier `Grok`, attempt result `self`). Paste the **Grok host** Advisor block
91
- from that doc into every executor's spawn prompt never the Claude
92
- SendMessage block. Every row in the routing table is a consumer of the
93
- shared advisor, not just this session. The orchestrating session owns the
94
- shared advisor's lifecycle end to end (spawn or self-bind, drift handling
95
- per the shared doc, shutdown at task end); executors only ever SendMessage
96
- the warm agent (Claude) or report to this session (Grok).
88
+ every executor's spawn prompt. On a **Grok host**, skip the Agent spawn —
89
+ bind a max-tier Claude advisor through the protocol's CLI Claude-chain path
90
+ (Fable high, then Opus max; `claude_chain_runner.py` for account usage
91
+ failover). Paste the **Grok host** Advisor block from that doc into every
92
+ executor's spawn prompt never the Claude SendMessage block. Every row in
93
+ the routing table is a consumer of the shared advisor, not just this
94
+ session. The orchestrating session owns the shared advisor's lifecycle end
95
+ to end (Agent spawn or CLI bind, drift handling per the shared doc,
96
+ shutdown at task end); executors only ever SendMessage the warm agent
97
+ (Claude) or report to this session so it can consult the CLI advisor
98
+ (Grok). When the CLI chain cannot bind, fail closed and report to the user
99
+ — do not answer the four signals as this Grok session.
97
100
 
98
101
  4. **Orchestrate the task.** Hold the plan and the user conversation. Execute
99
102
  workflow-backed spawns or resumes using the routing table below, and keep
@@ -112,10 +115,13 @@ session drives the plan and routes hard decisions to the shared advisor
112
115
 
113
116
  **Claude host:** consult the shared `session-advisor` via `SendMessage`.
114
117
  **Grok host:** executors report to this orchestrating session; this session
115
- answers the four signals inline (self-as-advisor no Agent, no
116
- SendMessage-to-`session-advisor`). Every consult gets back one of four
117
- signals (ENDORSE, CORRECTION, PLAN, or STOP). See
118
- `agents/session-advisor.md` for what each signal means and
118
+ consults the bound Claude CLI advisor (`claude_chain_runner.py` +
119
+ `--resume`) and relays the four-signal reply (no Agent-tool
120
+ `session-advisor`, no SendMessage to one). Every consult gets back one of
121
+ four signals (ENDORSE, CORRECTION, PLAN, or STOP). When the CLI advisor is
122
+ unreachable, fail closed and surface that to the user — do not invent a
123
+ signal as this session. See `agents/session-advisor.md` for what each
124
+ signal means and
119
125
  [`_shared/advisor/advisor-protocol.md`](../../_shared/advisor/advisor-protocol.md)
120
126
  for the consult format.
121
127
 
@@ -173,8 +179,8 @@ Routing rules:
173
179
  session (see
174
180
  [`_shared/advisor/advisor-protocol.md`](../../_shared/advisor/advisor-protocol.md))
175
181
  — on Claude, executors consult a warm `session-advisor` via SendMessage; on
176
- Grok, this session is the advisor and executors report here. Executors never
177
- spawn or respawn the advisor.
182
+ Grok, executors report here and this session relays the Claude CLI advisor.
183
+ Executors never spawn or respawn the advisor.
178
184
  - Reuse a warm agent over a cold spawn whenever one holds relevant context.
179
185
 
180
186
  ## File Index
@@ -4,7 +4,7 @@ description: >-
4
4
  Fired by the /orchestrator loop reminder about every 20 minutes to
5
5
  re-assert the advisor discipline mid-run: orchestrate, route hard decisions
6
6
  to the shared advisor (ENDORSE / CORRECTION / PLAN / STOP — SendMessage on
7
- Claude, self-as-advisor on Grok), reuse warm agents. Triggers:
7
+ Claude, Claude CLI chain on Grok), reuse warm agents. Triggers:
8
8
  '/orchestrator-refresh'.
9
9
  ---
10
10
 
@@ -12,8 +12,8 @@ description: >-
12
12
 
13
13
  Detect the host profile first (see Host profiles in
14
14
  [`_shared/advisor/advisor-protocol.md`](../../_shared/advisor/advisor-protocol.md)).
15
- Re-assert the discipline for that host only — do not invent a Claude
16
- `session-advisor` spawn on a Grok host.
15
+ Re-assert the discipline for that host only — do not invent an Agent-tool
16
+ Claude `session-advisor` spawn on a Grok host.
17
17
 
18
18
  1. **You are the orchestrator.** Orchestrate and hold the user conversation;
19
19
  spawn executor subagents to do all the work — every code edit and build or
@@ -23,13 +23,17 @@ Re-assert the discipline for that host only — do not invent a Claude
23
23
  `SendMessage` and receive one of four signals — ENDORSE, CORRECTION, PLAN,
24
24
  or STOP. The orchestrating session routes its own hard decisions the same
25
25
  way and keeps its tool use to orchestration and light verification reads.
26
- - **Grok host:** this session *is* the advisor (self-as-advisor). Do **not**
27
- spawn `session-advisor` and do **not** tell executors to SendMessage a
28
- separate advisor agent. Executors report blockers to this session; answer
29
- with ENDORSE / CORRECTION / PLAN / STOP inline.
26
+ - **Grok host:** the advisor is a max-tier Claude CLI bind owned by this
27
+ session (`claude_chain_runner.py`, Fable high then Opus max). Do **not**
28
+ spawn `session-advisor` via Agent and do **not** tell executors to
29
+ SendMessage a separate advisor agent. Executors report blockers to this
30
+ session; consult the Claude CLI advisor and relay ENDORSE / CORRECTION /
31
+ PLAN / STOP. When the CLI bind is unreachable, fail closed and report to
32
+ the user — do not answer the four signals as this Grok session.
30
33
  3. **Resume before you spawn.** `SendMessage` an existing *executor* agent by
31
34
  name or `agentId` to reuse its warm context; prefer that over a cold spawn.
32
- (On Grok this is executor reuse only — not an advisor spawn.)
35
+ (On Grok this is executor reuse only — advisor re-bind stays on the CLI
36
+ chain path in the shared protocol.)
33
37
  4. **Fresh spawn only for a genuine task switch.** No tool compacts or clears a
34
38
  subagent's context, so a clean context comes from a fresh spawn — never tell
35
39
  an agent to compact.
@@ -28,4 +28,4 @@ Drives a draft PR to convergence by driving the internal passes to clean first
28
28
  - All findings and PR reports state verified facts only — no hedging language.
29
29
  - The GitHub MCP (`pull_request_read`, `pull_request_review_write`) is the primary path for PR inspection; `gh api` is the fallback.
30
30
  - Three step-scoped agents (`fix_executor`, `thread_sweep`, `copilot_watch`) persist across ticks via the `persistent_agents` map in loop state; each tick resumes them with `SendMessage` and spawns a fresh named agent when a stored id is dead.
31
- - The tick delegates shared mechanics to five sibling sub-skills: `reviewer-gates` (opt-out, Copilot quota, Bugbot trigger), `pr-scope-resolve` (target resolution), `pr-fix-protocol` (fix sequence + unresolved-thread sweep), `post-audit-findings` (audit posting), and `pr-loop-lifecycle` (run open/close).
31
+ - The tick delegates shared mechanics to three sibling sub-skills: `reviewer-gates` (opt-out, Copilot quota, Bugbot trigger), `pr-fix-protocol` (fix sequence + unresolved-thread sweep), and `pr-loop-lifecycle` (run open/close). Target resolution happens inline in `reference/per-tick.md` Steps 1 and 1.5. Audit posting follows the `_shared/pr-loop/post-audit-thread-contract.md` contract, run through `_shared/pr-loop/scripts/post_audit_thread.py`.
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: pr-fix-protocol
3
+ description: >-
4
+ Applies reviewer findings to a PR as verified fixes and drives unresolved
5
+ review threads to zero. Invoked by PR-loop orchestrators (pr-converge,
6
+ autoconverge, bugteam, qbug, copilot-review) when a reviewer reports
7
+ findings; not for ad-hoc 'fix this bug' requests outside a PR loop.
8
+ ---
9
+
10
+ # PR Fix Protocol
11
+
12
+ **Core principle:** a finding is addressed only when the fix is pushed, the thread carries a reply, and the thread is resolved — as one unit of work. Anything short of all three leaves a convergence gate stalled.
13
+
14
+ ## How callers invoke this
15
+
16
+ - **Skill-capable contexts** (a lead session that holds the `Skill` tool): `Skill({skill: "pr-fix-protocol", args: "--skill <caller> --pr <URL> --worktree <path> [findings payload or 'sweep']"})`.
17
+ - **Fallback** (a subagent or teammate without the `Skill` tool): the caller's spawn prompt says to read `~/.claude/skills/pr-fix-protocol/SKILL.md` and apply it with the parameters below.
18
+
19
+ The caller passes: its identity, the PR scope, the PR worktree path, this round's findings (or `sweep` for a thread sweep with no fresh findings), and its post-push obligations — which clean-SHA state fields to reset and which reviewers to re-trigger.
20
+
21
+ ## Executor choice
22
+
23
+ - **Single-PR loops** (no shared `state.json`): the lead spawns `Agent(subagent_type: "clean-coder")` to write the fix. Stop when `Agent` is unavailable. A spawned clean-coder starts in its own working directory, so its prompt names the PR worktree path and directs it to edit, stage, and commit there.
24
+ - **Multi-PR orchestration** (shared `state.json`): a per-PR clean-coder teammate owns edits, replies, and state writes; the orchestrator holds back from inline edits. The teammate obligations — reply before writing state, which state fields to set, idle handoff — live in the calling skill's multi-PR reference.
25
+
26
+ Run every git command in the PR worktree. `git add`, `git commit`, and `git push` act on the repo of the current working directory, so a cross-repo PR's fix lands in the PR's repo only when the working directory is its worktree.
27
+
28
+ ## The fix sequence
29
+
30
+ Follow the shared 13-step sequence in [`_shared/pr-loop/fix-protocol.md`](../../_shared/pr-loop/fix-protocol.md) exactly: read each file:line, capture the pre-fix SHA and contents, write a failing test first where the finding has behavior, apply the fix narrowly, `py_compile`, run the post-fix self-audit, stage by explicit path, make one commit, fast-forward push, then reply and resolve atomically per thread. Its Constraints section — narrow scope, keep the commit hooks, preserve helpers — binds every executor.
31
+
32
+ **Reply transport:** the GitHub MCP `add_reply_to_pull_request_comment` is primary. For a script-only context or a multi-PR teammate, the fallback is `python "$HOME/.claude/skills/pr-converge/scripts/post_fix_reply.py" --owner <O> --repo <R> --pr-number <N> --in-reply-to <COMMENT_ID> --body "Fixed in <SHA> — <what changed>"`. Both carry the body shape from [`_shared/pr-loop/audit-reply-template.md`](../../_shared/pr-loop/audit-reply-template.md). For a body-only finding with no inline thread, post a top-level review reply that cites the new HEAD SHA.
33
+
34
+ **Thread resolution:** call `pull_request_review_write(method="resolve_thread", threadId=<PRRT node id>)` right after each reply. Harvest the thread node ids (`PRRT_…`) from `get_review_comments` at fetch time.
35
+
36
+ ## The unresolved-thread sweep (hard gate)
37
+
38
+ A caller advances a phase, records a clean SHA, or marks a PR ready only when the PR carries zero unresolved review threads.
39
+
40
+ ```
41
+ pull_request_read(method="get_review_comments") → filter threads where is_resolved == false
42
+ ```
43
+
44
+ - The filter is purely `is_resolved == false`. Author, anchor commit, and `is_outdated` play no part in the count.
45
+ - `is_outdated` is informational, not a skip flag. GitHub marks a thread outdated when its anchor line changes, yet the concern can still apply to current HEAD — the fix may have moved rather than landed. Verify each outdated thread against current HEAD like any other.
46
+ - Per unresolved thread: verify the concern against current HEAD. The concern holds → fix (this protocol) → reply → resolve. The concern does not hold on current HEAD → reply with a note that explains why → resolve.
47
+ - Code changed during the sweep → push and hand control back to the caller's re-entry phase. Only resolutions and no code → re-run the sweep and keep the caller's state.
48
+
49
+ ## Post-push obligations
50
+
51
+ Every push through this protocol:
52
+
53
+ 1. Re-resolve `current_head` — `git rev-parse HEAD` locally, and the PR `get` call for API-visible state.
54
+ 2. Reset the caller-named clean-SHA fields to null (`bugbot_clean_at`, `code_review_clean_at`, `copilot_clean_at` — whichever the caller tracks). A new HEAD invalidates every prior clean.
55
+ 3. Re-trigger reviewers per the caller's parameter — for Cursor Bugbot the `reviewer-gates` Bugbot flow, for Copilot the caller's request step. Audit-family callers (`bugteam`, `qbug`) skip re-triggering, since their next loop iteration is the reviewer.
56
+
57
+ ## Gotchas
58
+
59
+ - **Reply, then resolve, atomic per thread.** Batching every reply ahead of any resolve, or yielding to the orchestrator between the two, leaves threads half-addressed when a run dies mid-loop.
60
+ - **An unchanged HEAD after step 11 means no commit landed.** Exit `stuck — could not address findings` rather than report the findings as fixed.
61
+ - **A resolved thread with no reply reads as dismissed.** Reviewers and the humans reading the PR need the one-paragraph explanation the template carries.
62
+
63
+ ## Folder map
64
+
65
+ - `SKILL.md` — this file. The step sequence, reply template, and payload shapes live in `_shared/pr-loop/` (`fix-protocol.md`, `audit-reply-template.md`, `gh-payloads.md`); the reply fallback script lives in `pr-converge/scripts/`.
@@ -84,7 +84,7 @@ In Process or a dedicated **Sub-skills** section:
84
84
 
85
85
  | Skill | When | Produces |
86
86
  |---|---|---|
87
- | `/pr-scope-resolve` | Step 1 — resolve the PR target | owner, repo, PR number, head ref |
87
+ | `/reviewer-gates` | Step 1 — gate external reviewers | opt-out, Copilot quota, Bugbot trigger decisions |
88
88
  | `/skill-writer` | Step 4 — author SKILL.md | skill package files |
89
89
 
90
90
  If a listed skill is not installed, respond: `[exact refusal or degrade line]`.
@@ -29,21 +29,25 @@ the CLI fallback — using `team-advisor-agent` as the name and this session as
29
29
  the only consumer (skip the "who you are and your assignment" opener in each
30
30
  consult; a single-consumer session doesn't need it).
31
31
 
32
- **Grok host:** use the self-as-advisor path in the shared protocol: this
33
- session answers ENDORSE / CORRECTION / PLAN / STOP itself. Do not spawn a
34
- Claude `session-advisor` subagent and do not walk the Claude multi-tier
35
- ladder.
32
+ **Grok host:** bind a max-tier Claude advisor through the shared CLI Claude-chain
33
+ in the protocol (Fable high, then Opus max; `claude_chain_runner.py` walks
34
+ `~/.claude/claude-chain.json` for account usage failover). Consult via
35
+ `--resume <session_id>` on that bind. This session is the sole consumer of that
36
+ CLI advisor; skip the multi-consumer opener. When the chain cannot bind or
37
+ reply, fail closed and report to the user — do **not** answer ENDORSE /
38
+ CORRECTION / PLAN / STOP as this Grok session.
36
39
 
37
40
  ## Constraints
38
41
 
39
- - One `team-advisor-agent` per session, owned by this session for its whole
40
- lifecycle (spawn, drift-respawn, shutdown) see
42
+ - One advisor bind per session (`team-advisor-agent` on Claude; one CLI
43
+ `session_id` on Grok), owned by this session for its whole lifecycle
44
+ (spawn or CLI bind, drift re-bind, shutdown) — see
41
45
  [`_shared/advisor/advisor-protocol.md`](../../_shared/advisor/advisor-protocol.md).
42
- - Never spawn the warm agent, or its CLI fallback, at a tier below this
43
- session's own tier.
44
- - The warm agent (or its CLI equivalent) only answers. It never edits a
45
- file, never runs a build or test, and never posts anything on the
46
- session's behalf.
46
+ - Never bind the advisor, or its CLI path, at a tier below the protocol floor
47
+ for this host (Claude: this session's own tier; Grok: Opus floor with Fable
48
+ first).
49
+ - The advisor only answers. It never edits a file, never runs a build or
50
+ test, and never posts anything on the session's behalf.
47
51
 
48
52
  ## File Index
49
53
 
@@ -140,7 +140,8 @@
140
140
  Apply an outside-in BDD reasoning protocol before writing any code. Outside-in BDD is the
141
141
  required development protocol; apply it in place of any Red-Green-Refactor heuristic. The
142
142
  full anti-pattern catalog, Example Mapping algorithm, and solo-developer guidance live in
143
- the bdd-protocol skill; this section carries the core four-phase sequence.
143
+ the long-form BDD references (`~/.claude/docs/BDD_DISCOVERY_PROTOCOL.md`,
144
+ `~/.claude/docs/BDD_SCENARIO_QUALITY.md`); this section carries the core four-phase sequence.
144
145
 
145
146
  Deliberate Discovery. Before writing any specification or code, reason explicitly about
146
147
  what the code should do, what constraints apply, and what concrete examples demonstrate the
@@ -159,8 +160,9 @@
159
160
  it pass. Assess each green state for structural improvement; refactor when a specific
160
161
  naming, cohesion, or duplication problem is identified.
161
162
 
162
- Reference the bdd-protocol skill for Smart and Molak §7.6 patterns, the Example Mapping
163
- algorithm, and guidance on applying this protocol in a solo-developer context.
163
+ Reference `~/.claude/docs/BDD_SCENARIO_QUALITY.md` and `~/.claude/docs/BDD_DISCOVERY_PROTOCOL.md`
164
+ for Smart and Molak §7.6 patterns, the Example Mapping algorithm, and guidance on applying this
165
+ protocol in a solo-developer context.
164
166
  </behavior_protocol>
165
167
 
166
168
  <scope_discipline>
@@ -231,11 +233,10 @@
231
233
  </agent_workflow>
232
234
 
233
235
  <code_review_response>
234
- When responding to GitHub PR review feedback, follow this mandatory protocol using the
235
- pr-review-responder skill.
236
+ When responding to GitHub PR review feedback, follow this mandatory protocol.
236
237
 
237
238
  Fetch all reviewer comments before making any fixes. Obtain the full comment set from the
238
- PR using `gh pr view --comments` or the pr-review-responder skill.
239
+ PR using `gh pr view --comments`.
239
240
 
240
241
  Create a TodoWrite checklist with one item per comment.
241
242
 
@@ -1,32 +0,0 @@
1
- """Tests for validator path verification script."""
2
-
3
- import pytest
4
-
5
- from .verify_paths import extract_validator_paths
6
-
7
-
8
- def test_extract_validator_paths_finds_validator_references() -> None:
9
- """Test that validator references are extracted from markdown content."""
10
- content = """
11
- **Validator:** `validators/import_checks.py`
12
- Some text here.
13
- **Validator:** `validators/style_checks.py`
14
- """
15
-
16
- result = extract_validator_paths(content)
17
-
18
- assert "import_checks.py" in result
19
- assert "style_checks.py" in result
20
-
21
-
22
- def test_extract_validator_paths_deduplicates() -> None:
23
- """Test that duplicate validator references are deduplicated."""
24
- content = """
25
- **Validator:** `validators/import_checks.py`
26
- **Validator:** `validators/import_checks.py`
27
- **Validator:** `validators/import_checks.py`
28
- """
29
-
30
- result = extract_validator_paths(content)
31
-
32
- assert result.count("import_checks.py") == 1
@@ -1,57 +0,0 @@
1
- """Verify all validator paths referenced in SKILL.md exist."""
2
-
3
- import re
4
- import sys
5
- from pathlib import Path
6
-
7
-
8
- SKILL_MD_PATH = Path(__file__).parent.parent.parent / "skills" / "pr-review-responder" / "SKILL.md"
9
- VALIDATORS_DIR = Path(__file__).parent
10
-
11
-
12
- def extract_validator_paths(content: str) -> list[str]:
13
- """Extract validator file paths from SKILL.md content."""
14
- pattern = r"validators[/\\](\w+\.py)"
15
- matches = re.findall(pattern, content)
16
- return list(set(matches))
17
-
18
-
19
- def verify_validators() -> int:
20
- """Verify all referenced validators exist.
21
-
22
- Returns:
23
- Exit code: 0 if all exist, 1 if any missing
24
- """
25
- if not SKILL_MD_PATH.exists():
26
- print(f"ERROR: SKILL.md not found at {SKILL_MD_PATH}")
27
- return 1
28
-
29
- content = SKILL_MD_PATH.read_text(encoding="utf-8")
30
- referenced_validators = extract_validator_paths(content)
31
-
32
- print(f"Found {len(referenced_validators)} validator references in SKILL.md")
33
- print()
34
-
35
- missing = []
36
- for validator_file in sorted(referenced_validators):
37
- validator_path = VALIDATORS_DIR / validator_file
38
- if validator_path.exists():
39
- print(f" [OK] {validator_file}")
40
- else:
41
- print(f" [MISSING] {validator_file}")
42
- missing.append(validator_file)
43
-
44
- print()
45
-
46
- if missing:
47
- print(f"ERROR: {len(missing)} validator(s) missing:")
48
- for validator_file in missing:
49
- print(f" - {validator_file}")
50
- return 1
51
-
52
- print("All referenced validators exist.")
53
- return 0
54
-
55
-
56
- if __name__ == "__main__":
57
- sys.exit(verify_validators())