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.
- package/_shared/advisor/CLAUDE.md +2 -2
- package/_shared/advisor/advisor-protocol.md +35 -27
- package/_shared/advisor/scripts/config/advisor_scripts_constants/model_tier_run_validator_constants.py +3 -2
- package/_shared/advisor/scripts/model_tier_run_validator.py +23 -15
- package/_shared/advisor/scripts/tests/test_model_tier_run_validator.py +81 -17
- package/bin/CLAUDE.md +10 -1
- package/bin/ever-shipped-skills.mjs +70 -0
- package/bin/install.mjs +136 -6
- package/bin/install.prune.test.mjs +457 -0
- package/docs/CODE_RULES.md +1 -1
- package/hooks/blocking/code_rules_enforcer.py +4 -0
- package/hooks/blocking/code_rules_shared.py +82 -0
- package/hooks/blocking/code_rules_test_layout.py +9 -3
- package/hooks/blocking/plain_language_blocker.py +138 -4
- package/hooks/blocking/sensitive_file_protector.py +114 -48
- package/hooks/blocking/tdd_enforcer.py +9 -2
- package/hooks/blocking/test_code_rules_enforcer_scratchpad.py +105 -0
- package/hooks/blocking/test_code_rules_shared.py +181 -0
- package/hooks/blocking/test_plain_language_blocker_allowlist.py +184 -0
- package/hooks/blocking/test_sensitive_file_protector.py +185 -0
- package/hooks/blocking/test_tdd_enforcer_scratchpad.py +105 -0
- package/hooks/hooks_constants/CLAUDE.md +2 -0
- package/hooks/hooks_constants/harness_scratchpad_constants.py +17 -0
- package/hooks/hooks_constants/plain_language_blocker_constants.py +5 -0
- package/hooks/hooks_constants/sensitive_file_protector_constants.py +42 -0
- package/hooks/pyproject.toml +75 -4
- package/hooks/validators/CLAUDE.md +1 -1
- package/hooks/validators/README.md +2 -0
- package/hooks/validators/python_style_checks.py +114 -136
- package/hooks/validators/python_style_helpers.py +95 -0
- package/hooks/validators/test_python_style_checks.py +0 -164
- package/hooks/validators/test_python_style_checks_decorator_gap.py +119 -0
- package/hooks/validators/test_python_style_fixes.py +251 -0
- package/hooks/validators/test_python_style_helpers.py +125 -0
- package/package.json +1 -1
- package/rules/CLAUDE.md +1 -0
- package/rules/anti-corollary-tests.md +69 -0
- package/rules/bdd.md +1 -3
- package/rules/code-reviews.md +1 -1
- package/rules/gh-paginate.md +1 -1
- package/rules/plain-language.md +2 -0
- package/skills/CLAUDE.md +4 -3
- package/skills/autoconverge/workflow/converge.mjs +2 -2
- package/skills/bugteam/reference/README.md +2 -3
- package/skills/closeout/SKILL.md +153 -0
- package/skills/closeout/reference/handoff-prompt-template.md +72 -0
- package/skills/closeout/reference/issue-body-templates.md +108 -0
- package/skills/closeout/reference/pii-redaction-checklist.md +36 -0
- package/skills/orchestrator/SKILL.md +27 -21
- package/skills/orchestrator-refresh/SKILL.md +12 -8
- package/skills/pr-converge/CLAUDE.md +1 -1
- package/skills/pr-fix-protocol/SKILL.md +65 -0
- package/skills/skill-builder/references/skill-modularity.md +1 -1
- package/skills/team-advisor/SKILL.md +15 -11
- package/system-prompts/software-engineer.xml +7 -6
- package/hooks/validators/test_verify_paths.py +0 -32
- 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:
|
|
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:
|
|
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
|
|
58
|
-
|
|
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
|
|
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
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
shared advisor, not just this
|
|
94
|
-
shared advisor's lifecycle end
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
|
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,
|
|
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
|
|
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:**
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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 —
|
|
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
|
|
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
|
-
| `/
|
|
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:**
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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`
|
|
40
|
-
|
|
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
|
|
43
|
-
session's own tier
|
|
44
|
-
|
|
45
|
-
|
|
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
|
|
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
|
|
163
|
-
algorithm, and guidance on applying this
|
|
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
|
|
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
|
|
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())
|