claude-dev-env 2.17.0 → 2.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/.agents/skills/AGENTS.md +4 -4
  2. package/.agents/skills/_shared/AGENTS.md +1 -0
  3. package/.agents/skills/_shared/pr-loop/AGENTS.md +1 -0
  4. package/.agents/skills/_shared/pr-loop/preflight-proposal.contract.test.mjs +89 -0
  5. package/.agents/skills/_shared/pr-loop/preflight-proposal.md +5 -0
  6. package/.agents/skills/orchestrator/SKILL.md +6 -4
  7. package/.agents/skills/orchestrator-refresh/SKILL.md +9 -5
  8. package/.agents/skills/pr-cleanup/SKILL.md +17 -85
  9. package/.agents/skills/pr-cleanup/reference/process-inventory.md +15 -0
  10. package/.agents/skills/pr-cleanup/reference/task-seeds.md +20 -0
  11. package/.agents/skills/{name-by-capability-audit → pr-name-by-capability}/SKILL.md +18 -12
  12. package/.agents/skills/{name-by-capability-audit → pr-name-by-capability}/reference/offense-examples.md +1 -1
  13. package/.agents/skills/{name-by-capability-audit → pr-name-by-capability}/reference/task-seeds.md +3 -2
  14. package/.agents/skills/pr-refinement/SKILL.md +31 -0
  15. package/.agents/skills/{shared-extraction-audit → pr-shared-extraction}/SKILL.md +24 -7
  16. package/.agents/skills/{small-cl → pr-small-cl}/SKILL.md +1 -1
  17. package/.agents/skills/prototype/scripts/test_probe_sandbox_safety.py +33 -5
  18. package/.agents/skills/skill-builder/SKILL.md +1 -0
  19. package/.agents/skills/team-advisor/SKILL.md +5 -5
  20. package/.agents/skills-archived/bugteam/SKILL.md +1 -1
  21. package/.agents/skills-archived/bugteam/test_skill_additions.py +1 -1
  22. package/.agents/skills-archived/comments/SKILL.md +1 -1
  23. package/.agents/skills-archived/descriptions/SKILL.md +1 -1
  24. package/.agents/skills-archived/reviews/SKILL.md +1 -1
  25. package/AGENTS.md +1 -1
  26. package/_shared/advisor/AGENTS.md +5 -5
  27. package/_shared/advisor/advisor-protocol.md +54 -31
  28. package/_shared/advisor/reference/advisor-block.md +5 -1
  29. package/_shared/advisor/reference/consult-format.md +1 -1
  30. package/_shared/advisor/reference/identity.md +28 -0
  31. package/_shared/advisor/reference/lifecycle.md +8 -1
  32. package/_shared/advisor/reference/sol-rung.md +12 -7
  33. package/_shared/advisor/reference/spawn-walk-log.md +6 -5
  34. package/_shared/advisor/reference/third-party-bind.md +5 -6
  35. package/_shared/advisor/reference/warm-up.md +9 -2
  36. package/_shared/advisor/scripts/codex_sol_advisor.py +66 -11
  37. package/_shared/advisor/scripts/config/advisor_scripts_constants/advisor_route_constants.py +9 -0
  38. package/_shared/advisor/scripts/config/advisor_scripts_constants/model_tier_run_validator_constants.py +16 -4
  39. package/_shared/advisor/scripts/config/advisor_scripts_constants/sol_advisor_constants.py +11 -10
  40. package/_shared/advisor/scripts/model_tier_run_validator.py +50 -23
  41. package/_shared/advisor/scripts/tests/test_codex_sol_advisor.py +108 -3
  42. package/_shared/advisor/scripts/tests/test_model_tier_run_validator.py +171 -82
  43. package/_shared/advisor/scripts/tests/test_tier_model_ids.py +43 -0
  44. package/_shared/advisor/scripts/tier_model_ids.py +75 -7
  45. package/_shared/pr-loop/AGENTS.md +2 -1
  46. package/_shared/pr-loop/preflight-proposal.md +56 -0
  47. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_gate_running.py +47 -4
  48. package/_shared/pr-loop/worker-spawn.md +4 -3
  49. package/bin/ever-shipped-skills.mjs +14 -0
  50. package/bin/install-constants.mjs +5 -0
  51. package/bin/install.agents-home.test.mjs +23 -0
  52. package/bin/install.codex-rules.test.mjs +61 -6
  53. package/bin/install.mjs +57 -9
  54. package/bin/install.prune.test.mjs +65 -3
  55. package/bin/install.test.mjs +202 -2
  56. package/docs/CODE_RULES.md +4 -0
  57. package/docs/references/team-advisor-skill.md +2 -2
  58. package/hooks/advisory/migration_safety_advisor.py +14 -14
  59. package/hooks/advisory/test_migration_safety_advisor.py +120 -0
  60. package/hooks/atomic_file_writer.py +81 -0
  61. package/hooks/blocking/AGENTS.md +2 -1
  62. package/hooks/blocking/code_rules_banned_identifiers.py +55 -4
  63. package/hooks/blocking/code_rules_enforcer_test_support.py +92 -0
  64. package/hooks/blocking/destructive_command_blocker.py +8 -7
  65. package/hooks/blocking/pre_tool_use_dispatcher.py +11 -7
  66. package/hooks/blocking/precommit_code_rules_gate.py +14 -139
  67. package/hooks/blocking/sensitive_file_protector.py +8 -6
  68. package/hooks/blocking/session_edit_stage_gate.py +31 -1
  69. package/hooks/blocking/test_claude_md_orphan_file_blocker.py +171 -1
  70. package/hooks/blocking/test_code_rules_enforcer_agent_home_tooling.py +37 -12
  71. package/hooks/blocking/test_code_rules_enforcer_banned_noun_word.py +54 -0
  72. package/hooks/blocking/test_code_rules_enforcer_duplicate_body_hook_routing.py +15 -53
  73. package/hooks/blocking/test_code_rules_enforcer_ephemeral.py +13 -62
  74. package/hooks/blocking/test_code_rules_enforcer_narrow_edit.py +308 -0
  75. package/hooks/blocking/test_code_rules_enforcer_precheck_forecast.py +14 -71
  76. package/hooks/blocking/test_code_rules_enforcer_scratchpad.py +14 -16
  77. package/hooks/blocking/test_code_rules_enforcer_split_entry_2.py +31 -46
  78. package/hooks/blocking/test_code_rules_enforcer_stage.py +192 -0
  79. package/hooks/blocking/test_code_rules_enforcer_zero_payload_alias_hook_routing.py +13 -59
  80. package/hooks/blocking/test_destructive_command_blocker_deny_mode.py +42 -25
  81. package/hooks/blocking/test_destructive_command_blocker_no_verify.py +58 -38
  82. package/hooks/blocking/test_docstring_rule_gate_count_blocker.py +113 -1
  83. package/hooks/blocking/test_env_var_table_code_drift_blocker.py +70 -3
  84. package/hooks/blocking/test_hook_subprocess_support.py +296 -0
  85. package/hooks/blocking/test_package_inventory_stale_blocker.py +1 -1
  86. package/hooks/blocking/test_pii_scanner.py +81 -0
  87. package/hooks/blocking/test_pre_tool_use_dispatcher.py +32 -3
  88. package/hooks/blocking/test_precommit_code_rules_gate.py +11 -16
  89. package/hooks/blocking/test_precommit_code_rules_gate_native_owner.py +168 -0
  90. package/hooks/blocking/test_pytest_testpaths_orphan_blocker.py +25 -18
  91. package/hooks/blocking/test_sensitive_file_protector.py +145 -5
  92. package/hooks/blocking/test_session_edit_stage_gate_staging.py +64 -0
  93. package/hooks/blocking/test_session_edit_stage_gate_support.py +204 -0
  94. package/hooks/blocking/test_session_edit_stage_gate_tracker.py +116 -0
  95. package/hooks/blocking/test_shared_stdin_adoption.py +31 -20
  96. package/hooks/blocking/test_test_preflight_check.py +80 -0
  97. package/hooks/git-hooks/pre_commit.py +6 -2
  98. package/hooks/git-hooks/test_pre_push.py +57 -0
  99. package/hooks/hooks_constants/AGENTS.md +3 -1
  100. package/hooks/hooks_constants/atomic_file_writer_constants.py +4 -0
  101. package/hooks/hooks_constants/banned_identifiers_constants.py +1 -0
  102. package/hooks/hooks_constants/destructive_command_environment_constants.py +18 -0
  103. package/hooks/hooks_constants/destructive_command_segment_constants.py +1 -11
  104. package/hooks/hooks_constants/hardcoded_user_path_constants.py +9 -3
  105. package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +1 -1
  106. package/hooks/hooks_constants/sensitive_file_protector_constants.py +2 -4
  107. package/hooks/json_file_reader.py +22 -0
  108. package/hooks/pending_sidecars.py +33 -0
  109. package/hooks/test_atomic_file_writer.py +73 -0
  110. package/hooks/test_json_file_reader.py +24 -0
  111. package/hooks/test_pending_sidecars.py +25 -0
  112. package/package.json +1 -1
  113. /package/.agents/skills/{name-by-capability-audit → pr-name-by-capability}/reference/fetch-commands.md +0 -0
  114. /package/.agents/skills/{name-by-capability-audit → pr-name-by-capability}/reference/report-template.md +0 -0
  115. /package/.agents/skills/{name-by-capability-audit → pr-name-by-capability}/reference/rule-checklist.md +0 -0
  116. /package/.agents/skills/{shared-extraction-audit → pr-shared-extraction}/reference/examples.md +0 -0
  117. /package/.agents/skills/{shared-extraction-audit → pr-shared-extraction}/reference/offense-taxonomy.md +0 -0
@@ -35,15 +35,15 @@ contracts, runtime scripts). Map: `skills/_shared/.claude/CLAUDE.md`. End-of-run
35
35
 
36
36
  **PR review and convergence**
37
37
 
38
- - `shared-extraction-audit` — audits workflow packages for helpers that belong in shared libraries; extracts in small tested CLs
39
- - `name-by-capability-audit` — audits PR paths/titles for driver/motive words on reusable capability code
38
+ - `pr-shared-extraction` — audits workflow packages for helpers that belong in shared libraries; extracts in small tested CLs
39
+ - `pr-name-by-capability` — audits PR paths/titles for driver/motive words on reusable capability code
40
40
  - `review-tier` — classifies `review_tier_constants` from change axes, hard triggers, and user overrides
41
41
  - `review-router` — resolves and arms one supported `route_review_config` route through the registered Agent|Task gate
42
- - `pr-cleanup` — one-agent end-to-end PR cleanup: extraction → naming → sr-loop → small-cl; apply and validate fixes as they return
42
+ - `pr-cleanup` — one-agent end-to-end PR cleanup: extraction → naming → sr-loop → pr-small-cl; apply and validate fixes as they return
43
43
  - `autoconverge` — autonomous single-run workflow that drives a PR to ready
44
44
  - `e-code-review` — max-recall code review at a selectable effort level
45
45
  - `e-simplify` — cleanup-only pass on the current diff
46
- - `small-cl` — the Small CLs guide for scope and split decisions
46
+ - `pr-small-cl` — the Small CLs guide for scope and split decisions
47
47
 
48
48
  **Research and discovery**
49
49
  - `everything-search` — file-system search via the Everything `es.exe` CLI on Windows
@@ -37,6 +37,7 @@
37
37
  | `pr-loop/gh-payloads.md` | `@~/.claude/_shared/pr-loop/gh-payloads.md` |
38
38
  | `pr-loop/post-audit-thread-contract.md` | `@~/.claude/_shared/pr-loop/post-audit-thread-contract.md` |
39
39
  | `pr-loop/precatch-rubric.md` | `@~/.claude/_shared/pr-loop/precatch-rubric.md` |
40
+ | `pr-loop/preflight-proposal.md` | `@~/.claude/_shared/pr-loop/preflight-proposal.md` |
40
41
  | `pr-loop/state-schema.md` | `@~/.claude/_shared/pr-loop/state-schema.md` |
41
42
  | `pr-loop/worker-spawn.md` | `@~/.claude/_shared/pr-loop/worker-spawn.md` |
42
43
  | `pr-loop/scripts/RUNTIME_SCRIPTS.md` | `@~/.claude/_shared/pr-loop/scripts/` |
@@ -26,6 +26,7 @@ Open a stub, then load the `@` target:
26
26
  | `gh-payloads.md` | `@~/.claude/_shared/pr-loop/gh-payloads.md` |
27
27
  | `post-audit-thread-contract.md` | `@~/.claude/_shared/pr-loop/post-audit-thread-contract.md` |
28
28
  | `precatch-rubric.md` | `@~/.claude/_shared/pr-loop/precatch-rubric.md` |
29
+ | `preflight-proposal.md` | `@~/.claude/_shared/pr-loop/preflight-proposal.md` |
29
30
  | `state-schema.md` | `@~/.claude/_shared/pr-loop/state-schema.md` |
30
31
  | `worker-spawn.md` | `@~/.claude/_shared/pr-loop/worker-spawn.md` |
31
32
  | `scripts/RUNTIME_SCRIPTS.md` | `@~/.claude/_shared/pr-loop/scripts/` |
@@ -0,0 +1,89 @@
1
+ import assert from 'node:assert/strict'
2
+ import { readFileSync } from 'node:fs'
3
+ import { dirname, resolve } from 'node:path'
4
+ import test from 'node:test'
5
+ import { fileURLToPath } from 'node:url'
6
+
7
+ const THIS_DIRECTORY = dirname(fileURLToPath(import.meta.url))
8
+ const canonicalContractSource = readFileSync(
9
+ resolve(THIS_DIRECTORY, '../../../../_shared/pr-loop/preflight-proposal.md'),
10
+ 'utf8',
11
+ )
12
+ const sharedSkillSource = readFileSync(
13
+ resolve(THIS_DIRECTORY, '../../pr-shared-extraction/SKILL.md'),
14
+ 'utf8',
15
+ )
16
+ const capabilitySkillSource = readFileSync(
17
+ resolve(THIS_DIRECTORY, '../../pr-name-by-capability/SKILL.md'),
18
+ 'utf8',
19
+ )
20
+ const capabilityTaskSeedsSource = readFileSync(
21
+ resolve(THIS_DIRECTORY, '../../pr-name-by-capability/reference/task-seeds.md'),
22
+ 'utf8',
23
+ )
24
+
25
+ const allSkillContracts = [
26
+ {
27
+ name: 'shared extraction audit',
28
+ skillSource: sharedSkillSource,
29
+ invocationPattern: /pr-shared-extraction preflight-proposal/,
30
+ classificationPattern: /priority and target/,
31
+ expectedDefaultBehavior: 'applies the prioritized fix band by default',
32
+ },
33
+ {
34
+ name: 'name by capability audit',
35
+ skillSource: capabilitySkillSource,
36
+ invocationPattern: /pr-name-by-capability preflight-proposal/,
37
+ classificationPattern: /violation or OK-driver classification/,
38
+ expectedDefaultBehavior: 'applies the suggested rename direction by default',
39
+ },
40
+ ]
41
+
42
+ function assertProposalAdapter(skillContract) {
43
+ const preflightRoutingOffset = skillContract.skillSource.indexOf('`preflight-proposal`')
44
+ const reportOnlyRoutingOffset = skillContract.skillSource.indexOf('`audit-only`')
45
+
46
+ assert.ok(preflightRoutingOffset >= 0, `${skillContract.name} selects proposal mode`)
47
+ assert.ok(preflightRoutingOffset < reportOnlyRoutingOffset, `${skillContract.name} routes proposal mode first`)
48
+ assert.match(skillContract.skillSource, skillContract.invocationPattern)
49
+ assert.match(skillContract.skillSource, skillContract.classificationPattern)
50
+ assert.match(skillContract.skillSource, new RegExp(skillContract.expectedDefaultBehavior))
51
+ }
52
+
53
+ function assertTaskRoutingAndNormalMode() {
54
+ assert.match(sharedSkillSource, /Register this checklist with `update_plan`/)
55
+ assert.match(capabilitySkillSource, /Register every bullet from `reference\/task-seeds\.md` with `update_plan`/)
56
+ assert.match(capabilityTaskSeedsSource, /Register each item with `update_plan`/)
57
+ assert.doesNotMatch(sharedSkillSource, /TodoWrite|TaskCreate/)
58
+ assert.doesNotMatch(capabilitySkillSource, /TodoWrite|TaskCreate/)
59
+ assert.doesNotMatch(capabilityTaskSeedsSource, /TodoWrite|TaskCreate/)
60
+ assert.match(sharedSkillSource, /audit-only` is report-only/)
61
+ assert.match(capabilitySkillSource, /audit-only` is report-only/)
62
+ }
63
+
64
+ function assertSharedProposalContract(contractSource) {
65
+ assert.match(contractSource, /caller-supplied isolated worktree/)
66
+ assert.match(contractSource, /resolved PR number/)
67
+ assert.match(contractSource, /immutable base SHA/)
68
+ assert.match(contractSource, /immutable head SHA/)
69
+ assert.match(contractSource, /exact `base_sha\.\.\.head_sha` range/)
70
+ assert.match(contractSource, /require exact equality with the head SHA/)
71
+ assert.match(contractSource, /immutable proposal identity/)
72
+ assert.match(contractSource, /deterministic diff hash/)
73
+ assert.match(contractSource, /changed paths/)
74
+ assert.match(contractSource, /exact tests and outcomes/)
75
+ assert.match(contractSource, /selected-candidate-ready proposal evidence/)
76
+ assert.match(contractSource, /selected or dispositioned proposal collection/)
77
+ assert.match(contractSource, /Reapplication uses exactly the selected records/)
78
+ }
79
+
80
+ test('audit modes retain their normal routing behavior', () => {
81
+ assertTaskRoutingAndNormalMode()
82
+ })
83
+
84
+ test('one shared contract defines proposal evidence for both audit skills', () => {
85
+ for (const eachSkillContract of allSkillContracts) {
86
+ assertProposalAdapter(eachSkillContract)
87
+ }
88
+ assertSharedProposalContract(canonicalContractSource)
89
+ })
@@ -0,0 +1,5 @@
1
+ # Preflight proposal contract
2
+
3
+ **Canonical home:**
4
+
5
+ @~/.claude/_shared/pr-loop/preflight-proposal.md
@@ -122,9 +122,11 @@ pending, or when the tool is `CronCreate`.
122
122
  `rearm_pending` when already active, but still do not re-arm.)
123
123
  2. **Bind the shared advisor before any executor.** Follow
124
124
  [`_shared/advisor/advisor-protocol.md`](../../_shared/advisor/advisor-protocol.md)
125
- end to end: detect the host profile, compute the floor from the
125
+ end to end: name the session identity, compute the floor from the
126
126
  orchestrator consumer set — this session plus every tier in the
127
- routing table (its Model floor section) — walk the ladder top-down,
127
+ routing table (its Model floor section) — walk the ladder for that
128
+ host (Claude: Fable first, then Sol when Fable is out of usage;
129
+ Codex: Sol in-session; ThirdParty: headless Fable then Sol),
128
130
  and fail closed when nothing binds. This session owns the advisor's
129
131
  whole lifecycle (its Lifecycle ownership section); executors only ever
130
132
  message the warm agent or report here, and an executor that finds the
@@ -261,8 +263,8 @@ Routing rules:
261
263
  way — the coding spawn stops and the orchestrator reports it.
262
264
  - Host detection follows
263
265
  [`_shared/advisor/advisor-protocol.md`](../../_shared/advisor/advisor-protocol.md)
264
- (Host profiles section, `detect_host_profile`) — the sole detection
265
- system, with no second one.
266
+ (Host profiles section, `resolve_session_identity` then
267
+ `detect_host_profile`) — the sole detection system, with no second one.
266
268
  - Resume a warm workflow agent before creating a new workflow run when
267
269
  the warm agent holds the relevant context.
268
270
  - Review and verification workflows apply the [review guide](../reviews/SKILL.md#review-workflow).
@@ -10,10 +10,10 @@ description: >-
10
10
 
11
11
  # Orchestrator Refresh
12
12
 
13
- Detect the host profile first (see Host profiles in
13
+ Name the session identity first (see Host profiles in
14
14
  [`_shared/advisor/advisor-protocol.md`](../../_shared/advisor/advisor-protocol.md)).
15
15
  Re-assert the discipline for that host only — do not invent an Agent-tool
16
- Claude `session-advisor` spawn on a third-party host.
16
+ Claude `session-advisor` spawn on a Codex or third-party host.
17
17
 
18
18
  ## 0. status_gate first (deterministic)
19
19
 
@@ -94,9 +94,13 @@ once, and reports the unreachable advisor.
94
94
  the protocol's warm-up rule states;
95
95
  `hooks/blocking/fable_spawn_gate.py` denies a fable spawn whose
96
96
  prompt lacks it.
97
- - **Third-party host:** advisor is a max-tier Claude CLI bind owned
98
- by this session (`claude_chain_runner.py`, Fable high then Opus
99
- max). Do **not** spawn `session-advisor` via Agent. Executors
97
+ - **Codex host:** advisor is a native in-session Sol subagent owned
98
+ by this session. Do **not** spawn Claude `session-advisor` via
99
+ Agent. Executors consult that Sol subagent in-session. If Sol does
100
+ not bind, fail closed.
101
+ - **Third-party host:** advisor is a Claude CLI bind owned
102
+ by this session (`claude_chain_runner.py`, Fable then Sol when Fable
103
+ is out of usage, both at `ADVISOR_EFFORT`). Do **not** spawn `session-advisor` via Agent. Executors
100
104
  report blockers here; consult the CLI advisor and relay signals.
101
105
  If the CLI bind is unreachable, fail closed — do not answer the
102
106
  four signals as this third-party session.
@@ -1,99 +1,31 @@
1
1
  ---
2
2
  name: pr-cleanup
3
- description: >-
4
- Clean a PR end-to-end with one coding agent: shared-extraction-audit,
5
- name-by-capability-audit, sr-loop, then small-cl — apply and validate fixes
6
- as they return. Use when the user asks for /pr-cleanup or full PR cleanup
7
- (place, name, converge, then shrink).
3
+ description: Refine a pull request, then run the final simplify and code-review loop. Use when the user asks for /pr-cleanup or full PR cleanup.
8
4
  ---
9
5
 
10
- # PR cleanup
6
+ # PR Cleanup
11
7
 
12
- One coding agent cleans a pull request end-to-end: put code in the right place,
13
- name it for what it does, run the converging cleanup loop, then shrink the
14
- change into a reviewable size.
8
+ Run `pr-refinement`, then run `sr-loop` on its resulting pull request or stack.
15
9
 
16
- This skill is host-neutral. Any coding agent that can edit the PR head, run
17
- scoped tests, and invoke the composed skills may run it.
10
+ ## Workflow
18
11
 
19
- ## When to use
12
+ 1. Resolve the target pull request and use its head worktree.
13
+ 2. Run `pr-refinement`. It owns extraction, capability naming, in-place updates, and a required replacement stack.
14
+ 3. Run `sr-loop` on every resulting pull request. Apply findings, run scoped tests, commit, and push each validated change.
15
+ 4. Keep every pull request draft. Keep merge authority with the user.
20
16
 
21
- - `/pr-cleanup <PR>` or “run pr-cleanup on this PR”
22
- - A PR needs extraction + naming + sr-loop + a smaller reviewable slice in one pass
17
+ ## Promotion gates
23
18
 
24
- ## Inputs
19
+ Run preflight work in isolated worktrees from the recorded parent SHA. Apply selected changes in the parent worktree.
25
20
 
26
- - Target: PR URL, number, or branch (required). Missing ask:
27
- `Give a GitHub PR number or URL for pr-cleanup.`
28
- - Repo: take from the PR URL when given; otherwise the user’s default monitored repo
21
+ Before promoting a child, merge the exact parent-ready SHA. Prove that SHA is an ancestor of the child head. Rerun the child tests, `e-simplify`, and `e-code-review` after the merge.
29
22
 
30
- ## Composition (run in this order)
31
-
32
- | Step | Skill | Role |
33
- |------|--------|------|
34
- | 1 | `shared-extraction-audit` | Wrong *place* (workflow package vs shared library) |
35
- | 2 | `name-by-capability-audit` | Wrong *name* (driver word on reusable capability) |
36
- | 3 | `sr-loop` / `e-simplify` then `e-code-review` | Converging simplify + high-effort review with `--fix` |
37
- | 4 | `small-cl` | Split / shrink into a focused reviewable PR |
38
-
39
- All four run under **one coding agent session** on the same worktree / PR head.
40
- For sr-loop advisor consults, bind `team-advisor` as a second session at equal
41
- tier when the host supports it (see `team-advisor` and the advisor docs).
42
-
43
- ## Fix-as-you-go (required)
44
-
45
- Some of these skills can report without changing code. For **pr-cleanup**, that
46
- is not enough:
47
-
48
- 1. **Stream findings** — as each audit/loop returns an item (offense, rename,
49
- simplify fix, review finding), treat it as work to do now, not a backlog.
50
- 2. **Apply the fix** on the PR head (or the first small-cl increment if already
51
- splitting) before moving on to the next item when practical.
52
- 3. **Validate** after each applied fix: scoped tests beside touched files (or
53
- `py_compile` / package tests when there is no adjacent suite). No test theater.
54
- 4. **Commit + push** after each validated changing pass (one concern per commit
55
- when possible; keep the PR draft).
56
- 5. **Do not** finish with an audit-only report while known P0/P1 fixes sit
57
- unapplied — either fix them or hard-block with why.
58
-
59
- If the user says **audit-only**, stop after reports and skip apply / small-cl.
60
-
61
- ## Process
62
-
63
- 1. Resolve PR → convert to draft if needed; clean worktree of the PR head;
64
- never mark ready for review.
65
- 2. Run the four composed skills in order on that head:
66
- - `shared-extraction-audit` in the **implement** band (not audit-only)
67
- - `name-by-capability-audit`; apply clear rename directions (or ones the user
68
- already approved), noting rename direction in the commit message
69
- - `sr-loop`: Phase A `e-simplify`, Phase B `e-code-review` at **xhigh** with
70
- `--fix` (not the default low); consult `team-advisor` before the first
71
- write and after writes + validation
72
- - Apply fixes as each pass returns findings; validate → commit → push
73
- 3. After the loop converges (or nits-only stop): run **small-cl** — identify the
74
- first coherent reviewable increment; if the PR is still too wide, split or
75
- retitle/scope per small-cl (do not invent extra PRs unless the user asked).
76
- 4. Return the finish report below. Merge-ready email / chat delivery is owned by
77
- the caller (for example a PR monitor host), not this skill.
78
-
79
- ## Hard rules
80
-
81
- - No test theater.
82
- - Real spawn/behavior validation when the PR claims an external binary path.
83
- - Prefer cleanup; functional only for correctness. Label each commit
84
- `cleanup` vs `functional`.
85
- - Keep the PR draft. Never mark ready for review during this skill.
86
- - Extraction before rename when both apply to the same symbol (move, then name
87
- the new home).
88
- - small-cl last — shrink only after place / name / cleanup are settled enough
89
- that the slice is honest.
23
+ Use `reference/task-seeds.md` and `reference/process-inventory.md` to record promotion evidence.
90
24
 
91
25
  ## Finish report
92
26
 
93
- - PR / repo / starting_sha / ending_sha
94
- - Per step: extraction findings applied, naming violations applied, sr-loop
95
- passes + commits, small-cl outcome (kept / split plan)
96
- - `commits_pushed` with cleanup|functional labels
97
- - `validation_ran` + outcomes
98
- - `hard_block` or null
99
- - `draft_still: true`
27
+ - Pull request or stack URLs.
28
+ - `pr-refinement` outcome.
29
+ - `sr-loop` passes, commits, and validation results.
30
+ - Parent-ready and child-ready SHAs when a child is promoted.
31
+ - Remaining hard block, or `null`.
@@ -0,0 +1,15 @@
1
+ # PR cleanup process inventory
2
+
3
+ | Step | Class | Home | Evidence | Paired test |
4
+ |---|---|---|---|---|
5
+ | Resolve PR and immutable parent SHA | deterministic | `task-seed:reference/task-seeds.md` | Target record and parent SHA | task-tool |
6
+ | Create isolated preflight worktrees | deterministic | `task-seed:reference/task-seeds.md` | Worktree paths and base SHA | task-tool |
7
+ | Run parallel preflight streams | borderline | `SKILL.md` and `task-seed:reference/task-seeds.md` | Stream reports and worker availability | task-tool |
8
+ | Apply or disposition findings | judgment | `SKILL.md` and `task-seed:reference/task-seeds.md` | Changed diff or exact disposition | task-tool |
9
+ | Validate parent head | deterministic | `task-seed:reference/task-seeds.md` | Scoped test and confirmation results | task-tool |
10
+ | Promote parent and record exact Ready SHA | deterministic | `task-seed:reference/task-seeds.md` | Remote parent Ready state and SHA | task-tool |
11
+ | Merge exact parent SHA into child | deterministic | `task-seed:reference/task-seeds.md` | Child merge commit and parent SHA | task-tool |
12
+ | Prove parent SHA ancestry | deterministic | `task-seed:reference/task-seeds.md` | `git merge-base --is-ancestor` exit code `0` | task-tool |
13
+ | Reapply relevant fixes to child | judgment | `SKILL.md` and `task-seed:reference/task-seeds.md` | Child diff and reapplication record | task-tool |
14
+ | Validate child and rerun confirmations | deterministic | `task-seed:reference/task-seeds.md` | New child-head tests, simplify, and review results | task-tool |
15
+ | Promote child and report | deterministic | `task-seed:reference/task-seeds.md` | Child Ready state and finish report | task-tool |
@@ -0,0 +1,20 @@
1
+ # PR cleanup task seeds
2
+
3
+ Register each numbered item as one session task before work starts. Complete
4
+ each task with evidence from the stated gate.
5
+
6
+ 1. Resolve the target PR, repository, parent head SHA, and child boundary.
7
+ 2. Create isolated preflight worktrees from the immutable parent preflight SHA.
8
+ 3. Run the shared-extraction, capability-name, `e-simplify`, and `e-code-review` preflight streams in parallel when available.
9
+ 4. Record each stream's worktree, base SHA, findings, proposed patch, and validation evidence.
10
+ 5. Keep parent merge, rebase, push, and Ready operations unavailable during preflight.
11
+ 6. Select, apply, validate, or exactly disposition every actionable preflight finding in the one-agent parent cleanup worktree.
12
+ 7. Run parent scoped tests and cleanup/review confirmation checks.
13
+ 8. Promote the parent to Ready and record the exact remote `parent_ready_sha`.
14
+ 9. Create the child from its intended pre-parent base and merge the exact `parent_ready_sha`.
15
+ 10. Prove `parent_ready_sha` is an ancestor of the child head and record the exit code.
16
+ 11. Reapply every relevant preflight fix to the child.
17
+ 12. Run child scoped tests on the new child head.
18
+ 13. Rerun `e-simplify` and `e-code-review` on the new child head.
19
+ 14. Promote the child to Ready after all child evidence passes.
20
+ 15. Write the finish report with SHAs, evidence, states, and hard blocks.
@@ -1,17 +1,26 @@
1
1
  ---
2
- name: name-by-capability-audit
2
+ name: pr-name-by-capability
3
3
  description: >-
4
4
  Audit a GitHub PR for name-by-capability violations: driver/motive words on
5
5
  reusable capability modules (queues and report routers may keep the driver
6
6
  word), then apply capability-oriented renames by default. Triggers:
7
- /name-by-capability-audit, name-by-capability audit, audit PR for naming, name
7
+ /pr-name-by-capability, name-by-capability audit, audit PR for naming, name
8
8
  by capability, capability naming review, cert_fix rename check, driver word in
9
9
  package name.
10
10
  ---
11
11
 
12
12
  # Name-by-Capability Audit
13
13
 
14
- Audit a GitHub PR against the **name-by-capability** rule. Inspect paths and title wording for driver/motive words on reusable capability code, report findings with a rename direction, and apply the suggested renames by default. An explicit audit-only request ends after the report.
14
+ Audit a GitHub PR against the **name-by-capability** rule. Inspect paths and title wording for driver or motive words on reusable capability code, and report violations with capability-oriented rename directions.
15
+
16
+ ## Mode routing
17
+
18
+ First-match routing selects the mode before the audit steps:
19
+
20
+ 1. `preflight-proposal` runs `pr-name-by-capability preflight-proposal <pr_number> --base-sha <base_sha> --head-sha <head_sha> --worktree <isolated_worktree>` under the [shared preflight proposal contract](../_shared/pr-loop/preflight-proposal.md). Record each finding with violation or OK-driver classification.
21
+ 2. `audit-only` is report-only and ends after the findings report.
22
+ 3. A user-supplied rename or fix direction follows the existing normal fix workflow.
23
+ 4. Normal mode applies the suggested rename direction by default.
15
24
 
16
25
  ## Gotchas
17
26
 
@@ -21,15 +30,10 @@ Audit a GitHub PR against the **name-by-capability** rule. Inspect paths and tit
21
30
 
22
31
  ## When this applies
23
32
 
24
- - User invokes `/name-by-capability-audit <PR>` or asks to audit a PR for name-by-capability / capability naming.
33
+ - User invokes `/pr-name-by-capability <PR>` or asks to audit a PR for name-by-capability / capability naming.
25
34
  - PR adds or renames packages/modules, or frames a general shared operation with a driver/motive word (`cert_fix`, `cert_closeout`, `portal`, `export`, …).
26
35
 
27
- **First match wins:**
28
-
29
- - Missing PR number or URL → respond exactly: `Give a GitHub PR number or URL to audit for name-by-capability.`
30
- - User requests audit-only → finish the audit report and stop.
31
- - User gives a rename or fix direction → finish the audit report, then apply the direction they gave.
32
- - A violation with no user-supplied direction → finish the audit report, then apply the suggested rename direction by default.
36
+ A missing PR number or URL returns exactly: `Give a GitHub PR number or URL to audit for name-by-capability.` Resolved targets follow **Mode routing**.
33
37
 
34
38
  ## Constraints
35
39
 
@@ -39,7 +43,7 @@ Audit a GitHub PR against the **name-by-capability** rule. Inspect paths and tit
39
43
 
40
44
  ## Process
41
45
 
42
- Register every bullet from `reference/task-seeds.md` on the host task tool (`TodoWrite` / `TaskCreate`). Mark each complete with evidence. Follow those seeds in order — do not restate them here.
46
+ Register every bullet from `reference/task-seeds.md` with `update_plan`. Mark each complete with evidence. Follow those seeds in order — do not restate them here.
43
47
 
44
48
  Load order for the rule: if `docs/agents/name-by-capability.md` exists, read it first; always keep `reference/rule-checklist.md` as the fallback when the doc is missing. On disagreement after the docs PR merges, prefer the repo doc and update the skill checklist in a follow-up.
45
49
 
@@ -47,7 +51,7 @@ Load order for the rule: if `docs/agents/name-by-capability.md` exists, read it
47
51
 
48
52
  | Peer | Relationship |
49
53
  |------|----------------|
50
- | `shared-extraction-audit` | Layering and extraction (where code lives). Invoke when a path’s *role* is unclear; this skill only scores the *name*. |
54
+ | `pr-shared-extraction` | Layering and extraction (where code lives). Invoke when a path’s *role* is unclear; this skill only scores the *name*. |
51
55
  | `reviews` / PR review skills | May invoke this skill by name when naming is in scope |
52
56
 
53
57
  ## File index
@@ -60,6 +64,8 @@ Load order for the rule: if `docs/agents/name-by-capability.md` exists, read it
60
64
  | `reference/fetch-commands.md` | Minimal `gh` fetch for PR naming surface |
61
65
  | `reference/report-template.md` | Compact report shape |
62
66
  | `reference/task-seeds.md` | Ordered task seeds for the audit run |
67
+ | `../_shared/pr-loop/preflight-proposal.md` | Shared isolated proposal mode and evidence record |
68
+ | `../_shared/pr-loop/preflight-proposal.contract.test.mjs` | Cross-skill mode and contract test |
63
69
 
64
70
  ## Folder map
65
71
 
@@ -1,6 +1,6 @@
1
1
  # Offense examples (this repo)
2
2
 
3
- Classify by **role** — the reusable work the surface performs — not by matching a string list. For whether code belongs in `shared_utils` vs a workflow package, invoke `shared-extraction-audit`; this map only scores names.
3
+ Classify by **role** — the reusable work the surface performs — not by matching a string list. For whether code belongs in `shared_utils` vs a workflow package, invoke `pr-shared-extraction`; this map only scores names.
4
4
 
5
5
  ## Quick classifier
6
6
 
@@ -1,9 +1,10 @@
1
1
  # Task seeds
2
2
 
3
- Register each item on `TodoWrite` / `TaskCreate` at audit start. Complete with evidence.
3
+ Register each item with `update_plan` at audit start. Complete with evidence.
4
4
 
5
5
  1. Load the rule: `docs/agents/name-by-capability.md` when present, else `reference/rule-checklist.md` (always keep the skill checklist as fallback).
6
6
  2. Fetch PR title, body, and changed/renamed paths via `reference/fetch-commands.md`.
7
7
  3. Classify each naming signal as violation, OK driver, or skip (`reference/offense-examples.md` classifier first).
8
8
  4. Emit report from `reference/report-template.md`.
9
- 5. Apply the requested or suggested rename direction by default; an explicit audit-only request ends after the report.
9
+ 5. After the report, continue with `SKILL.md` **Mode routing**.
10
+ 6. For `preflight-proposal`, complete the shared contract referenced by `SKILL.md` **Mode routing**.
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: pr-refinement
3
+ description: Coordinate shared-extraction and capability-naming audits, then update an existing pull request or publish a required focused GitHub pull-request stack. Use when a user asks to turn a PR architecture audit into extracted shared code and small pull requests.
4
+ ---
5
+
6
+ # PR Refinement
7
+
8
+ Turn audit findings into a focused existing pull-request update or a required dependency-ordered GitHub pull-request stack.
9
+
10
+ ## Peer skills
11
+
12
+ 1. Run `pr-shared-extraction` for reusable-code placement, canonical shared homes, and extraction findings.
13
+ 2. Run `pr-name-by-capability` for module, symbol, path, branch, and pull-request naming findings.
14
+ 3. Use `pr-small-cl` to divide approved fixes into coherent, independently reviewable pull requests.
15
+
16
+ The peer skills own their audit rules and finding priorities.
17
+
18
+ ## Workflow
19
+
20
+ 1. Run both audits in parallel against the same pull request. Keep their findings, locations, priorities, destinations, API directions, and naming directions.
21
+ 2. Build one change map. Group findings by shared capability and dependency.
22
+ 3. Use `pr-small-cl` to choose the delivery shape. Update the existing pull request when it remains one coherent, reviewable outcome.
23
+ 4. Create a replacement pull-request stack when the focused-change review identifies independent increments. Give each pull request one coherent outcome, related tests, a clear verification boundary, and a capability-oriented branch and title. Close the original pull request as superseded and link the replacement stack.
24
+ 5. Implement the existing pull request or the replacement stack in dependency order. Earlier pull requests create stable shared foundations. Later pull requests migrate consumers and remove replaced code.
25
+ 6. Run scoped production-path tests for each pull request. Record commands and results.
26
+ 7. Commit and push each branch. Update the existing pull request, or open draft replacement pull requests in stack order and set every child pull request base to its parent.
27
+ 8. Include scope, verification, risks, and stack dependencies in every pull-request body.
28
+
29
+ ## Completion
30
+
31
+ Deliver a focused, tested, pushed existing pull request, or a replacement stack with explicit parent-child links. Keep merge authority with the user.
@@ -1,11 +1,11 @@
1
1
  ---
2
- name: shared-extraction-audit
2
+ name: pr-shared-extraction
3
3
  description: Audits pull requests and packages for general helpers living in workflow-specific code instead of shared_utils, then applies extraction fixes by default in small tested CLs. Use when reviewing PRs for architectural layering, migrating utilities out of cert_fix_queue/theme_dialer_pipeline/skills, auditing "similar offenses", or when the user mentions extraction audit, shared_utils migration, orchestration-only packages, thin wrappers, or layer inversions.
4
4
  ---
5
5
 
6
6
  # Shared Extraction Audit
7
7
 
8
- Audit PRs and packages, report findings, and apply extraction fixes by default to keep **orchestration packages thin** and **shared_utils canonical**.
8
+ Audit PRs and packages for reusable behavior placed in workflow code. Keep **orchestration packages thin** and **shared_utils canonical**.
9
9
 
10
10
  ## When to use
11
11
 
@@ -13,6 +13,14 @@ Audit PRs and packages, report findings, and apply extraction fixes by default t
13
13
  - A package grew `fix_one`, `_default_*`, backup upload, rembg session, or residual gates alongside orchestration
14
14
  - Before merge: confirm consumers are adapters, not second implementations
15
15
 
16
+ ## Mode routing
17
+
18
+ Resolve the first matching mode before the audit steps:
19
+
20
+ 1. `preflight-proposal` runs `pr-shared-extraction preflight-proposal <pr_number> --base-sha <base_sha> --head-sha <head_sha> --worktree <isolated_worktree>` under the [shared preflight proposal contract](../_shared/pr-loop/preflight-proposal.md). Record each finding with priority and target.
21
+ 2. `audit-only` is report-only and ends after the findings report.
22
+ 3. Normal mode follows the existing audit workflow and applies the prioritized fix band by default.
23
+
16
24
  ## Target architecture
17
25
 
18
26
  | Layer | Holds | Examples |
@@ -25,7 +33,7 @@ Audit PRs and packages, report findings, and apply extraction fixes by default t
25
33
 
26
34
  ## Audit workflow
27
35
 
28
- Copy to TodoWrite:
36
+ Register this checklist with `update_plan` and mark each step complete with evidence:
29
37
 
30
38
  ```
31
39
  Shared extraction audit:
@@ -33,9 +41,10 @@ Shared extraction audit:
33
41
  - [ ] 2. Map canonical homes already in shared_utils
34
42
  - [ ] 3. Grep for offense patterns (see reference/offense-taxonomy.md)
35
43
  - [ ] 4. Write prioritized findings (P0–P3)
36
- - [ ] 5. Apply the prioritized fix band by default; an explicit audit-only request ends after the report
44
+ - [ ] 5. Apply **Mode routing** after the report
37
45
  - [ ] 6. Extract in small CLs (~100 lines) + move/adjust tests
38
- - [ ] 7. Run scoped pytest, commit, push, update PR
46
+ - [ ] 7. Run scoped pytest, then follow the selected mode's mutation boundary
47
+ - [ ] 8. When the mode is `preflight-proposal`, record proposal evidence from the [shared preflight proposal contract](../_shared/pr-loop/preflight-proposal.md) and require downstream owner selection before reapplication
39
48
  ```
40
49
 
41
50
  ### Step 1 — Scope
@@ -97,8 +106,6 @@ Use [reference/offense-taxonomy.md](reference/offense-taxonomy.md). Assign prior
97
106
  1. …
98
107
  ```
99
108
 
100
- Apply the prioritized fixes after the report by default. An explicit audit-only request ends after the report.
101
-
102
109
  ## Fix workflow
103
110
 
104
111
  ### Extraction rules
@@ -158,3 +165,13 @@ Provide evidence: pytest output counts, not "should work".
158
165
  ## Examples
159
166
 
160
167
  See [reference/examples.md](reference/examples.md) for cert_fix_queue (#1965) and background_removal (#1954) audits.
168
+
169
+ ## File index
170
+
171
+ | File | Purpose |
172
+ |------|---------|
173
+ | `SKILL.md` | Hub — architecture, routing, audit checklist, and fix workflow |
174
+ | `reference/offense-taxonomy.md` | Offense signals and priority guide |
175
+ | `reference/examples.md` | Audit examples and fix order |
176
+ | `../_shared/pr-loop/preflight-proposal.md` | Shared isolated proposal mode and evidence record |
177
+ | `../_shared/pr-loop/preflight-proposal.contract.test.mjs` | Cross-skill mode and contract test |
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: small-cl
2
+ name: pr-small-cl
3
3
  description: >-
4
4
  Scope or split a pull request into a self-contained reviewable increment. Use
5
5
  when a user asks to "split this PR", "make this change smaller", or "small CL".
@@ -33,6 +33,7 @@ from prototype_scripts_constants.config.probe_sandbox_safety_constants import (
33
33
  )
34
34
 
35
35
  SCRIPTS_DIRECTORY = Path(__file__).resolve().parent
36
+ BUILDER_PATH = SCRIPTS_DIRECTORY / "build_sandbox_settings.py"
36
37
  PROBE_PATH = SCRIPTS_DIRECTORY / "probe_sandbox_safety.py"
37
38
  HOOKS_BLOCKING_DIRECTORY = SCRIPTS_DIRECTORY.parents[3] / "hooks" / "blocking"
38
39
 
@@ -52,13 +53,21 @@ ASK_HOOK_SOURCE = (
52
53
  ALLOW_HOOK_SOURCE = "import sys\nsys.exit(0)\n"
53
54
 
54
55
 
55
- def load_probe_module() -> ModuleType:
56
- spec = importlib.util.spec_from_file_location("probe_sandbox_safety", PROBE_PATH)
56
+ def load_module_from_path(module_name: str, module_path: Path) -> ModuleType:
57
+ spec = importlib.util.spec_from_file_location(module_name, module_path)
57
58
  assert spec is not None
58
59
  assert spec.loader is not None
59
- probe_module = importlib.util.module_from_spec(spec)
60
- spec.loader.exec_module(probe_module)
61
- return probe_module
60
+ loaded_module = importlib.util.module_from_spec(spec)
61
+ spec.loader.exec_module(loaded_module)
62
+ return loaded_module
63
+
64
+
65
+ def load_probe_module() -> ModuleType:
66
+ return load_module_from_path("probe_sandbox_safety", PROBE_PATH)
67
+
68
+
69
+ def load_builder_module() -> ModuleType:
70
+ return load_module_from_path("build_sandbox_settings", BUILDER_PATH)
62
71
 
63
72
 
64
73
  def quoted_command(script_path: Path) -> str:
@@ -123,6 +132,25 @@ def test_main_exits_zero_when_the_real_destructive_hook_denies_in_deny_mode(
123
132
  assert exit_code == PROBE_SUCCESS_EXIT_CODE
124
133
 
125
134
 
135
+ def test_built_deny_environment_denies_real_destructive_hook() -> None:
136
+ builder_module = load_builder_module()
137
+ settings_document = builder_module.build_minimal_settings(
138
+ builder_module.resolve_safety_hook_entries(real_hook_settings_document())
139
+ )
140
+ probe_module = load_probe_module()
141
+ probe_payload = probe_module.build_probe_payload_for_basename(DESTRUCTIVE_HOOK_BASENAME)
142
+ destructive_hook_path = HOOKS_BLOCKING_DIRECTORY / DESTRUCTIVE_HOOK_BASENAME
143
+ destructive_hook_tokens = probe_module.parse_command_argv(
144
+ quoted_command(destructive_hook_path)
145
+ )
146
+ is_hook_blocking = probe_module.hook_blocks_probe(
147
+ destructive_hook_tokens,
148
+ probe_payload,
149
+ settings_document["env"],
150
+ )
151
+ assert is_hook_blocking is True
152
+
153
+
126
154
  def test_pii_basename_probe_payload_carries_the_secret() -> None:
127
155
  probe = load_probe_module()
128
156
  probe_payload = probe.build_probe_payload_for_basename(PII_HOOK_BASENAME)
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: skill-builder
3
+ disable-model-invocation: true
3
4
  description: >-
4
5
  Skill lifecycle: classify, scaffold, write via the skill-writer-agent, self-audit, compose
5
6
  sub-skills, polish description triggers, enforce deterministic scripts. Triggers: