claude-dev-env 4.3.0 → 7.0.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 (293) hide show
  1. package/.agents/agents/pr-description-writer.md +2 -2
  2. package/.agents/agents/test_agent_frontmatter.py +2 -2
  3. package/.agents/agents/test_pr_description_writer_style.py +1 -3
  4. package/.agents/skills/e-code-review/SKILL.md +12 -12
  5. package/.agents/skills/e-code-review/preflight-proposal.contract.test.mjs +20 -0
  6. package/.agents/skills/e-code-review/reference/fix.md +15 -17
  7. package/.agents/skills/e-code-review/reference/loop.md +35 -39
  8. package/.agents/skills/e-code-review/reference/mode-contract.test.mjs +2 -1
  9. package/.agents/skills/e-code-review/reference/preflight-proposal.md +44 -9
  10. package/.agents/skills/e-code-review/reference/runner-selection.md +13 -14
  11. package/.agents/skills/issue-tracker/SKILL.md +5 -4
  12. package/.agents/skills/pull-request/SKILL.md +11 -13
  13. package/.agents/skills/pull-request/reference/publication-tasks.md +3 -3
  14. package/.agents/skills/pull-request/scripts/github_pr_command_constants/config/constants.py +9 -1
  15. package/.agents/skills/pull-request/scripts/pull_request.py +33 -44
  16. package/.agents/skills/pull-request/scripts/test_github_pr_command_constants.py +9 -0
  17. package/.agents/skills/pull-request/scripts/test_pull_request.py +1 -3
  18. package/.agents/skills/skill-builder/SKILL.md +3 -196
  19. package/_shared/pr-loop/scripts/pr_loop_shared_constants/terminology_sweep_constants.py +6 -0
  20. package/_shared/pr-loop/scripts/terminology_sweep.py +64 -19
  21. package/_shared/pr-loop/scripts/tests/test_terminology_sweep.py +59 -0
  22. package/bin/install.agents-home.test.mjs +15 -13
  23. package/bin/install.mjs +28 -0
  24. package/bin/install.policy-lint.test.mjs +78 -0
  25. package/bin/install.prune.test.mjs +59 -20
  26. package/bin/install.pstack-plugin.test.mjs +114 -0
  27. package/bin/install.test.mjs +37 -0
  28. package/bin/refresh-pstack-plugin-skills.test.mjs +211 -0
  29. package/hooks/advisory/pr_done_reminder.py +342 -0
  30. package/hooks/advisory/test_pr_done_reminder.py +249 -0
  31. package/hooks/blocking/bash_post_call_dispatcher.py +53 -6
  32. package/hooks/blocking/code_rules_paired_test.py +22 -15
  33. package/hooks/blocking/test_bash_post_call_dispatcher.py +65 -4
  34. package/hooks/blocking/test_code_rules_enforcer_paired_test.py +36 -29
  35. package/hooks/blocking/test_code_rules_js_resume_task_enumeration.py +4 -4
  36. package/hooks/blocking/test_code_rules_js_returns_object_schemaless.py +5 -5
  37. package/hooks/blocking/test_pre_tool_use_dispatcher.py +68 -133
  38. package/hooks/blocking/test_pre_tool_use_dispatcher_native.py +20 -51
  39. package/hooks/blocking/test_precommit_code_rules_gate_native_owner.py +18 -18
  40. package/hooks/git-hooks/git_hooks_constants/staged_policy_lint.py +12 -0
  41. package/hooks/git-hooks/pre_commit.py +52 -11
  42. package/hooks/git-hooks/test_installed_policy_lint.py +159 -0
  43. package/hooks/git-hooks/test_native_policy_commit.py +87 -0
  44. package/hooks/git-hooks/test_pre_commit.py +246 -0
  45. package/hooks/hooks.json +1 -1
  46. package/hooks/hooks_constants/bash_post_call_dispatcher_constants.py +14 -1
  47. package/hooks/hooks_constants/pr_done_reminder_constants.py +98 -0
  48. package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +10 -43
  49. package/hooks/hooks_constants/test_bash_post_call_dispatcher_constants.py +19 -2
  50. package/hooks/hooks_constants/test_pr_done_reminder_constants.py +40 -0
  51. package/hooks/hooks_constants/test_pre_tool_use_dispatcher_constants.py +20 -32
  52. package/package.json +2 -2
  53. package/rules/durable-post-artifacts.md +2 -1
  54. package/rules/git-workflow.md +6 -6
  55. package/scripts/check.ps1 +0 -1
  56. package/{.agents/skills/run-claude-dev-env/driver.mjs → scripts/ci/installer-lifecycle.mjs} +3 -28
  57. package/scripts/ci/installer-lifecycle.test.mjs +26 -0
  58. package/scripts/ci/windows-installer-lifecycle.ps1 +1 -11
  59. package/scripts/dev_env_scripts_constants/shared_tree_constants.py +4 -5
  60. package/{.agents/skills/_shared/pr-loop/scripts → scripts}/durable_post_lint.py +5 -41
  61. package/{.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/durable_post_lint_constants.py → scripts/durable_post_lint_config/config/constants.py} +0 -10
  62. package/{.agents/skills/_shared/pr-loop/scripts/test_durable_post_lint_constants.py → scripts/durable_post_lint_config/config/test_constants.py} +1 -1
  63. package/scripts/policy_lint/adapter_detectors.py +13 -6
  64. package/scripts/policy_lint/adapters.py +7 -4
  65. package/scripts/policy_lint/config/constants.py +5 -0
  66. package/scripts/policy_lint/engine.py +48 -4
  67. package/scripts/policy_lint/model.py +1 -0
  68. package/scripts/policy_lint/registry.py +1 -1
  69. package/scripts/policy_lint/selection.py +2 -1
  70. package/scripts/policy_lint/selection_git.py +2 -0
  71. package/scripts/refresh_pstack_plugin_skills.mjs +200 -0
  72. package/scripts/shared_tree_paths.py +32 -3
  73. package/scripts/test_shared_tree_paths.py +33 -0
  74. package/scripts/tests/test_policy_lint_rules_archive.py +120 -0
  75. package/scripts/tests/test_policy_lint_rules_engine.py +25 -4
  76. package/scripts/tests/test_policy_lint_rules_installed_loader.py +29 -0
  77. package/scripts/tests/test_policy_lint_rules_registry.py +227 -13
  78. package/scripts/tests/test_policy_lint_selection.py +25 -2
  79. package/scripts/tests/test_policy_lint_selection_native_index.py +30 -0
  80. package/scripts/tests/test_rules.py +3 -7
  81. package/.agents/skills/_shared/pr-loop/.claude/CLAUDE.md +0 -1
  82. package/.agents/skills/_shared/pr-loop/AGENTS.md +0 -1
  83. package/.agents/skills/_shared/pr-loop/audit-contract.md +0 -5
  84. package/.agents/skills/_shared/pr-loop/audit-reply-template.md +0 -5
  85. package/.agents/skills/_shared/pr-loop/code-rules-gate.md +0 -5
  86. package/.agents/skills/_shared/pr-loop/fix-protocol.md +0 -5
  87. package/.agents/skills/_shared/pr-loop/gh-payloads.md +0 -5
  88. package/.agents/skills/_shared/pr-loop/portable-driver.md +0 -149
  89. package/.agents/skills/_shared/pr-loop/post-audit-thread-contract.md +0 -5
  90. package/.agents/skills/_shared/pr-loop/precatch-rubric.md +0 -5
  91. package/.agents/skills/_shared/pr-loop/preflight-proposal.contract.test.mjs +0 -119
  92. package/.agents/skills/_shared/pr-loop/preflight-proposal.md +0 -5
  93. package/.agents/skills/_shared/pr-loop/prompts/.claude/CLAUDE.md +0 -1
  94. package/.agents/skills/_shared/pr-loop/prompts/AGENTS.md +0 -1
  95. package/.agents/skills/_shared/pr-loop/prompts/pr-consistency-audit.xml +0 -324
  96. package/.agents/skills/_shared/pr-loop/scripts/.claude/CLAUDE.md +0 -1
  97. package/.agents/skills/_shared/pr-loop/scripts/AGENTS.md +0 -1
  98. package/.agents/skills/_shared/pr-loop/scripts/RUNTIME_SCRIPTS.md +0 -29
  99. package/.agents/skills/_shared/pr-loop/scripts/_cli_utils.py +0 -22
  100. package/.agents/skills/_shared/pr-loop/scripts/_path_resolver.py +0 -186
  101. package/.agents/skills/_shared/pr-loop/scripts/_xml_utils.py +0 -20
  102. package/.agents/skills/_shared/pr-loop/scripts/audit_category_schema.py +0 -355
  103. package/.agents/skills/_shared/pr-loop/scripts/build_audit_prompt.py +0 -289
  104. package/.agents/skills/_shared/pr-loop/scripts/build_converge_task_list.py +0 -310
  105. package/.agents/skills/_shared/pr-loop/scripts/build_fix_prompt.py +0 -292
  106. package/.agents/skills/_shared/pr-loop/scripts/init_loop_state.py +0 -134
  107. package/.agents/skills/_shared/pr-loop/scripts/portable_converge_driver.py +0 -1646
  108. package/.agents/skills/_shared/pr-loop/scripts/preflight_worktree.py +0 -392
  109. package/.agents/skills/_shared/pr-loop/scripts/select_converge_pacer.py +0 -215
  110. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/.claude/CLAUDE.md +0 -1
  111. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/AGENTS.md +0 -1
  112. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/__init__.py +0 -0
  113. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/audit_category_schema_constants.py +0 -37
  114. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/converge_task_list_constants.py +0 -56
  115. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/handoff_constants.py +0 -45
  116. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/pacer_constants.py +0 -47
  117. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py +0 -157
  118. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/portable_driver_constants.py +0 -177
  119. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/preflight_constants.py +0 -70
  120. package/.agents/skills/_shared/pr-loop/scripts/teardown_worktrees.py +0 -172
  121. package/.agents/skills/_shared/pr-loop/scripts/test__path_resolver.py +0 -106
  122. package/.agents/skills/_shared/pr-loop/scripts/test_audit_category_schema.py +0 -94
  123. package/.agents/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +0 -499
  124. package/.agents/skills/_shared/pr-loop/scripts/test_build_converge_task_list.py +0 -140
  125. package/.agents/skills/_shared/pr-loop/scripts/test_build_fix_prompt.py +0 -262
  126. package/.agents/skills/_shared/pr-loop/scripts/test_init_loop_state.py +0 -71
  127. package/.agents/skills/_shared/pr-loop/scripts/test_portable_converge_driver.py +0 -1119
  128. package/.agents/skills/_shared/pr-loop/scripts/test_preflight_worktree.py +0 -287
  129. package/.agents/skills/_shared/pr-loop/scripts/test_select_converge_pacer.py +0 -207
  130. package/.agents/skills/_shared/pr-loop/scripts/test_teardown_worktrees.py +0 -59
  131. package/.agents/skills/_shared/pr-loop/scripts/test_write_handoff.py +0 -201
  132. package/.agents/skills/_shared/pr-loop/scripts/write_audit_outcomes.py +0 -182
  133. package/.agents/skills/_shared/pr-loop/scripts/write_fix_outcomes.py +0 -206
  134. package/.agents/skills/_shared/pr-loop/scripts/write_handoff.py +0 -309
  135. package/.agents/skills/_shared/pr-loop/state-schema.md +0 -5
  136. package/.agents/skills/_shared/pr-loop/worker-spawn.md +0 -5
  137. package/.agents/skills/autoconverge/.claude/CLAUDE.md +0 -1
  138. package/.agents/skills/autoconverge/AGENTS.md +0 -1
  139. package/.agents/skills/autoconverge/SKILL.md +0 -431
  140. package/.agents/skills/autoconverge/reference/.claude/CLAUDE.md +0 -1
  141. package/.agents/skills/autoconverge/reference/AGENTS.md +0 -1
  142. package/.agents/skills/autoconverge/reference/closing-report.md +0 -93
  143. package/.agents/skills/autoconverge/reference/convergence-gates.md +0 -31
  144. package/.agents/skills/autoconverge/reference/convergence.md +0 -219
  145. package/.agents/skills/autoconverge/reference/copilot-findings.md +0 -51
  146. package/.agents/skills/autoconverge/reference/gotchas.md +0 -66
  147. package/.agents/skills/autoconverge/reference/headless-safety.md +0 -44
  148. package/.agents/skills/autoconverge/reference/multi-pr.md +0 -128
  149. package/.agents/skills/autoconverge/reference/self-closing-loop.md +0 -84
  150. package/.agents/skills/autoconverge/reference/stop-conditions.md +0 -127
  151. package/.agents/skills/autoconverge/test_portable_pacer_gate.py +0 -54
  152. package/.agents/skills/autoconverge/workflow/.claude/CLAUDE.md +0 -1
  153. package/.agents/skills/autoconverge/workflow/AGENTS.md +0 -1
  154. package/.agents/skills/autoconverge/workflow/aggregate_runs.py +0 -371
  155. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/.claude/CLAUDE.md +0 -1
  156. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/AGENTS.md +0 -1
  157. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/__init__.py +0 -0
  158. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/render_report_constants.py +0 -250
  159. package/.agents/skills/autoconverge/workflow/converge.clean-audit.test.mjs +0 -665
  160. package/.agents/skills/autoconverge/workflow/converge.codex-gate.test.mjs +0 -472
  161. package/.agents/skills/autoconverge/workflow/converge.contract.test.mjs +0 -64
  162. package/.agents/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +0 -1009
  163. package/.agents/skills/autoconverge/workflow/converge.fix-progress.test.mjs +0 -107
  164. package/.agents/skills/autoconverge/workflow/converge.fix-recovery.test.mjs +0 -33
  165. package/.agents/skills/autoconverge/workflow/converge.merge-conflict.test.mjs +0 -15
  166. package/.agents/skills/autoconverge/workflow/converge.mjs +0 -3132
  167. package/.agents/skills/autoconverge/workflow/converge.p2-advance.test.mjs +0 -202
  168. package/.agents/skills/autoconverge/workflow/converge.path-aware.test.mjs +0 -47
  169. package/.agents/skills/autoconverge/workflow/converge.precatch.test.mjs +0 -152
  170. package/.agents/skills/autoconverge/workflow/converge.run-input.test.mjs +0 -116
  171. package/.agents/skills/autoconverge/workflow/converge_multi.mjs +0 -169
  172. package/.agents/skills/autoconverge/workflow/converge_multi.run-input.test.mjs +0 -173
  173. package/.agents/skills/autoconverge/workflow/convergence_summary.py +0 -110
  174. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a11d903476b803493.jsonl +0 -2
  175. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a26213978adeef6fb.jsonl +0 -2
  176. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a3def0d15ed9d9110.jsonl +0 -2
  177. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a41f41b1b708ee3b7.jsonl +0 -2
  178. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a758b880abecc3ff7.jsonl +0 -2
  179. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a8897b89656b1bd16.jsonl +0 -2
  180. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ab1c2d3e4f5a6b7c8.jsonl +0 -2
  181. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-abd463d744a1437bc.jsonl +0 -2
  182. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ad19d027ae8ee1816.jsonl +0 -2
  183. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/workflows/wf_881252e6-700.json +0 -266
  184. package/.agents/skills/autoconverge/workflow/render_report.py +0 -1024
  185. package/.agents/skills/autoconverge/workflow/test_aggregate_runs.py +0 -134
  186. package/.agents/skills/autoconverge/workflow/test_convergence_summary.py +0 -149
  187. package/.agents/skills/autoconverge/workflow/test_render_report.py +0 -812
  188. package/.agents/skills/hitl/SKILL.md +0 -45
  189. package/.agents/skills/pr-cleanup/SKILL.md +0 -140
  190. package/.agents/skills/pr-cleanup/reference/process-inventory.md +0 -17
  191. package/.agents/skills/pr-cleanup/reference/task-seeds.md +0 -22
  192. package/.agents/skills/pr-name-by-capability/SKILL.md +0 -73
  193. package/.agents/skills/pr-name-by-capability/reference/fetch-commands.md +0 -29
  194. package/.agents/skills/pr-name-by-capability/reference/offense-examples.md +0 -32
  195. package/.agents/skills/pr-name-by-capability/reference/report-template.md +0 -29
  196. package/.agents/skills/pr-name-by-capability/reference/rule-checklist.md +0 -38
  197. package/.agents/skills/pr-name-by-capability/reference/task-seeds.md +0 -10
  198. package/.agents/skills/pr-plain-language-cleanup/SKILL.md +0 -93
  199. package/.agents/skills/pr-refinement/SKILL.md +0 -31
  200. package/.agents/skills/pr-shared-extraction/SKILL.md +0 -177
  201. package/.agents/skills/pr-shared-extraction/reference/examples.md +0 -46
  202. package/.agents/skills/pr-shared-extraction/reference/offense-taxonomy.md +0 -100
  203. package/.agents/skills/pr-small-cl/SKILL.md +0 -52
  204. package/.agents/skills/pr-title-description/SKILL.md +0 -96
  205. package/.agents/skills/prototype/SKILL.md +0 -85
  206. package/.agents/skills/prototype/reference/honest-limitations.md +0 -23
  207. package/.agents/skills/prototype/reference/promotion-tasks.md +0 -23
  208. package/.agents/skills/prototype/scripts/build_sandbox_settings.py +0 -249
  209. package/.agents/skills/prototype/scripts/conftest.py +0 -15
  210. package/.agents/skills/prototype/scripts/launch_sandbox.py +0 -205
  211. package/.agents/skills/prototype/scripts/probe_sandbox_safety.py +0 -311
  212. package/.agents/skills/prototype/scripts/prototype_scripts_constants/__init__.py +0 -1
  213. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/__init__.py +0 -0
  214. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/build_sandbox_settings_constants.py +0 -41
  215. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/launch_sandbox_constants.py +0 -23
  216. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/probe_sandbox_safety_constants.py +0 -45
  217. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/prototype_common_constants.py +0 -10
  218. package/.agents/skills/prototype/scripts/test_build_sandbox_settings.py +0 -275
  219. package/.agents/skills/prototype/scripts/test_launch_sandbox.py +0 -303
  220. package/.agents/skills/prototype/scripts/test_probe_sandbox_safety.py +0 -312
  221. package/.agents/skills/prototype/workflows/promotion.md +0 -25
  222. package/.agents/skills/prototype/workflows/sandbox.md +0 -35
  223. package/.agents/skills/rebase/.claude/CLAUDE.md +0 -1
  224. package/.agents/skills/rebase/AGENTS.md +0 -1
  225. package/.agents/skills/rebase/SKILL.md +0 -178
  226. package/.agents/skills/review-router/SKILL.md +0 -51
  227. package/.agents/skills/review-router/reference/route-policy.json +0 -7
  228. package/.agents/skills/review-router/reference/task-seeds.md +0 -1
  229. package/.agents/skills/review-router/scripts/conftest.py +0 -4
  230. package/.agents/skills/review-router/scripts/review_router.py +0 -50
  231. package/.agents/skills/review-router/scripts/review_router_cli.py +0 -211
  232. package/.agents/skills/review-router/scripts/review_router_constants/__init__.py +0 -1
  233. package/.agents/skills/review-router/scripts/review_router_constants/config/__init__.py +0 -0
  234. package/.agents/skills/review-router/scripts/review_router_constants/config/constants.py +0 -13
  235. package/.agents/skills/review-router/scripts/test_review_router.py +0 -23
  236. package/.agents/skills/review-router/scripts/test_review_router_cli.py +0 -47
  237. package/.agents/skills/review-tier/SKILL.md +0 -56
  238. package/.agents/skills/review-tier/reference/task-seeds.md +0 -1
  239. package/.agents/skills/review-tier/reference/tier-policy.json +0 -9
  240. package/.agents/skills/review-tier/scripts/conftest.py +0 -4
  241. package/.agents/skills/review-tier/scripts/review_tier.py +0 -359
  242. package/.agents/skills/review-tier/scripts/review_tier_constants/__init__.py +0 -1
  243. package/.agents/skills/review-tier/scripts/review_tier_constants/config/__init__.py +0 -0
  244. package/.agents/skills/review-tier/scripts/review_tier_constants/config/constants.py +0 -29
  245. package/.agents/skills/review-tier/scripts/test_generation.py +0 -159
  246. package/.agents/skills/review-tier/scripts/test_review_tier.py +0 -33
  247. package/.agents/skills/run-claude-dev-env/SKILL.md +0 -84
  248. package/.agents/skills/session-log/.claude/CLAUDE.md +0 -1
  249. package/.agents/skills/session-log/AGENTS.md +0 -1
  250. package/.agents/skills/session-log/SKILL.md +0 -170
  251. package/.agents/skills/session-log/templates/frontmatter.md +0 -40
  252. package/.agents/skills/session-tidy/.claude/CLAUDE.md +0 -1
  253. package/.agents/skills/session-tidy/AGENTS.md +0 -1
  254. package/.agents/skills/session-tidy/SKILL.md +0 -191
  255. package/.agents/skills/skill-builder/references/.claude/CLAUDE.md +0 -1
  256. package/.agents/skills/skill-builder/references/AGENTS.md +0 -1
  257. package/.agents/skills/skill-builder/references/delegation-map.md +0 -130
  258. package/.agents/skills/skill-builder/references/description-field.md +0 -111
  259. package/.agents/skills/skill-builder/references/deterministic-elements.md +0 -218
  260. package/.agents/skills/skill-builder/references/progressive-disclosure.md +0 -122
  261. package/.agents/skills/skill-builder/references/self-audit-checklist.md +0 -126
  262. package/.agents/skills/skill-builder/references/skill-modularity.md +0 -111
  263. package/.agents/skills/skill-builder/references/skill-types.md +0 -232
  264. package/.agents/skills/skill-builder/references/thariq-x-post-skills.json +0 -33
  265. package/.agents/skills/skill-builder/templates/.claude/CLAUDE.md +0 -1
  266. package/.agents/skills/skill-builder/templates/AGENTS.md +0 -1
  267. package/.agents/skills/skill-builder/templates/gap-analysis.md +0 -87
  268. package/.agents/skills/skill-builder/workflows/.claude/CLAUDE.md +0 -1
  269. package/.agents/skills/skill-builder/workflows/AGENTS.md +0 -1
  270. package/.agents/skills/skill-builder/workflows/improve-skill.md +0 -136
  271. package/.agents/skills/skill-builder/workflows/new-skill.md +0 -179
  272. package/.agents/skills/skill-builder/workflows/polish-skill.md +0 -139
  273. package/.agents/skills/source-command-sr-loop/SKILL.md +0 -82
  274. package/.agents/skills/update/.claude/CLAUDE.md +0 -1
  275. package/.agents/skills/update/AGENTS.md +0 -1
  276. package/.agents/skills/update/SKILL.md +0 -190
  277. package/_shared/pr-loop/AGENTS.md +0 -1
  278. package/_shared/pr-loop/CLAUDE.md +0 -1
  279. package/_shared/pr-loop/audit-contract.md +0 -183
  280. package/_shared/pr-loop/audit-reply-template.md +0 -151
  281. package/_shared/pr-loop/code-rules-gate.md +0 -65
  282. package/_shared/pr-loop/fix-protocol.md +0 -60
  283. package/_shared/pr-loop/gh-payloads.md +0 -75
  284. package/_shared/pr-loop/post-audit-thread-contract.md +0 -51
  285. package/_shared/pr-loop/precatch-rubric.md +0 -66
  286. package/_shared/pr-loop/preflight-proposal.md +0 -56
  287. package/_shared/pr-loop/scripts/post_audit_thread.py +0 -1242
  288. package/_shared/pr-loop/scripts/pr_loop_shared_constants/post_audit_thread_constants.py +0 -199
  289. package/_shared/pr-loop/scripts/tests/test_post_audit_thread.py +0 -1115
  290. package/_shared/pr-loop/scripts/tests/test_post_audit_thread_constants.py +0 -129
  291. package/_shared/pr-loop/state-schema.md +0 -45
  292. package/_shared/pr-loop/worker-spawn.md +0 -189
  293. /package/{.agents/skills/_shared/pr-loop/scripts → scripts}/test_durable_post_lint.py +0 -0
@@ -6,11 +6,11 @@ reason when the task is conditional. This file is a task seed catalog, not a
6
6
  markdown progress board.
7
7
 
8
8
  1. Resolve one repository, action, and selected author. For create, resolve the source branch, base, and head. For other actions, resolve one existing pull request target. Create actions publish drafts.
9
- 2. Invoke the required `pr-description-writer` for create or full body rewrite, then record its title and body file. `pr-title-description` may assist. Mark `N/A` for comment or review bodies that do not rewrite the pull request description.
9
+ 2. Invoke the required `pr-description-writer` for create or full body rewrite, then record its title and body file. Mark `N/A` for comment or review bodies that do not rewrite the pull request description.
10
10
  3. Validate every title, body, artifact, and local path input. Reject inline body input.
11
- 4. Run `_shared/pr-loop/scripts/durable_post_lint.py` for the matching action and record exit code `0` before credential lookup or network work.
11
+ 4. Resolve the active managed root and run `<managed-root>/scripts/durable_post_lint.py` for the matching action. Record exit code `0` before credential lookup or network work.
12
12
  5. Run `privacy-hygiene` before the GitHub post and record its clean result.
13
- 6. Upload binary evidence through `scripts/gh_artifact_upload.py`, replace local references with permanent URLs, and rerun the shared body linter. Mark `N/A` when no binary evidence exists.
13
+ 6. Upload binary evidence through `scripts/gh_artifact_upload.py`, replace local references with permanent URLs, and rerun the body linter. Mark `N/A` when no binary evidence exists.
14
14
  7. Resolve the selected author in the child process environment and prove that the parent environment and global `gh` account remain unchanged.
15
15
  8. Run `.agents/skills/pull-request/scripts/pull_request.py` for exactly one action: `create`, `edit`, `comment`, or `review`.
16
16
  9. When the user selects a legacy state file, run `recover_legacy_author.py <exact-state-file> --confirm-inactive` for exactly that record. Preserve every other record and delete the selected record only after successful restore. Mark `N/A` otherwise.
@@ -29,13 +29,21 @@ ALL_LINTER_ACTIONS_BY_COMMAND: dict[str, str] = {
29
29
  }
30
30
 
31
31
  SELECTED_ACCOUNT_ENVIRONMENT_KEY = "GITHUB_DEFAULT_ACCOUNT"
32
+ CONFIG_DIR_OVERRIDE_ENVIRONMENT_KEY = "CLAUDE_CONFIG_DIR"
33
+ DEFAULT_MANAGED_ROOT_DIRECTORY_NAME = ".claude"
34
+ ALL_DURABLE_POST_LINTER_RELATIVE_PATH_PARTS = ("scripts", "durable_post_lint.py")
35
+ GITHUB_TOKEN_ENVIRONMENT_KEY = "GITHUB" + "_TOKEN"
36
+ GH_TOKEN_ENVIRONMENT_KEY = "GH" + "_TOKEN"
37
+ ALL_GITHUB_AUTHORIZATION_ENVIRONMENT_KEYS = (
38
+ GITHUB_TOKEN_ENVIRONMENT_KEY,
39
+ GH_TOKEN_ENVIRONMENT_KEY,
40
+ )
32
41
 
33
42
  ACCOUNT_LOOKUP_FAILED_MESSAGE = "error: GitHub account lookup failed\n"
34
43
  ACCOUNT_LOOKUP_EMPTY_MESSAGE = "error: GitHub account lookup returned no value\n"
35
44
  ACTION_FAILED_MESSAGE = "error: GitHub action failed\n"
36
45
  ACCOUNT_LOOKUP_FAILURE_EXIT_CODE = 1
37
46
  PACKAGE_ROOT_PARENT_INDEX = 4
38
- SKILLS_DIRECTORY_PARENT_INDEX = 2
39
47
 
40
48
  ALL_GH_AUTH_SWITCH_COMMAND_HEAD: tuple[str, ...] = (
41
49
  "gh",
@@ -3,7 +3,6 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import argparse
6
- import importlib
7
6
  import os
8
7
  import subprocess
9
8
  import sys
@@ -19,12 +18,17 @@ from github_pr_command_constants.config.constants import (
19
18
  ACTION_EDIT,
20
19
  ACTION_FAILED_MESSAGE,
21
20
  ACTION_REVIEW,
21
+ ALL_DURABLE_POST_LINTER_RELATIVE_PATH_PARTS,
22
+ ALL_GITHUB_AUTHORIZATION_ENVIRONMENT_KEYS,
22
23
  ALL_LINTER_ACTIONS_BY_COMMAND,
23
24
  ALL_REVIEW_FLAGS_BY_EVENT,
25
+ CONFIG_DIR_OVERRIDE_ENVIRONMENT_KEY,
26
+ DEFAULT_MANAGED_ROOT_DIRECTORY_NAME,
27
+ GH_TOKEN_ENVIRONMENT_KEY,
28
+ GITHUB_TOKEN_ENVIRONMENT_KEY,
24
29
  PACKAGE_ROOT_PARENT_INDEX,
25
30
  REVIEW_EVENT_COMMENT,
26
31
  SELECTED_ACCOUNT_ENVIRONMENT_KEY,
27
- SKILLS_DIRECTORY_PARENT_INDEX,
28
32
  )
29
33
 
30
34
  CommandRunner = Callable[..., subprocess.CompletedProcess[str]]
@@ -60,17 +64,33 @@ def _build_parser() -> argparse.ArgumentParser:
60
64
  return parser
61
65
 
62
66
 
63
- def _linter_path() -> Path:
64
- return (
65
- Path(__file__).resolve().parents[SKILLS_DIRECTORY_PARENT_INDEX]
66
- / "_shared/pr-loop/scripts/durable_post_lint.py"
67
+ def _configured_managed_root(all_environment: Mapping[str, str]) -> Path:
68
+ configured_root_text = all_environment.get(CONFIG_DIR_OVERRIDE_ENVIRONMENT_KEY, "").strip()
69
+ if not configured_root_text:
70
+ return Path.home() / DEFAULT_MANAGED_ROOT_DIRECTORY_NAME
71
+ configured_root = Path(configured_root_text).expanduser()
72
+ if configured_root.is_absolute():
73
+ return configured_root
74
+ return Path.home() / configured_root
75
+
76
+
77
+ def _linter_path(all_environment: Mapping[str, str]) -> Path:
78
+ source_candidate = Path(__file__).resolve().parents[PACKAGE_ROOT_PARENT_INDEX].joinpath(
79
+ *ALL_DURABLE_POST_LINTER_RELATIVE_PATH_PARTS
80
+ )
81
+ if source_candidate.is_file():
82
+ return source_candidate
83
+ return _configured_managed_root(all_environment).joinpath(
84
+ *ALL_DURABLE_POST_LINTER_RELATIVE_PATH_PARTS
67
85
  )
68
86
 
69
87
 
70
- def _linter_arguments(arguments: argparse.Namespace) -> list[str]:
88
+ def _linter_arguments(
89
+ arguments: argparse.Namespace, all_environment: Mapping[str, str]
90
+ ) -> list[str]:
71
91
  all_arguments = [
72
92
  sys.executable,
73
- str(_linter_path()),
93
+ str(_linter_path(all_environment)),
74
94
  "--action",
75
95
  ALL_LINTER_ACTIONS_BY_COMMAND[arguments.action],
76
96
  ]
@@ -138,28 +158,9 @@ def _post_arguments(arguments: argparse.Namespace) -> list[str]:
138
158
  ]
139
159
 
140
160
 
141
- def _shared_environment_key_names() -> tuple[str, str, tuple[str, ...]]:
142
- shared_directory = (
143
- Path(__file__).resolve().parents[PACKAGE_ROOT_PARENT_INDEX]
144
- / "_shared/pr-loop/scripts"
145
- )
146
- shared_directory_text = str(shared_directory)
147
- if shared_directory_text not in sys.path:
148
- sys.path.insert(0, shared_directory_text)
149
- constants_module = importlib.import_module(
150
- "pr_loop_shared_constants.post_audit_thread_constants"
151
- )
152
- return (
153
- constants_module.GITHUB_TOKEN_ENV_VAR_NAME,
154
- constants_module.GH_TOKEN_ENV_VAR_NAME,
155
- constants_module.ALL_GH_TOKEN_ENV_VAR_NAMES,
156
- )
157
-
158
-
159
161
  def _lookup_environment(all_environment: Mapping[str, str]) -> dict[str, str]:
160
162
  lookup_environment = dict(all_environment)
161
- _, _, all_authorization_names = _shared_environment_key_names()
162
- for each_name in all_authorization_names:
163
+ for each_name in ALL_GITHUB_AUTHORIZATION_ENVIRONMENT_KEYS:
163
164
  lookup_environment.pop(each_name, None)
164
165
  return lookup_environment
165
166
 
@@ -203,12 +204,9 @@ def _action_environment(
203
204
  )
204
205
  if account_authorization is None:
205
206
  return None
206
- parent_authorization_name, child_authorization_name, _ = (
207
- _shared_environment_key_names()
208
- )
209
207
  action_environment = dict(all_environment)
210
- action_environment.pop(parent_authorization_name, None)
211
- action_environment[child_authorization_name] = account_authorization
208
+ action_environment.pop(GITHUB_TOKEN_ENVIRONMENT_KEY, None)
209
+ action_environment[GH_TOKEN_ENVIRONMENT_KEY] = account_authorization
212
210
  return action_environment
213
211
 
214
212
 
@@ -247,19 +245,10 @@ def main(
247
245
  all_environment: Mapping[str, str],
248
246
  command_runner: CommandRunner,
249
247
  ) -> int:
250
- """Run one validated pull request action.
251
-
252
- Args:
253
- all_arguments: Command arguments after the script name.
254
- all_environment: Parent environment copied for child processes.
255
- command_runner: Process runner used by tests and production.
256
-
257
- Returns:
258
- The linter, account lookup, or GitHub action exit status.
259
- """
248
+ """Run one validated pull request action."""
260
249
  arguments = _build_parser().parse_args(list(all_arguments))
261
250
  completed_lint = command_runner(
262
- _linter_arguments(arguments), check=False, shell=False
251
+ _linter_arguments(arguments, all_environment), check=False, shell=False
263
252
  )
264
253
  if completed_lint.returncode != 0:
265
254
  return completed_lint.returncode
@@ -34,6 +34,15 @@ def test_account_boundary_constants_are_safe_and_stable() -> None:
34
34
  assert constants.ACCOUNT_LOOKUP_EMPTY_MESSAGE.endswith("returned no value\n")
35
35
 
36
36
 
37
+ def test_durable_post_linter_location_uses_managed_root() -> None:
38
+ assert constants.CONFIG_DIR_OVERRIDE_ENVIRONMENT_KEY == "CLAUDE_CONFIG_DIR"
39
+ assert constants.DEFAULT_MANAGED_ROOT_DIRECTORY_NAME == ".claude"
40
+ assert constants.ALL_DURABLE_POST_LINTER_RELATIVE_PATH_PARTS == (
41
+ "scripts",
42
+ "durable_post_lint.py",
43
+ )
44
+
45
+
37
46
  def test_legacy_recovery_constants_define_one_record_boundary() -> None:
38
47
  assert constants.ALL_GH_AUTH_SWITCH_COMMAND_HEAD == (
39
48
  "gh",
@@ -25,9 +25,7 @@ PR_TITLE = "feat(skills): add guarded pull request publication"
25
25
  ACCOUNT_A = "JonEcho"
26
26
  ACCOUNT_B = "ReviewBot"
27
27
  BODY_FILENAME = "pull-request-body.md"
28
- LINTER_PATH = (
29
- _SCRIPTS_DIRECTORY.parents[1] / "_shared/pr-loop/scripts/durable_post_lint.py"
30
- )
28
+ LINTER_PATH = _SCRIPTS_DIRECTORY.parents[3] / "scripts/durable_post_lint.py"
31
29
  COMMENT_CLI = ["comment", "--repo", REPOSITORY, "--number", PR_NUMBER, "--body-file"]
32
30
  ACTION_CASES = [
33
31
  (
@@ -1,202 +1,9 @@
1
1
  ---
2
2
  name: skill-builder
3
3
  disable-model-invocation: true
4
- description: >-
5
- Skill lifecycle: classify, scaffold, write via the skill-writer-agent, self-audit, compose
6
- sub-skills, polish description triggers, enforce deterministic scripts. Triggers:
7
- build a skill, new skill workflow, improve this skill, optimize skill description,
8
- skill development lifecycle, skill modularity, skill composition, description
9
- trigger catalog, deterministic skill scripts.
4
+ description: Placeholder for the skill-builder rework to follow pstack philosophy.
10
5
  ---
11
6
 
12
- # Skill Builder
7
+ # Skill builder
13
8
 
14
- **Core principle:** Best-practice-driven craftsman. Knows every proven pattern, applies them intentionally, self-audits after building. The expert that enforces craft standards.
15
-
16
- Sources: [Anthropic best practices](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices), [Lessons from Building Claude Code](references/thariq-x-post-skills.json), model skills (bugteam, pr-converge).
17
-
18
- ## Gotchas
19
-
20
- Highest-signal content. Append a bullet each time a skill build fails in a new way.
21
-
22
- > "The highest-signal content in any skill is the Gotchas section. These sections should be built up from common failure points that Claude runs into when using your skill."
23
-
24
- - Story-form `description` burns always-on context and weakens selection — rewrite to capability stem + `Triggers:` list (`description-field.md`).
25
- - Multi-capability packages fail modularity audit — split or thin orchestrator + named sub-skills (`skill-modularity.md`).
26
- - Skipping the composition plan before Write reintroduces silent reimplementation of peer skills.
27
- - Deterministic steps written only as prose (fenced source, giant `rg` lines, multi-step mechanical sequences) fail audit — extract to `scripts/` / `workflow/` / `templates/` / `reference/` (`deterministic-elements.md`).
28
- - Markdown `- [ ]` checklists as the agent's progress board fail audit when a task tool exists — seed tasks via `TaskCreate` / `TodoWrite` (`deterministic-elements.md`).
29
-
30
- ## When this skill applies
31
-
32
- Trigger for requests to **build**, **improve**, or **polish** a skill. This skill orchestrates the process — it classifies, scaffolds, gathers context, delegates writing to the `skill-writer-agent` agent, and self-audits the result.
33
-
34
- For quick skill syntax questions or one-off SKILL.md edits, spawn the `skill-writer-agent` agent directly.
35
-
36
- **Refusal cases — first match wins:**
37
-
38
- - **No clear task or domain.** Respond exactly: `What should this skill do? Give me a one-sentence description of the capability.`
39
-
40
- ## The Process
41
-
42
- Each workflow file provides step-by-step instructions. After routing below, open the corresponding workflow file and follow it.
43
-
44
- ### Routing
45
-
46
- Assess the user’s intent:
47
-
48
- **Creating a new skill?**
49
- Read `${CLAUDE_SKILL_DIR}/workflows/new-skill.md` and follow it.
50
-
51
- **Improving an existing skill?**
52
- Read `${CLAUDE_SKILL_DIR}/workflows/improve-skill.md` and follow it.
53
-
54
- **Final polish only (description optimization, trigger audit)?**
55
- Read `${CLAUDE_SKILL_DIR}/workflows/polish-skill.md` and follow it.
56
-
57
- **Ambiguous?** Ask: "Are you creating a new skill, improving an existing one, or doing a final polish pass?"
58
-
59
- ### The Claude A / Claude B pattern
60
-
61
- You and the user are **Claude A** — the expert who designs and refines the skill. Subagents running the built skill on real tasks are **Claude B** — the agent using the skill to perform actual work.
62
-
63
- > "Work with one instance of Claude (‘Claude A’) to create a Skill that is used by other instances (‘Claude B’). Claude A helps you design and refine instructions, while Claude B tests them in real tasks."
64
-
65
- The feedback loop: observe Claude B’s behavior, bring insights back, refine the skill, test again.
66
-
67
- ## Skill type routing
68
-
69
- > "After cataloging all of our skills, we noticed they cluster into a few recurring categories."
70
-
71
- Classify into one of 9 types — type sets folder structure. Taxonomy and layouts: [`references/skill-types.md`](references/skill-types.md).
72
-
73
- ## Principles
74
-
75
- These are non-negotiable. Every skill must satisfy them. Enforce via [`references/self-audit-checklist.md`](references/self-audit-checklist.md).
76
-
77
- ### Concision and defaults
78
-
79
- > "Default assumption: Claude is already very smart. Only add context Claude doesn’t already have."
80
-
81
- > "Don’t State the Obvious — focus on information that pushes Claude out of its normal way of thinking."
82
-
83
- Challenge each sentence: "Does Claude really need this?"
84
-
85
- ### Degree of freedom
86
-
87
- > "Match the level of specificity to the task’s fragility and variability."
88
-
89
- High freedom (text guidance) for open fields. Low freedom (exact scripts, no parameters) for narrow bridges with cliffs.
90
-
91
- > "Avoid Railroading Claude — give Claude the information it needs, but give it the flexibility to adapt."
92
-
93
- ### Progressive disclosure
94
-
95
- Hub pattern, line caps, one-level references, TOC and path rules: [`references/progressive-disclosure.md`](references/progressive-disclosure.md).
96
-
97
- ### Modularity and composition
98
-
99
- One skill = one capability. Multi-step work invokes **sub-skills** (peer skills) by name. Prefer compose over reimplement. Full rules: [`references/skill-modularity.md`](references/skill-modularity.md).
100
-
101
- > "You can just reference other skills by name, and the model will invoke them if they are installed."
102
-
103
- New-skill Gather records a composition plan before write. Self-audit modularity items are mandatory.
104
-
105
- ### Description field (trigger catalog)
106
-
107
- The frontmatter `description` is **selection metadata** pre-loaded for every skill. Write a **trigger catalog**, not a story: short capability stem + concrete trigger phrases. No narrative, benefits language, or process dump.
108
-
109
- Full rules: [`references/description-field.md`](references/description-field.md). Polish workflow Step 1 is the dedicated rewrite pass.
110
-
111
- > "The description field is not a summary — it’s a description of when to trigger."
112
-
113
- ### Gotchas
114
-
115
- Mandatory highest-signal section (see Gotchas above). Capture real failure modes; self-audit requires the section present and actionable.
116
-
117
- ### Templates and examples
118
-
119
- > "Provide templates for output format" and "Examples help Claude understand the desired style and level of detail more clearly than descriptions alone."
120
-
121
- Use the template pattern for structured outputs. Use the examples pattern (input/output pairs) for style-dependent work.
122
-
123
- ### Workflows and task seeds
124
-
125
- Multi-step required work is a **task seed list** (plain bullets in a reference file) plus an instruction to register each item on the host task tool (`TaskCreate`, `TodoWrite`, or equivalent). Agents work the task list and mark complete with evidence.
126
-
127
- Do **not** ship markdown `- [ ]` boards as the completion protocol when a task tool is available. Do **not** say "copy this checklist into your response and check it off."
128
-
129
- Quality-critical operations still use feedback loops (run validator → fix → repeat). Spec: [`references/deterministic-elements.md`](references/deterministic-elements.md) (Task-tool tracking).
130
-
131
- ### Scripts
132
-
133
- > "Handle error conditions rather than punting to Claude." "Make clear whether Claude should execute the script or read it as reference."
134
-
135
- > "One of the most powerful tools you can give Claude is code — letting Claude spend its turns on composition rather than reconstructing boilerplate."
136
-
137
- ### Deterministic elements (mandatory classification)
138
-
139
- Any skill element that is **deterministic** (same inputs → same outputs; machine-checkable success) ships as code, a fixed artifact, or a **session task seed** — not prose-only steps or markdown checkbox boards. Judgment, routing, and refusals stay in markdown.
140
-
141
- Full rules, inventory table, task-tool tracking, CODE_RULES bar for skill scripts, and anti-patterns: [`references/deterministic-elements.md`](references/deterministic-elements.md).
142
-
143
- New-skill Gather records a deterministic-elements inventory before write. Self-audit items register as session tasks and are mandatory on every delivery (pure-judgment skills mark script rows N/A with evidence).
144
-
145
- ### Setup and memory
146
-
147
- > "Think through the Setup — some skills may need to be set up with context from the user. A good pattern is to store this in a config.json file."
148
-
149
- > "Data stored in the skill directory may be deleted when you upgrade the skill, so store persistent data in `${CLAUDE_PLUGIN_DATA}`."
150
-
151
- ### Constraints and refusal cases
152
-
153
- > bugteam pattern — non-negotiables separated from guidance, with design rationale. Explicit "first match wins" refusal conditions.
154
-
155
- ### Anti-patterns
156
-
157
- > No Windows paths. Don’t offer too many options — provide a default with escape hatch. Avoid time-sensitive claims. Use consistent terminology. No deeply nested references.
158
-
159
- Also: story-form descriptions; monolith multi-capability skills; silent reimplementation of peer skills; nested folders used as fake sub-skills; deterministic logic only in prose or fenced source; markdown `- [ ]` as the agent's work tracker.
160
-
161
- ## Self-audit
162
-
163
- After every build, improvement, or polish pass, load `${CLAUDE_SKILL_DIR}/references/self-audit-checklist.md`, **register every bullet as a session task**, and complete each with evidence. Every item must pass before delivery. Fix failures, then re-audit.
164
-
165
- ## Delegation to skill-writer-agent
166
-
167
- skill-builder orchestrates; the `skill-writer-agent` agent authors. The caller spawns it with `Agent(subagent_type="skill-writer-agent", ...)`. The handoff packet from Step 4 must include:
168
-
169
- - Skill type and folder structure
170
- - Gap analysis or observation findings (composition plan + description triggers + deterministic inventory)
171
- - Degree of freedom assessment
172
- - Initial gotchas
173
- - Composition plan: related skills, sub-skills to invoke, split decisions
174
- - Description trigger catalog: capability stem + trigger phrases (not prose)
175
- - Deterministic elements inventory: each process step classified; code paths + paired tests
176
- - Any constraints
177
-
178
- See `${CLAUDE_SKILL_DIR}/references/delegation-map.md` for exact patterns.
179
-
180
- ## File index
181
-
182
- | File | Purpose |
183
- |------|---------|
184
- | `SKILL.md` | This hub — principles, process, routing, file index |
185
- | `references/skill-types.md` | 9-type taxonomy with folder structures per type |
186
- | `references/progressive-disclosure.md` | Folder conventions, hub pattern, hard rules |
187
- | `references/skill-modularity.md` | Cross-skill modularity, sub-skills, composition plan |
188
- | `references/description-field.md` | Description as trigger catalog (not story prose) |
189
- | `references/deterministic-elements.md` | Deterministic steps as code/task seeds; CODE_RULES; no markdown checkbox boards |
190
- | `references/self-audit-checklist.md` | Post-build audit task seeds (register via TaskCreate / TodoWrite) |
191
- | `references/delegation-map.md` | Subagent handoff patterns and transcript guidance |
192
- | `workflows/new-skill.md` | Full lifecycle for new skills (6 steps) |
193
- | `workflows/improve-skill.md` | Observation-first flow for existing skills (6 steps) |
194
- | `workflows/polish-skill.md` | Description trigger-catalog audit and final validation (5 steps) |
195
- | `templates/gap-analysis.md` | Gaps, composition plan, description triggers, deterministic inventory |
196
-
197
- ## Folder map
198
-
199
- - `SKILL.md` — hub.
200
- - `references/` — best-practice specifications and the audit checklist.
201
- - `workflows/` — step-by-step workflows for each lifecycle phase.
202
- - `templates/` — reusable templates for skill artifacts.
9
+ TODO: Rework to follow pstack philosophy.
@@ -107,6 +107,12 @@ ALL_GIT_DIFF_CACHED_UNIFIED_ZERO_COMMAND: tuple[str, ...] = (
107
107
  "--unified=0",
108
108
  )
109
109
 
110
+ ALL_GIT_DIFF_UNIFIED_ZERO_COMMAND: tuple[str, ...] = (
111
+ "git",
112
+ "diff",
113
+ "--unified=0",
114
+ )
115
+
110
116
  GIT_DIFF_SUBPROCESS_TIMEOUT_SECONDS: int = 30
111
117
 
112
118
  GIT_NO_MATCH_EXIT_CODE: int = 1
@@ -32,6 +32,7 @@ from pr_loop_shared_constants.terminology_sweep_constants import (
32
32
  ALL_COMMON_ENGLISH_COMPOUND_TAIL_WORDS,
33
33
  ALL_DIFF_FILE_PATH_STRIP_PREFIXES,
34
34
  ALL_GIT_DIFF_CACHED_UNIFIED_ZERO_COMMAND,
35
+ ALL_GIT_DIFF_UNIFIED_ZERO_COMMAND,
35
36
  ALL_GIT_GREP_BASE_TREE_COMMAND_PREFIX,
36
37
  ALL_PROSE_STOPWORD_TOKENS,
37
38
  ALL_STRING_ESCAPE_SEQUENCES,
@@ -622,21 +623,23 @@ def _identifier_names_on_added_code_lines(diff_text: str) -> frozenset[str]:
622
623
 
623
624
 
624
625
  def _base_tree_names(
625
- repository_root: Path, all_names: frozenset[str]
626
+ repository_root: Path,
627
+ all_names: frozenset[str],
628
+ tree_revision: str,
626
629
  ) -> frozenset[str]:
627
- """Return the names the repository's base tree already contains.
630
+ """Return the names the comparison tree already contains.
628
631
 
629
- Each name is looked up as a whole word in the base revision's tree. A
630
- repository with no commits yet, or a lookup that git cannot run, reports
631
- the name as absent, so the sweep then treats it as newly introduced.
632
- That is the behaviour the sweep has with no base-tree check at all.
632
+ Each name is looked up as a whole word in ``tree_revision``. A repository
633
+ with no commits yet, or a lookup that git cannot run, reports the name as
634
+ absent, so the sweep treats it as newly introduced.
633
635
 
634
636
  Args:
635
637
  repository_root: The repository root the lookups run in.
636
638
  all_names: The identifier names to look up.
639
+ tree_revision: The revision whose tree is searched.
637
640
 
638
641
  Returns:
639
- The subset of names present in the base tree.
642
+ The subset of names present in that tree.
640
643
  """
641
644
  all_present_names: set[str] = set()
642
645
  for each_name in sorted(all_names):
@@ -645,7 +648,7 @@ def _base_tree_names(
645
648
  [
646
649
  *ALL_GIT_GREP_BASE_TREE_COMMAND_PREFIX,
647
650
  each_name,
648
- GIT_BASE_TREE_REVISION,
651
+ tree_revision,
649
652
  ],
650
653
  cwd=str(repository_root),
651
654
  capture_output=True,
@@ -695,14 +698,16 @@ def _raise_for_git_failure(
695
698
 
696
699
 
697
700
  def _strict_base_tree_names(
698
- repository_root: Path, all_names: frozenset[str]
701
+ repository_root: Path,
702
+ all_names: frozenset[str],
703
+ tree_revision: str,
699
704
  ) -> frozenset[str]:
700
705
  all_present_names: set[str] = set()
701
706
  for each_name in sorted(all_names):
702
707
  all_arguments = (
703
708
  *ALL_GIT_GREP_BASE_TREE_COMMAND_PREFIX,
704
709
  each_name,
705
- GIT_BASE_TREE_REVISION,
710
+ tree_revision,
706
711
  )
707
712
  grep_process = _run_strict_git(repository_root, all_arguments)
708
713
  if grep_process.returncode == 0:
@@ -728,14 +733,53 @@ def strict_staged_terminology_findings(repository_root: Path) -> list[str]:
728
733
  RuntimeError: Git could not read the staged diff or look up an
729
734
  identifier in HEAD.
730
735
  """
731
- diff_process = _run_strict_git(
732
- repository_root, ALL_GIT_DIFF_CACHED_UNIFIED_ZERO_COMMAND
736
+ return _strict_terminology_findings(
737
+ repository_root,
738
+ ALL_GIT_DIFF_CACHED_UNIFIED_ZERO_COMMAND,
739
+ GIT_BASE_TREE_REVISION,
733
740
  )
741
+
742
+
743
+ def strict_base_terminology_findings(
744
+ repository_root: Path, base_revision: str
745
+ ) -> list[str]:
746
+ """Return near-miss findings for worktree changes against a base revision.
747
+
748
+ Args:
749
+ repository_root: The repository root the worktree diff is read from.
750
+ base_revision: The tree that worktree changes are compared against.
751
+
752
+ Returns:
753
+ One finding string per near-miss term on an added prose line.
754
+
755
+ Raises:
756
+ RuntimeError: Git could not read the committed diff or look up an
757
+ identifier in the comparison tree.
758
+ """
759
+ all_arguments = (
760
+ *ALL_GIT_DIFF_UNIFIED_ZERO_COMMAND,
761
+ base_revision,
762
+ )
763
+ return _strict_terminology_findings(
764
+ repository_root,
765
+ all_arguments,
766
+ base_revision,
767
+ )
768
+
769
+
770
+ def _strict_terminology_findings(
771
+ repository_root: Path,
772
+ all_diff_arguments: Sequence[str],
773
+ tree_revision: str,
774
+ ) -> list[str]:
775
+ diff_process = _run_strict_git(repository_root, all_diff_arguments)
734
776
  _raise_for_git_failure(diff_process, GIT_DIFF_OPERATION)
735
777
  all_added_names = _identifier_names_on_added_code_lines(diff_process.stdout)
736
778
  preexisting_tuples = frozenset(
737
779
  _identifier_token_tuple(each_name)
738
- for each_name in _strict_base_tree_names(repository_root, all_added_names)
780
+ for each_name in _strict_base_tree_names(
781
+ repository_root, all_added_names, tree_revision
782
+ )
739
783
  )
740
784
  return _find_terminology_near_misses(diff_process.stdout, preexisting_tuples)
741
785
 
@@ -743,16 +787,15 @@ def strict_staged_terminology_findings(repository_root: Path) -> list[str]:
743
787
  def staged_terminology_findings(repository_root: Path) -> list[str]:
744
788
  """Return terminology near-miss findings for a repository's staged diff.
745
789
 
746
- An identifier the base tree already names is not one the staged diff
747
- introduces, so no prose is flagged against it. Only genuinely new
748
- identifiers are swept.
790
+ An identifier already present in HEAD is not treated as introduced, so
791
+ prose is not flagged against it.
749
792
 
750
793
  Args:
751
794
  repository_root: The repository root the staged diff is read from.
752
795
 
753
796
  Returns:
754
- One finding string per near-miss term on a staged added prose line, or
755
- an empty list when the staged diff is empty or git cannot be run.
797
+ One finding string per near-miss term on a staged prose line, or an
798
+ empty list when the staged diff is empty or git cannot be run.
756
799
  """
757
800
  diff_process = subprocess.run(
758
801
  list(ALL_GIT_DIFF_CACHED_UNIFIED_ZERO_COMMAND),
@@ -770,7 +813,9 @@ def staged_terminology_findings(repository_root: Path) -> list[str]:
770
813
  all_added_names = _identifier_names_on_added_code_lines(diff_process.stdout)
771
814
  preexisting_tuples = frozenset(
772
815
  _identifier_token_tuple(each_name)
773
- for each_name in _base_tree_names(repository_root, all_added_names)
816
+ for each_name in _base_tree_names(
817
+ repository_root, all_added_names, GIT_BASE_TREE_REVISION
818
+ )
774
819
  )
775
820
  return _find_terminology_near_misses(diff_process.stdout, preexisting_tuples)
776
821
 
@@ -31,6 +31,7 @@ sweep_module = _load_sweep_module()
31
31
  sweep_diff = sweep_module.sweep_diff
32
32
  staged_terminology_findings = sweep_module.staged_terminology_findings
33
33
  strict_staged_terminology_findings = sweep_module.strict_staged_terminology_findings
34
+ strict_base_terminology_findings = sweep_module.strict_base_terminology_findings
34
35
  main = sweep_module.main
35
36
  parse_added_lines = sweep_module._parse_added_lines
36
37
 
@@ -53,6 +54,54 @@ def _init_git_repository(repository_path: Path) -> None:
53
54
  )
54
55
 
55
56
 
57
+ def _run_repository_git(repository_path: Path, all_arguments: list[str]) -> str:
58
+ completed = subprocess.run(
59
+ all_arguments,
60
+ cwd=repository_path,
61
+ check=True,
62
+ capture_output=True,
63
+ text=True,
64
+ env=_hermetic_git_environment(),
65
+ )
66
+ return completed.stdout.strip()
67
+
68
+
69
+ def _write_repository_text(
70
+ repository_path: Path, relative_path: str, text: str
71
+ ) -> None:
72
+ (repository_path / relative_path).write_text(text, encoding="utf-8")
73
+
74
+
75
+ def _commit_all(repository_path: Path, message: str) -> None:
76
+ _run_repository_git(repository_path, ["git", "add", "-A"])
77
+ _run_repository_git(repository_path, ["git", "commit", "-m", message])
78
+
79
+
80
+ def _head_revision(repository_path: Path) -> str:
81
+ return _run_repository_git(repository_path, ["git", "rev-parse", "HEAD"])
82
+
83
+
84
+ def _committed_near_miss_repository(repository_path: Path) -> str:
85
+ _init_git_repository(repository_path)
86
+ _write_repository_text(repository_path, "quota.py", "baseline = 1\n")
87
+ _write_repository_text(repository_path, "README.md", "Baseline quota text.\n")
88
+ _commit_all(repository_path, "base")
89
+ comparison_revision = _head_revision(repository_path)
90
+ _write_repository_text(
91
+ repository_path,
92
+ "quota.py",
93
+ "baseline = 1\npremium_request_interactions = 5\n",
94
+ )
95
+ _commit_all(repository_path, "identifier")
96
+ _write_repository_text(
97
+ repository_path,
98
+ "README.md",
99
+ "The premium-request-budget field gates the run.\n",
100
+ )
101
+ _commit_all(repository_path, "documentation")
102
+ return comparison_revision
103
+
104
+
56
105
  CODE_AND_PROSE_DIFF = (
57
106
  "diff --git a/api/quota.py b/api/quota.py\n"
58
107
  "--- a/api/quota.py\n"
@@ -310,6 +359,16 @@ def test_staged_terminology_findings_empty_when_clean(tmp_path: Path) -> None:
310
359
  assert staged_terminology_findings(tmp_path) == []
311
360
 
312
361
 
362
+ def test_strict_base_terminology_findings_reports_committed_near_miss(
363
+ tmp_path: Path,
364
+ ) -> None:
365
+ comparison_revision = _committed_near_miss_repository(tmp_path)
366
+ all_findings = strict_base_terminology_findings(tmp_path, comparison_revision)
367
+ assert len(all_findings) == 1
368
+ assert "README.md:1" in all_findings[0]
369
+ assert "premium-request-budget" in all_findings[0]
370
+
371
+
313
372
  def test_parse_added_lines_counts_pre_increment_content_as_added_line() -> None:
314
373
  diff_with_pre_increment = (
315
374
  "diff --git a/app.mjs b/app.mjs\n"