project-init 0.5.2__tar.gz → 0.6.1__tar.gz

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 (545) hide show
  1. {project_init-0.5.2/templates/lifecycle/dot_claude → project_init-0.6.1/.claude}/hooks/dag_workflow.py +95 -11
  2. {project_init-0.5.2 → project_init-0.6.1}/.claude/scripts/monitor_pr.sh +57 -16
  3. {project_init-0.5.2 → project_init-0.6.1}/.claude/scripts/push_wiki.sh +7 -2
  4. {project_init-0.5.2 → project_init-0.6.1}/.claude/settings.json +1 -1
  5. project_init-0.6.1/.githooks/pre-push +34 -0
  6. {project_init-0.5.2 → project_init-0.6.1}/.github/workflows/ci.yml +41 -17
  7. {project_init-0.5.2 → project_init-0.6.1}/.github/workflows/docs.yml +4 -4
  8. {project_init-0.5.2 → project_init-0.6.1}/.github/workflows/release.yml +17 -7
  9. {project_init-0.5.2/templates/lifecycle/dot_github → project_init-0.6.1/.github}/workflows/review-status.yml +5 -1
  10. project_init-0.6.1/.github/workflows/tag-release.yml +68 -0
  11. {project_init-0.5.2 → project_init-0.6.1}/.github/workflows/third-party-updates.yml +2 -2
  12. {project_init-0.5.2 → project_init-0.6.1}/CITATION.cff +1 -1
  13. {project_init-0.5.2 → project_init-0.6.1}/CLAUDE.md +13 -3
  14. {project_init-0.5.2 → project_init-0.6.1}/CONTRIBUTING.md +5 -1
  15. {project_init-0.5.2 → project_init-0.6.1}/PKG-INFO +4 -8
  16. {project_init-0.5.2 → project_init-0.6.1}/README.md +3 -3
  17. project_init-0.6.1/docs/reviews/2026-07-project-review.md +249 -0
  18. {project_init-0.5.2 → project_init-0.6.1}/install.sh +33 -8
  19. {project_init-0.5.2 → project_init-0.6.1}/justfile +4 -2
  20. {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-lifecycle/.claude-plugin/plugin.json +1 -1
  21. {project_init-0.5.2/plugins/project-init-workflow → project_init-0.6.1/plugins/project-init-lifecycle}/hooks/_py.sh +2 -2
  22. {project_init-0.5.2/.claude → project_init-0.6.1/plugins/project-init-lifecycle}/hooks/dag_workflow.py +95 -11
  23. {project_init-0.5.2/templates/lifecycle_fallback/dot_claude → project_init-0.6.1/plugins/project-init-lifecycle}/hooks/github_command_guard.sh +1 -1
  24. {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-lifecycle/hooks/hooks.json +1 -1
  25. {project_init-0.5.2/templates/lifecycle_fallback/dot_claude → project_init-0.6.1/plugins/project-init-lifecycle}/hooks/workflow_state_reminder.sh +24 -4
  26. {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/.claude-plugin/plugin.json +1 -1
  27. {project_init-0.5.2/plugins/project-init-lifecycle → project_init-0.6.1/plugins/project-init-workflow}/hooks/_py.sh +2 -2
  28. {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/hooks/hooks.json +6 -0
  29. project_init-0.6.1/plugins/project-init-workflow/hooks/package_guard.py +370 -0
  30. project_init-0.6.1/plugins/project-init-workflow/hooks/post_edit_lint.sh +111 -0
  31. project_init-0.6.1/plugins/project-init-workflow/hooks/pre_commit_gate.sh +156 -0
  32. {project_init-0.5.2/templates/base/dot_claude → project_init-0.6.1/plugins/project-init-workflow}/hooks/prod_guard.py +10 -1
  33. {project_init-0.5.2/templates/fallback/dot_claude → project_init-0.6.1/plugins/project-init-workflow}/hooks/session_setup.sh +14 -8
  34. project_init-0.6.1/plugins/project-init-workflow/skills/report_upstream_issue/SKILL.md +114 -0
  35. {project_init-0.5.2 → project_init-0.6.1}/pyproject.toml +9 -4
  36. {project_init-0.5.2 → project_init-0.6.1}/renovate.json +2 -2
  37. {project_init-0.5.2 → project_init-0.6.1}/src/project_init/__init__.py +2 -2
  38. {project_init-0.5.2 → project_init-0.6.1}/src/project_init/__main__.py +261 -66
  39. {project_init-0.5.2 → project_init-0.6.1}/src/project_init/capabilities.py +19 -7
  40. {project_init-0.5.2 → project_init-0.6.1}/src/project_init/concerns.py +67 -17
  41. {project_init-0.5.2 → project_init-0.6.1}/src/project_init/governance.py +24 -4
  42. {project_init-0.5.2 → project_init-0.6.1}/src/project_init/mcps.py +12 -0
  43. {project_init-0.5.2 → project_init-0.6.1}/src/project_init/migration_notes.py +50 -7
  44. {project_init-0.5.2 → project_init-0.6.1}/src/project_init/scaffold.py +269 -57
  45. {project_init-0.5.2 → project_init-0.6.1}/src/project_init/surfaces.py +0 -9
  46. {project_init-0.5.2 → project_init-0.6.1}/src/project_init/upgrade.py +175 -21
  47. project_init-0.6.1/templates/amp/dot_agents/skills/report_upstream_issue/SKILL.md +114 -0
  48. project_init-0.6.1/templates/antigravity/dot_agents/skills/report_upstream_issue/SKILL.md +114 -0
  49. {project_init-0.5.2 → project_init-0.6.1}/templates/auto/dot_claude/scripts/lint_memory.sh +31 -15
  50. {project_init-0.5.2 → project_init-0.6.1}/templates/base/AGENTS.md.tmpl +4 -3
  51. {project_init-0.5.2 → project_init-0.6.1}/templates/base/Dockerfile.tmpl +34 -3
  52. project_init-0.6.1/templates/base/bunfig.toml.tmpl +14 -0
  53. project_init-0.6.1/templates/base/clippy.toml.tmpl +10 -0
  54. project_init-0.6.1/templates/base/deny.toml.tmpl +40 -0
  55. project_init-0.6.1/templates/base/dot_cargo/config.toml.tmpl +7 -0
  56. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/config.yaml.tmpl +1 -1
  57. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/hooks/_py.sh +2 -2
  58. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/hooks/agent_guard_adapter.py.tmpl +21 -9
  59. project_init-0.6.1/templates/base/dot_claude/hooks/package_guard.py +370 -0
  60. {project_init-0.5.2/plugins/project-init-workflow → project_init-0.6.1/templates/base/dot_claude}/hooks/prod_guard.py +10 -1
  61. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/project-init.md.tmpl +2 -1
  62. project_init-0.6.1/templates/base/dot_claude/rules/go.md +37 -0
  63. project_init-0.6.1/templates/base/dot_claude/rules/node.md +40 -0
  64. project_init-0.6.1/templates/base/dot_claude/rules/python.md +57 -0
  65. project_init-0.6.1/templates/base/dot_claude/rules/rust.md +64 -0
  66. project_init-0.6.1/templates/base/dot_claude/rules/typescript.md +45 -0
  67. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/scripts/gh_host.sh +14 -5
  68. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/scripts/setup_env_protection.sh.tmpl +32 -9
  69. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/scripts/whats_deployed.sh.tmpl +4 -3
  70. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/settings.json.tmpl +7 -1
  71. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/skills/README.md.tmpl +2 -1
  72. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_devcontainer/devcontainer.json.tmpl +4 -1
  73. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_env.example.tmpl +1 -1
  74. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_github/hooks/commit-msg +1 -1
  75. project_init-0.6.1/templates/base/dot_github/hooks/pre-commit +75 -0
  76. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_github/hooks/pre-push.tmpl +34 -0
  77. project_init-0.6.1/templates/base/dot_github/workflows/ci.yml.tmpl +722 -0
  78. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_github/workflows/deploy.yml.tmpl +12 -0
  79. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_github/workflows/registry-publish.yml.tmpl +18 -0
  80. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_github/workflows/release.yml.tmpl +72 -5
  81. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_gitignore.tmpl +7 -2
  82. project_init-0.6.1/templates/base/dot_gitleaks.toml +17 -0
  83. project_init-0.6.1/templates/base/dot_golangci.yml.tmpl +43 -0
  84. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_vscode/extensions.json.tmpl +2 -1
  85. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_vscode/settings.json.tmpl +4 -1
  86. project_init-0.6.1/templates/base/eslint.config.mjs.tmpl +87 -0
  87. project_init-0.6.1/templates/base/justfile.tmpl +315 -0
  88. {project_init-0.5.2 → project_init-0.6.1}/templates/base/mise.toml.tmpl +9 -1
  89. project_init-0.6.1/templates/base/mypy.ini.tmpl +19 -0
  90. project_init-0.6.1/templates/base/ruff.toml.tmpl +50 -0
  91. project_init-0.6.1/templates/base/rustfmt.toml.tmpl +4 -0
  92. project_init-0.6.1/templates/base/tsconfig.base.json.tmpl +19 -0
  93. project_init-0.6.1/templates/base/tsconfig.json.tmpl +6 -0
  94. project_init-0.6.1/templates/codex/dot_agents/skills/report_upstream_issue/SKILL.md +114 -0
  95. project_init-0.6.1/templates/fallback/dot_claude/hooks/post_edit_lint.sh +111 -0
  96. project_init-0.6.1/templates/fallback/dot_claude/hooks/pre_commit_gate.sh +156 -0
  97. {project_init-0.5.2/plugins/project-init-workflow → project_init-0.6.1/templates/fallback/dot_claude}/hooks/session_setup.sh +14 -8
  98. {project_init-0.5.2 → project_init-0.6.1}/templates/fallback/dot_claude/skills/INDEX.md.tmpl +1 -0
  99. project_init-0.6.1/templates/fallback/dot_claude/skills/report_upstream_issue/SKILL.md +114 -0
  100. {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/scripts/governance_gate.sh +6 -1
  101. project_init-0.6.1/templates/junie/dot_junie/skills/report_upstream_issue/SKILL.md +114 -0
  102. {project_init-0.5.2/plugins/project-init-lifecycle → project_init-0.6.1/templates/lifecycle/dot_claude}/hooks/dag_workflow.py +95 -11
  103. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/scripts/create_issue.sh +145 -107
  104. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/scripts/monitor_pr.sh +96 -25
  105. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/scripts/setup_github.sh +78 -52
  106. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/scripts/start_issue.sh +42 -25
  107. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/copilot-instructions.md.tmpl +1 -1
  108. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/workflows/board-automation.yml +44 -30
  109. project_init-0.6.1/templates/lifecycle/dot_github/workflows/issue-validation.yml +121 -0
  110. {project_init-0.5.2/plugins/project-init-lifecycle → project_init-0.6.1/templates/lifecycle_fallback/dot_claude}/hooks/github_command_guard.sh +1 -1
  111. {project_init-0.5.2/plugins/project-init-lifecycle → project_init-0.6.1/templates/lifecycle_fallback/dot_claude}/hooks/workflow_state_reminder.sh +24 -4
  112. {project_init-0.5.2 → project_init-0.6.1}/templates/multi_model/dot_claude/scripts/models.sh +44 -15
  113. {project_init-0.5.2 → project_init-0.6.1}/templates/multi_model/dot_claude/scripts/setup_models.sh +34 -17
  114. project_init-0.6.1/templates/observability/dot_claude/scripts/observability.sh +60 -0
  115. {project_init-0.5.2 → project_init-0.6.1}/templates/rag/dot_claude/scripts/setup_rag.sh +2 -2
  116. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_capabilities.py +9 -0
  117. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_cross_stack_examples.py +3 -3
  118. project_init-0.6.1/tests/contracts/test_dockerfile_lint.py +96 -0
  119. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_emission_hardening.py +7 -8
  120. project_init-0.6.1/tests/contracts/test_fuzzing.py +81 -0
  121. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_governance.py +10 -4
  122. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_governance_overlay.py +20 -0
  123. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_governance_product.py +73 -0
  124. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_hook_portability.py +15 -0
  125. project_init-0.6.1/tests/contracts/test_image_scan.py +79 -0
  126. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_justfile.py +105 -5
  127. project_init-0.6.1/tests/contracts/test_justfile_combinations.py +59 -0
  128. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_library_release.py +6 -1
  129. project_init-0.6.1/tests/contracts/test_license_scan.py +105 -0
  130. project_init-0.6.1/tests/contracts/test_lifecycle_byte_identity.py +217 -0
  131. project_init-0.6.1/tests/contracts/test_lifecycle_script_hardening.py +151 -0
  132. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_memory_byte_identity.py +85 -1
  133. project_init-0.6.1/tests/contracts/test_package_guard.py +247 -0
  134. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_parity_bundle.py +8 -4
  135. project_init-0.6.1/tests/contracts/test_post_edit_lint_typecheck.py +64 -0
  136. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_prod_guard.py +6 -0
  137. project_init-0.6.1/tests/contracts/test_provenance.py +88 -0
  138. project_init-0.6.1/tests/contracts/test_quality_toolchain.py +617 -0
  139. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_release_engineering.py +41 -5
  140. project_init-0.6.1/tests/contracts/test_sbom.py +100 -0
  141. project_init-0.6.1/tests/contracts/test_scorecard.py +72 -0
  142. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_templates.py +38 -0
  143. {project_init-0.5.2/tests/fixtures/memory_baseline → project_init-0.6.1/tests/fixtures/lifecycle_baseline}/obsidian-graphify__no_plugin.json +6 -6
  144. {project_init-0.5.2/tests/fixtures/memory_baseline → project_init-0.6.1/tests/fixtures/lifecycle_baseline}/obsidian-graphify__plugin.json +4 -4
  145. {project_init-0.5.2 → project_init-0.6.1}/tests/fixtures/lifecycle_baseline/obsidian-only__no_plugin.json +6 -6
  146. {project_init-0.5.2 → project_init-0.6.1}/tests/fixtures/lifecycle_baseline/obsidian-only__plugin.json +4 -4
  147. {project_init-0.5.2/tests/fixtures/lifecycle_baseline → project_init-0.6.1/tests/fixtures/memory_baseline}/obsidian-graphify__no_plugin.json +6 -6
  148. {project_init-0.5.2/tests/fixtures/lifecycle_baseline → project_init-0.6.1/tests/fixtures/memory_baseline}/obsidian-graphify__plugin.json +4 -4
  149. {project_init-0.5.2 → project_init-0.6.1}/tests/fixtures/memory_baseline/obsidian-only__no_plugin.json +6 -6
  150. {project_init-0.5.2 → project_init-0.6.1}/tests/fixtures/memory_baseline/obsidian-only__plugin.json +4 -4
  151. {project_init-0.5.2 → project_init-0.6.1}/tests/helpers.py +1 -0
  152. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_cli.py +39 -6
  153. project_init-0.6.1/tests/integration/test_commit_hook_gates.py +190 -0
  154. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_concern_add_remove.py +22 -0
  155. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_dag_workflow.py +64 -0
  156. project_init-0.6.1/tests/integration/test_gitignore_scaffold.py +77 -0
  157. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_issue_metadata_workflow.py +38 -2
  158. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_memory_backends.py +7 -1
  159. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_memory_starters.py +30 -0
  160. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_overwrite_protection.py +124 -0
  161. project_init-0.6.1/tests/integration/test_quality_gate_lint.py +94 -0
  162. project_init-0.6.1/tests/integration/test_report_upstream_issue_skill.py +91 -0
  163. project_init-0.6.1/tests/integration/test_shell_lint_gate.py +119 -0
  164. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_upgrade.py +41 -5
  165. project_init-0.6.1/tests/integration/test_upgrade_edges.py +87 -0
  166. project_init-0.6.1/tests/unit/test_audit_fixes.py +194 -0
  167. {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_presets_inheritance.py +11 -0
  168. {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_third_party_updates.py +16 -0
  169. {project_init-0.5.2 → project_init-0.6.1}/tools/check_third_party_updates.py +20 -18
  170. {project_init-0.5.2 → project_init-0.6.1}/tools/sync_plugin.py +69 -3
  171. {project_init-0.5.2 → project_init-0.6.1}/uv.lock +14 -8
  172. project_init-0.5.2/plugins/project-init-workflow/hooks/post_edit_lint.sh +0 -68
  173. project_init-0.5.2/plugins/project-init-workflow/hooks/pre_commit_gate.sh +0 -96
  174. project_init-0.5.2/templates/base/dot_claude/rules/go.md +0 -14
  175. project_init-0.5.2/templates/base/dot_claude/rules/node.md +0 -17
  176. project_init-0.5.2/templates/base/dot_claude/rules/python.md +0 -25
  177. project_init-0.5.2/templates/base/dot_github/hooks/pre-commit +0 -16
  178. project_init-0.5.2/templates/base/dot_github/workflows/ci.yml.tmpl +0 -328
  179. project_init-0.5.2/templates/base/dot_golangci.yml.tmpl +0 -20
  180. project_init-0.5.2/templates/base/eslint.config.mjs.tmpl +0 -29
  181. project_init-0.5.2/templates/base/justfile.tmpl +0 -113
  182. project_init-0.5.2/templates/base/ruff.toml.tmpl +0 -31
  183. project_init-0.5.2/templates/fallback/dot_claude/hooks/post_edit_lint.sh +0 -68
  184. project_init-0.5.2/templates/fallback/dot_claude/hooks/pre_commit_gate.sh +0 -96
  185. project_init-0.5.2/templates/lifecycle/dot_github/workflows/issue-validation.yml +0 -72
  186. project_init-0.5.2/templates/observability/dot_claude/scripts/observability.sh +0 -52
  187. project_init-0.5.2/tests/contracts/test_lifecycle_byte_identity.py +0 -116
  188. project_init-0.5.2/tests/contracts/test_quality_toolchain.py +0 -204
  189. project_init-0.5.2/tests/integration/test_quality_gate_lint.py +0 -52
  190. {project_init-0.5.2 → project_init-0.6.1}/.claude/hooks/github_command_guard.sh +0 -0
  191. {project_init-0.5.2 → project_init-0.6.1}/.claude/hooks/workflow_state_reminder.sh +0 -0
  192. {project_init-0.5.2 → project_init-0.6.1}/.claude/scripts/create_nojira_pr.sh +0 -0
  193. {project_init-0.5.2 → project_init-0.6.1}/.claude/scripts/finish_pr.sh +0 -0
  194. {project_init-0.5.2 → project_init-0.6.1}/.claude/scripts/promote_review.sh +0 -0
  195. {project_init-0.5.2 → project_init-0.6.1}/.claude/scripts/push_branch.sh +0 -0
  196. {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/INDEX.md +0 -0
  197. {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/README.md +0 -0
  198. {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/add_command/SKILL.md +0 -0
  199. {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/add_hook/SKILL.md +0 -0
  200. {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/github_workflow/SKILL.md +0 -0
  201. {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/live_test/SKILL.md +0 -0
  202. {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/session_summary/SKILL.md +0 -0
  203. {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/start_task/SKILL.md +0 -0
  204. {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/wiki/SKILL.md +0 -0
  205. {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/wiki/templates/architecture.md +0 -0
  206. {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/wiki/templates/implementation-guide.md +0 -0
  207. {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/wiki/templates/preset-guide.md +0 -0
  208. {project_init-0.5.2 → project_init-0.6.1}/.claude/skills/wiki/templates/scaffolder-logic.md +0 -0
  209. {project_init-0.5.2 → project_init-0.6.1}/.claude-plugin/marketplace.json +0 -0
  210. {project_init-0.5.2 → project_init-0.6.1}/.gitattributes +0 -0
  211. {project_init-0.5.2 → project_init-0.6.1}/.github/ISSUE_TEMPLATE/bug.yml +0 -0
  212. {project_init-0.5.2 → project_init-0.6.1}/.github/ISSUE_TEMPLATE/chore.yml +0 -0
  213. {project_init-0.5.2 → project_init-0.6.1}/.github/ISSUE_TEMPLATE/docs.yml +0 -0
  214. {project_init-0.5.2 → project_init-0.6.1}/.github/ISSUE_TEMPLATE/feature.yml +0 -0
  215. {project_init-0.5.2 → project_init-0.6.1}/.github/ISSUE_TEMPLATE/test.yml +0 -0
  216. {project_init-0.5.2 → project_init-0.6.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  217. {project_init-0.5.2 → project_init-0.6.1}/.github/copilot-instructions.md +0 -0
  218. {project_init-0.5.2 → project_init-0.6.1}/.github/workflows/board-automation.yml +0 -0
  219. {project_init-0.5.2 → project_init-0.6.1}/.github/workflows/validate-pr.yml +0 -0
  220. {project_init-0.5.2 → project_init-0.6.1}/.gitignore +0 -0
  221. {project_init-0.5.2 → project_init-0.6.1}/.gitleaks.toml +0 -0
  222. {project_init-0.5.2 → project_init-0.6.1}/AGENTS.md +0 -0
  223. {project_init-0.5.2 → project_init-0.6.1}/LICENSE +0 -0
  224. {project_init-0.5.2 → project_init-0.6.1}/cliff.toml +0 -0
  225. {project_init-0.5.2 → project_init-0.6.1}/docs/README.md +0 -0
  226. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-001-scaffolder-design.md +0 -0
  227. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-002-dotglob-template-convention.md +0 -0
  228. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-003-github-native-workflow.md +0 -0
  229. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-004-obsidian-docs-integration.md +0 -0
  230. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-005-github-pr-board-workflow.md +0 -0
  231. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-006-conventional-commit-titles.md +0 -0
  232. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-007-security-enforcement-layers.md +0 -0
  233. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-008-distribution-channel.md +0 -0
  234. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-009-graphify-memory-preset.md +0 -0
  235. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-010-plugin-marketplace-dual-ship.md +0 -0
  236. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-011-pypi-trusted-publishing.md +0 -0
  237. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-012-prod-safety-guard.md +0 -0
  238. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-013-distribution-governance-model.md +0 -0
  239. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-014-environment-promotion-chains.md +0 -0
  240. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-015-env-deploy-model.md +0 -0
  241. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-016-model-agnostic-switching.md +0 -0
  242. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-017-per-surface-config-generator.md +0 -0
  243. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-018-ai-governance-overlay.md +0 -0
  244. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-019-local-observability-overlay.md +0 -0
  245. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-020-memory-backend-decomposition.md +0 -0
  246. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-021-quality-vs-lifecycle-tier-boundary.md +0 -0
  247. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-022-toolchain-gate-map.md +0 -0
  248. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-023-wizard-explanation-standard.md +0 -0
  249. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-024-memory-tier-model.md +0 -0
  250. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-025-agentic-os-root-layer.md +0 -0
  251. {project_init-0.5.2 → project_init-0.6.1}/docs/adr/adr-026-tier3-rag-engine-cocoindex.md +0 -0
  252. {project_init-0.5.2 → project_init-0.6.1}/docs/development/agentic-os-root-layer.md +0 -0
  253. {project_init-0.5.2 → project_init-0.6.1}/docs/development/build-reproducibility.md +0 -0
  254. {project_init-0.5.2 → project_init-0.6.1}/docs/development/contributing.md +0 -0
  255. {project_init-0.5.2 → project_init-0.6.1}/docs/development/enforcement-classification.md +0 -0
  256. {project_init-0.5.2 → project_init-0.6.1}/docs/development/enterprise-github-support-matrix.md +0 -0
  257. {project_init-0.5.2 → project_init-0.6.1}/docs/development/measurement-methodology.md +0 -0
  258. {project_init-0.5.2 → project_init-0.6.1}/docs/development/memory-descriptor.md +0 -0
  259. {project_init-0.5.2 → project_init-0.6.1}/docs/development/mobile-remote-access.md +0 -0
  260. {project_init-0.5.2 → project_init-0.6.1}/docs/development/non-cli-surface-matrix.md +0 -0
  261. {project_init-0.5.2 → project_init-0.6.1}/docs/development/template-system.md +0 -0
  262. {project_init-0.5.2 → project_init-0.6.1}/docs/development/testing.md +0 -0
  263. {project_init-0.5.2 → project_init-0.6.1}/docs/guides/org-fork-lifecycle.md +0 -0
  264. {project_init-0.5.2 → project_init-0.6.1}/docs/guides/using-project-init.md +0 -0
  265. {project_init-0.5.2 → project_init-0.6.1}/docs/positioning.md +0 -0
  266. {project_init-0.5.2 → project_init-0.6.1}/docs/research/model-agnostic-switching.md +0 -0
  267. {project_init-0.5.2 → project_init-0.6.1}/mkdocs.yml +0 -0
  268. {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-lifecycle/hooks/_usage_log.sh +0 -0
  269. {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-lifecycle/skills/audit/SKILL.md +0 -0
  270. {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-lifecycle/skills/create_issue/SKILL.md +0 -0
  271. {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-lifecycle/skills/github_workflow/SKILL.md +0 -0
  272. {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-lifecycle/skills/request_review/SKILL.md +0 -0
  273. {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-lifecycle/skills/start_task/SKILL.md +0 -0
  274. {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/hooks/_usage_log.sh +0 -0
  275. {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/skills/add_adr/SKILL.md +0 -0
  276. {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/skills/add_command/SKILL.md +0 -0
  277. {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/skills/add_hook/SKILL.md +0 -0
  278. {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/skills/review/SKILL.md +0 -0
  279. {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/skills/save_memory/SKILL.md +0 -0
  280. {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/skills/session_summary/SKILL.md +0 -0
  281. {project_init-0.5.2 → project_init-0.6.1}/plugins/project-init-workflow/skills/status/SKILL.md +0 -0
  282. {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/add_adr/SKILL.md +0 -0
  283. {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/add_command/SKILL.md +0 -0
  284. {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/add_hook/SKILL.md +0 -0
  285. {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/audit/SKILL.md.tmpl +0 -0
  286. {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/create_issue/SKILL.md.tmpl +0 -0
  287. {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/github_workflow/SKILL.md.tmpl +0 -0
  288. {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/plan/SKILL.md +0 -0
  289. {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/request_review/SKILL.md.tmpl +0 -0
  290. {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/review/SKILL.md +0 -0
  291. {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/save_memory/SKILL.md +0 -0
  292. {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/session_summary/SKILL.md +0 -0
  293. {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/start_task/SKILL.md.tmpl +0 -0
  294. {project_init-0.5.2 → project_init-0.6.1}/templates/amp/dot_agents/skills/status/SKILL.md +0 -0
  295. {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/add_adr/SKILL.md +0 -0
  296. {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/add_command/SKILL.md +0 -0
  297. {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/add_hook/SKILL.md +0 -0
  298. {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/audit/SKILL.md.tmpl +0 -0
  299. {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/create_issue/SKILL.md.tmpl +0 -0
  300. {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/github_workflow/SKILL.md.tmpl +0 -0
  301. {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/plan/SKILL.md +0 -0
  302. {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/request_review/SKILL.md.tmpl +0 -0
  303. {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/review/SKILL.md +0 -0
  304. {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/save_memory/SKILL.md +0 -0
  305. {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/session_summary/SKILL.md +0 -0
  306. {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/start_task/SKILL.md.tmpl +0 -0
  307. {project_init-0.5.2 → project_init-0.6.1}/templates/antigravity/dot_agents/skills/status/SKILL.md +0 -0
  308. {project_init-0.5.2 → project_init-0.6.1}/templates/auto/dot_claude/memory/MEMORY.md.tmpl +0 -0
  309. {project_init-0.5.2 → project_init-0.6.1}/templates/auto/dot_claude/memory/README.md +0 -0
  310. {project_init-0.5.2 → project_init-0.6.1}/templates/auto/dot_claude/memory/SCHEMA.md +0 -0
  311. {project_init-0.5.2 → project_init-0.6.1}/templates/auto/dot_claude/memory/feedback_conventions.md +0 -0
  312. {project_init-0.5.2 → project_init-0.6.1}/templates/auto/dot_claude/memory/project_context.md.tmpl +0 -0
  313. {project_init-0.5.2 → project_init-0.6.1}/templates/auto/dot_claude/memory/user_role.md +0 -0
  314. {project_init-0.5.2 → project_init-0.6.1}/templates/base/CLAUDE.md.tmpl +0 -0
  315. {project_init-0.5.2 → project_init-0.6.1}/templates/base/CONTRIBUTING.md.tmpl +0 -0
  316. {project_init-0.5.2 → project_init-0.6.1}/templates/base/LICENSE.tmpl +0 -0
  317. {project_init-0.5.2 → project_init-0.6.1}/templates/base/SECURITY.md.tmpl +0 -0
  318. {project_init-0.5.2 → project_init-0.6.1}/templates/base/compose.yaml.tmpl +0 -0
  319. {project_init-0.5.2 → project_init-0.6.1}/templates/base/deploy/environments.yaml.tmpl +0 -0
  320. {project_init-0.5.2 → project_init-0.6.1}/templates/base/docs/explanation/index.md.tmpl +0 -0
  321. {project_init-0.5.2 → project_init-0.6.1}/templates/base/docs/how-to/index.md.tmpl +0 -0
  322. {project_init-0.5.2 → project_init-0.6.1}/templates/base/docs/index.md.tmpl +0 -0
  323. {project_init-0.5.2 → project_init-0.6.1}/templates/base/docs/reference/index.md.tmpl +0 -0
  324. {project_init-0.5.2 → project_init-0.6.1}/templates/base/docs/tutorials/index.md.tmpl +0 -0
  325. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/agents/README.md +0 -0
  326. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/agents/code-reviewer.md +0 -0
  327. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/agents/explore.md +0 -0
  328. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/docs/README.md.tmpl +0 -0
  329. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/docs/adr/adr-002-mcp-choices.md.tmpl +0 -0
  330. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/docs/adr/adr-template.md +0 -0
  331. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/docs/development/conventions.md.tmpl +0 -0
  332. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/docs/development/testing.md +0 -0
  333. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/docs/guides/cloud-integration.md.tmpl +0 -0
  334. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/docs/guides/developer-onboarding.md +0 -0
  335. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/docs/guides/environments.md +0 -0
  336. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/docs/guides/secrets.md +0 -0
  337. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/hooks/README.md +0 -0
  338. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/rules/hooks.md.tmpl +0 -0
  339. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/scripts/README.md.tmpl +0 -0
  340. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/scripts/gen_code_map.py.tmpl +0 -0
  341. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/scripts/install_hooks.sh +0 -0
  342. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_claude/skills/plan/SKILL.md.tmpl +0 -0
  343. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_devcontainer/post-create.sh.tmpl +0 -0
  344. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_dockerignore.tmpl +0 -0
  345. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_gitattributes +0 -0
  346. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_github/CODEOWNERS.tmpl +0 -0
  347. {project_init-0.5.2 → project_init-0.6.1}/templates/base/dot_github/workflows/infra.yml.tmpl +0 -0
  348. {project_init-0.5.2 → project_init-0.6.1}/templates/base/infra/README.md.tmpl +0 -0
  349. {project_init-0.5.2 → project_init-0.6.1}/templates/base/infra/backend.tf.tmpl +0 -0
  350. {project_init-0.5.2 → project_init-0.6.1}/templates/base/infra/dot_gitignore.tmpl +0 -0
  351. {project_init-0.5.2 → project_init-0.6.1}/templates/base/infra/dot_pre-commit-config.yaml.tmpl +0 -0
  352. {project_init-0.5.2 → project_init-0.6.1}/templates/base/infra/main.tf.tmpl +0 -0
  353. {project_init-0.5.2 → project_init-0.6.1}/templates/base/infra/outputs.tf.tmpl +0 -0
  354. {project_init-0.5.2 → project_init-0.6.1}/templates/base/infra/variables.tf.tmpl +0 -0
  355. {project_init-0.5.2 → project_init-0.6.1}/templates/base/infra/versions.tf.tmpl +0 -0
  356. {project_init-0.5.2 → project_init-0.6.1}/templates/base/mkdocs.yml.tmpl +0 -0
  357. {project_init-0.5.2 → project_init-0.6.1}/templates/base/renovate.json.tmpl +0 -0
  358. {project_init-0.5.2 → project_init-0.6.1}/templates/base/typedoc.json.tmpl +0 -0
  359. {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/add_adr/SKILL.md +0 -0
  360. {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/add_command/SKILL.md +0 -0
  361. {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/add_hook/SKILL.md +0 -0
  362. {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/audit/SKILL.md.tmpl +0 -0
  363. {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/create_issue/SKILL.md.tmpl +0 -0
  364. {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/github_workflow/SKILL.md.tmpl +0 -0
  365. {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/plan/SKILL.md +0 -0
  366. {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/request_review/SKILL.md.tmpl +0 -0
  367. {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/review/SKILL.md +0 -0
  368. {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/save_memory/SKILL.md +0 -0
  369. {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/session_summary/SKILL.md +0 -0
  370. {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/start_task/SKILL.md.tmpl +0 -0
  371. {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_agents/skills/status/SKILL.md +0 -0
  372. {project_init-0.5.2 → project_init-0.6.1}/templates/codex/dot_codex/hooks.json.tmpl +0 -0
  373. {project_init-0.5.2 → project_init-0.6.1}/templates/fallback/dot_claude/hooks/_usage_log.sh +0 -0
  374. {project_init-0.5.2 → project_init-0.6.1}/templates/fallback/dot_claude/skills/add_adr/SKILL.md +0 -0
  375. {project_init-0.5.2 → project_init-0.6.1}/templates/fallback/dot_claude/skills/add_command/SKILL.md +0 -0
  376. {project_init-0.5.2 → project_init-0.6.1}/templates/fallback/dot_claude/skills/add_hook/SKILL.md +0 -0
  377. {project_init-0.5.2 → project_init-0.6.1}/templates/fallback/dot_claude/skills/review/SKILL.md +0 -0
  378. {project_init-0.5.2 → project_init-0.6.1}/templates/fallback/dot_claude/skills/save_memory/SKILL.md +0 -0
  379. {project_init-0.5.2 → project_init-0.6.1}/templates/fallback/dot_claude/skills/session_summary/SKILL.md +0 -0
  380. {project_init-0.5.2 → project_init-0.6.1}/templates/fallback/dot_claude/skills/status/SKILL.md +0 -0
  381. {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/AI_USAGE_POLICY.md +0 -0
  382. {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/NIST_RMF_CROSSWALK.md +0 -0
  383. {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/README.md +0 -0
  384. {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/ai-code-provenance.md +0 -0
  385. {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/ai-declarations.md +0 -0
  386. {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/approved-tools.md +0 -0
  387. {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/config.example.json +0 -0
  388. {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/data-handling.md +0 -0
  389. {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/examples/SYSTEM_CARD.example.md +0 -0
  390. {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/governance/examples/SYSTEM_CARD.template.md +0 -0
  391. {project_init-0.5.2 → project_init-0.6.1}/templates/governance/dot_claude/scripts/governance_gate.py +0 -0
  392. {project_init-0.5.2 → project_init-0.6.1}/templates/graphify/dot_claude/docs/guides/using-graphify.md +0 -0
  393. {project_init-0.5.2 → project_init-0.6.1}/templates/graphify/dot_claude/rules/graphify.md +0 -0
  394. {project_init-0.5.2 → project_init-0.6.1}/templates/graphify/dot_claude/scripts/setup_graphify.sh +0 -0
  395. {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/add_adr/SKILL.md +0 -0
  396. {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/add_command/SKILL.md +0 -0
  397. {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/add_hook/SKILL.md +0 -0
  398. {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/audit/SKILL.md.tmpl +0 -0
  399. {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/create_issue/SKILL.md.tmpl +0 -0
  400. {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/github_workflow/SKILL.md.tmpl +0 -0
  401. {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/plan/SKILL.md +0 -0
  402. {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/request_review/SKILL.md.tmpl +0 -0
  403. {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/review/SKILL.md +0 -0
  404. {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/save_memory/SKILL.md +0 -0
  405. {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/session_summary/SKILL.md +0 -0
  406. {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/start_task/SKILL.md.tmpl +0 -0
  407. {project_init-0.5.2 → project_init-0.6.1}/templates/junie/dot_junie/skills/status/SKILL.md +0 -0
  408. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/docs/guides/issue-metadata.md +0 -0
  409. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/scripts/create_nojira_pr.sh +0 -0
  410. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/scripts/finish_pr.sh +0 -0
  411. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/scripts/promote_review.sh +0 -0
  412. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/scripts/push_branch.sh +0 -0
  413. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_claude/scripts/push_wiki.sh +0 -0
  414. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/ISSUE_TEMPLATE/bug.yml +0 -0
  415. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/ISSUE_TEMPLATE/chore.yml +0 -0
  416. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/ISSUE_TEMPLATE/config.yml +0 -0
  417. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/ISSUE_TEMPLATE/docs.yml +0 -0
  418. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/ISSUE_TEMPLATE/feature.yml +0 -0
  419. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/ISSUE_TEMPLATE/test.yml +0 -0
  420. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/pull_request_template.md +0 -0
  421. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/workflows/project-init-upgrade.yml.tmpl +0 -0
  422. {project_init-0.5.2/.github → project_init-0.6.1/templates/lifecycle/dot_github}/workflows/review-status.yml +0 -0
  423. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle/dot_github/workflows/validate-pr.yml.tmpl +0 -0
  424. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle_fallback/dot_claude/skills/audit/SKILL.md +0 -0
  425. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle_fallback/dot_claude/skills/create_issue/SKILL.md +0 -0
  426. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle_fallback/dot_claude/skills/github_workflow/SKILL.md +0 -0
  427. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle_fallback/dot_claude/skills/request_review/SKILL.md +0 -0
  428. {project_init-0.5.2 → project_init-0.6.1}/templates/lifecycle_fallback/dot_claude/skills/start_task/SKILL.md +0 -0
  429. {project_init-0.5.2 → project_init-0.6.1}/templates/multi_model/dot_claude/docs/guides/using-multi-model.md +0 -0
  430. {project_init-0.5.2 → project_init-0.6.1}/templates/multi_model/dot_claude/multi-model/README.md +0 -0
  431. {project_init-0.5.2 → project_init-0.6.1}/templates/multi_model/dot_claude/multi-model/config.json +0 -0
  432. {project_init-0.5.2 → project_init-0.6.1}/templates/multi_model/dot_claude/multi-model/dot_env.example +0 -0
  433. {project_init-0.5.2 → project_init-0.6.1}/templates/observability/dot_claude/docs/guides/upgrading-observability.md +0 -0
  434. {project_init-0.5.2 → project_init-0.6.1}/templates/observability/dot_claude/docs/guides/using-observability.md +0 -0
  435. {project_init-0.5.2 → project_init-0.6.1}/templates/observability/dot_claude/observability/.keep +0 -0
  436. {project_init-0.5.2 → project_init-0.6.1}/templates/observability/dot_claude/observability/README.md +0 -0
  437. {project_init-0.5.2 → project_init-0.6.1}/templates/observability/dot_claude/observability/dot_gitignore +0 -0
  438. {project_init-0.5.2 → project_init-0.6.1}/templates/observability/dot_claude/observability/usage_report.py +0 -0
  439. {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/docs/adr/adr-001-memory-stack.md.tmpl +0 -0
  440. {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/docs/guides/using-memory.md +0 -0
  441. {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/README.md +0 -0
  442. {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/decisions/README.md +0 -0
  443. {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/decisions/adr-000-project-setup.md.tmpl +0 -0
  444. {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/design/README.md +0 -0
  445. {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/dot_obsidian/README.md +0 -0
  446. {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/dot_obsidian/app.json +0 -0
  447. {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/dot_obsidian/community-plugins.json +0 -0
  448. {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/dot_obsidian/core-plugins.json +0 -0
  449. {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/knowledge/README.md +0 -0
  450. {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/log.md +0 -0
  451. {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/sessions/README.md +0 -0
  452. {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/templates/decision.md +0 -0
  453. {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/templates/design-note.md +0 -0
  454. {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/templates/knowledge-note.md +0 -0
  455. {project_init-0.5.2 → project_init-0.6.1}/templates/obsidian/dot_claude/vault/templates/session-note.md +0 -0
  456. {project_init-0.5.2 → project_init-0.6.1}/templates/presets/auto.toml +0 -0
  457. {project_init-0.5.2 → project_init-0.6.1}/templates/presets/core.toml +0 -0
  458. {project_init-0.5.2 → project_init-0.6.1}/templates/presets/governed.toml +0 -0
  459. {project_init-0.5.2 → project_init-0.6.1}/templates/presets/obsidian-graphify.toml +0 -0
  460. {project_init-0.5.2 → project_init-0.6.1}/templates/presets/obsidian-only.toml +0 -0
  461. {project_init-0.5.2 → project_init-0.6.1}/templates/rag/dot_claude/docs/guides/using-rag.md +0 -0
  462. {project_init-0.5.2 → project_init-0.6.1}/templates/rag/dot_claude/rules/rag.md +0 -0
  463. {project_init-0.5.2 → project_init-0.6.1}/tests/__init__.py +0 -0
  464. {project_init-0.5.2 → project_init-0.6.1}/tests/conftest.py +0 -0
  465. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_agent_overlays.py +0 -0
  466. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_agents_canonical.py +0 -0
  467. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_benchmark_cost_latency.py +0 -0
  468. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_benchmark_harness.py +0 -0
  469. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_benchmark_report.py +0 -0
  470. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_benchmark_scoring.py +0 -0
  471. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_deploy_overlay.py +0 -0
  472. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_docs_renovate.py +0 -0
  473. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_enforcement.py +0 -0
  474. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_enterprise_host.py +0 -0
  475. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_env_tooling.py +0 -0
  476. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_iac_overlay.py +0 -0
  477. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_integration_seam.py +0 -0
  478. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_integrity.py +0 -0
  479. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_interpreter_portability.py +0 -0
  480. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_lifecycle_none.py +0 -0
  481. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_marketplace_source.py +0 -0
  482. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_memory_none.py +0 -0
  483. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_multi_model_overlay.py +0 -0
  484. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_no_bytecode_leak.py +0 -0
  485. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_no_egress.py +0 -0
  486. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_observability_overlay.py +0 -0
  487. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_observability_report.py +0 -0
  488. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_observability_self_log.py +0 -0
  489. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_plugin_marketplace.py +0 -0
  490. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_portability_hardening.py +0 -0
  491. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_renovate.py +0 -0
  492. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_repo_validate_pr.py +0 -0
  493. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_scaffold_graphify.py +0 -0
  494. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_scaffold_obsidian.py +0 -0
  495. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_session_bootstrap.py +0 -0
  496. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_skill_index.py +0 -0
  497. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_subagent_specs.py +0 -0
  498. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_surface_emission.py +0 -0
  499. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_third_party_pin_contract.py +0 -0
  500. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_upgrade_pr_workflow.py +0 -0
  501. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_variable_contract.py +0 -0
  502. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_wiki_skill.py +0 -0
  503. {project_init-0.5.2 → project_init-0.6.1}/tests/contracts/test_wizard_explanations.py +0 -0
  504. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_code_map.py +0 -0
  505. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_combination_matrix.py +0 -0
  506. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_compose_interop.py +0 -0
  507. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_concern_skill_gating.py +0 -0
  508. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_consent.py +0 -0
  509. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_hooks_and_safety.py +0 -0
  510. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_install_script.py +0 -0
  511. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_json_output.py +0 -0
  512. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_lifecycle.py +0 -0
  513. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_memory_descriptor.py +0 -0
  514. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_observability.py +0 -0
  515. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_org_lifecycle.py +0 -0
  516. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_rag_seam.py +0 -0
  517. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_readme_examples.py +0 -0
  518. {project_init-0.5.2 → project_init-0.6.1}/tests/integration/test_session_cold_start.py +0 -0
  519. {project_init-0.5.2 → project_init-0.6.1}/tests/smoke/test_packaging.py +0 -0
  520. {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_command_variables.py +0 -0
  521. {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_interactive_prompts.py +0 -0
  522. {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_mcps.py +0 -0
  523. {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_migration_notes.py +0 -0
  524. {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_presets.py +0 -0
  525. {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_profile.py +0 -0
  526. {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_render_nesting.py +0 -0
  527. {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_scaffold_inputs.py +0 -0
  528. {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_shell_portability.py +0 -0
  529. {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_surfaces.py +0 -0
  530. {project_init-0.5.2 → project_init-0.6.1}/tests/unit/test_version_span.py +0 -0
  531. {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/README.md +0 -0
  532. {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/harness.py +0 -0
  533. {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/latency.py +0 -0
  534. {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/model_prices.json +0 -0
  535. {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/prices.py +0 -0
  536. {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/record.py +0 -0
  537. {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/report.py +0 -0
  538. {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/scoring.py +0 -0
  539. {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/tasks/feat.toml +0 -0
  540. {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/tasks/fix.toml +0 -0
  541. {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/tasks/noop.toml +0 -0
  542. {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/tasks/qa.toml +0 -0
  543. {project_init-0.5.2 → project_init-0.6.1}/tools/benchmark/transcript.py +0 -0
  544. {project_init-0.5.2 → project_init-0.6.1}/tools/pinned_third_party.toml +0 -0
  545. {project_init-0.5.2 → project_init-0.6.1}/tools/propose_third_party_bumps.sh +0 -0
@@ -42,8 +42,6 @@ import sys
42
42
  import time
43
43
  from pathlib import Path
44
44
 
45
- CACHE_PATH = Path(".claude/.workflow-state.json")
46
-
47
45
  GRAPH: dict[str, list[str]] = {
48
46
  "issue.created": [],
49
47
  "branch.created": [],
@@ -64,8 +62,11 @@ else:
64
62
 
65
63
 
66
64
  def _run(cmd: list[str]) -> tuple[int, str]:
65
+ # Per-call timeout must stay well below the hook budget (settings.json
66
+ # "timeout": 60): a PreToolUse hook that exceeds its budget is killed and
67
+ # FAILS OPEN, so one hung gh call must never eat the whole allowance.
67
68
  try:
68
- proc = subprocess.run(cmd, capture_output=True, text=True, timeout=15)
69
+ proc = subprocess.run(cmd, capture_output=True, text=True, timeout=10) # noqa: S603 — argv list built from internal literals/validated state, never a shell string
69
70
  except (subprocess.TimeoutExpired, FileNotFoundError):
70
71
  return 1, ""
71
72
  return proc.returncode, proc.stdout
@@ -253,6 +254,17 @@ COMMAND_RULES: list[tuple[re.Pattern[str], str | None, str]] = [
253
254
  "pr.merged",
254
255
  "Use .claude/scripts/monitor_pr.sh <pr> --merge instead of `gh api .../merge` so CI and review gates are honored.",
255
256
  ),
257
+ (
258
+ # GraphQL merges bypass the REST-path rule above (2026-07 review): a
259
+ # `gh api graphql` mutation can merge or enable auto-merge without ever
260
+ # naming `/pulls/N/merge`. Block the mutation fields themselves.
261
+ re.compile(
262
+ r"\bgh\s+api\b[^&;]*\bgraphql\b[^&;]*"
263
+ r"(?:mergePullRequest|enablePullRequestAutoMerge)"
264
+ ),
265
+ "pr.merged",
266
+ "Use .claude/scripts/monitor_pr.sh <pr> --merge instead of a `gh api graphql` merge mutation so CI and review gates are honored.",
267
+ ),
256
268
  (
257
269
  re.compile(r"\bgh\s+pr\s+merge\b"),
258
270
  "pr.merged",
@@ -291,12 +303,69 @@ _HEREDOC_RE = re.compile(
291
303
  re.DOTALL,
292
304
  )
293
305
 
306
+ # Git global options that sit BETWEEN `git` and the subcommand (`git -C dir
307
+ # push`, `git -c k=v push`). Left unnormalized they defeat every `git push`
308
+ # rule, including the direct-push-to-main block (2026-07 review). Options that
309
+ # consume a value are listed with their value; boolean options stand alone.
310
+ # An option value is one shell word INCLUDING quoted runs — `-c foo='a b'`
311
+ # must normalize away too: a bare \S+ stops at the space inside the quotes
312
+ # and the mangled residue defeats every git rule (mirrors the quoted-value
313
+ # matcher in pre_commit_gate.sh).
314
+ _GIT_OPT_VAL = r"(?:[^\s'\"]|'[^']*'|\"[^\"]*\")+"
315
+ _GIT_GLOBAL_OPT = (
316
+ r"(?:"
317
+ rf"-C[ \t]+{_GIT_OPT_VAL}" # -C <path>
318
+ rf"|-c[ \t]+{_GIT_OPT_VAL}" # -c <name=value>
319
+ rf"|--git-dir(?:={_GIT_OPT_VAL}|[ \t]+{_GIT_OPT_VAL})"
320
+ rf"|--work-tree(?:={_GIT_OPT_VAL}|[ \t]+{_GIT_OPT_VAL})"
321
+ rf"|--namespace(?:={_GIT_OPT_VAL}|[ \t]+{_GIT_OPT_VAL})"
322
+ rf"|--config-env(?:={_GIT_OPT_VAL}|[ \t]+{_GIT_OPT_VAL})"
323
+ rf"|--exec-path(?:={_GIT_OPT_VAL})?"
324
+ r"|--no-pager|--paginate|-p|-P|--bare"
325
+ r"|--no-replace-objects|--literal-pathspecs|--no-optional-locks|--icase-pathspecs"
326
+ r")"
327
+ )
328
+ _GIT_NORMALIZE_RE = re.compile(r"\bgit((?:[ \t]+" + _GIT_GLOBAL_OPT + r")+)[ \t]+")
329
+
330
+ # An interpreter receiving a heredoc executes its body, so a guarded command
331
+ # hidden in `bash <<'EOF' … EOF` must still be scanned (2026-07 review). The
332
+ # negative lookbehind lets `/bin/bash` match while sparing `rebash`.
333
+ _INTERP = r"(?:bash|sh|zsh|dash|ksh|python3?|python2|eval|source)"
334
+ _INTERP_INTRO_RE = re.compile(r"(?<![\w.-])" + _INTERP + r"\b")
335
+ _PIPE_INTERP_RE = re.compile(r"^\s*\|\s*(?:sudo[ \t]+)?(?<![\w.-])" + _INTERP + r"\b")
336
+
337
+
338
+ def _normalize_git_globals(cmd: str) -> str:
339
+ """Rewrite ``git <global-opts> <subcommand>`` to ``git <subcommand>`` for
340
+ matching, so interposed ``-C``/``-c``/``--git-dir`` flags can't smuggle a
341
+ push past the rules (2026-07 review)."""
342
+ return _GIT_NORMALIZE_RE.sub("git ", cmd)
343
+
294
344
 
295
345
  def _strip_heredocs(cmd: str) -> str:
296
346
  """Remove heredoc body text so pattern rules don't fire on body content."""
297
347
  return _HEREDOC_RE.sub("", cmd)
298
348
 
299
349
 
350
+ def _executing_heredoc_bodies(cmd: str) -> str:
351
+ """Concatenate heredoc bodies that WILL run — those fed to an interpreter
352
+ directly (``bash <<EOF``) or via a pipe (``cat <<EOF … | bash``).
353
+
354
+ ``_strip_heredocs`` removes every body to spare prose (a commit message or
355
+ ``gh pr comment --body-file - <<EOF`` mentioning "git push main"), but that
356
+ also hid genuinely-executing bodies. Re-surfacing only the interpreter-fed
357
+ ones keeps prose exempt while closing the execution bypass (2026-07 review).
358
+ """
359
+ bodies = []
360
+ for m in _HEREDOC_RE.finditer(cmd):
361
+ line_start = cmd.rfind("\n", 0, m.start()) + 1
362
+ intro = cmd[line_start : m.start()]
363
+ after = cmd[m.end() : m.end() + 60]
364
+ if _INTERP_INTRO_RE.search(intro) or _PIPE_INTERP_RE.match(after):
365
+ bodies.append(m.group(0))
366
+ return "\n".join(bodies)
367
+
368
+
300
369
  # Free-text flag values carry arbitrary prose (commit messages, issue/PR comment
301
370
  # and release bodies, titles) that must not be scanned for command patterns — a
302
371
  # `--body` mentioning the literal "git push main" is data, not an invocation.
@@ -358,8 +427,15 @@ def guard(payload: dict) -> dict | None:
358
427
 
359
428
  # Strip heredoc bodies and free-text flag values so pattern rules don't fire
360
429
  # on prose content (e.g. `gh issue create --body "$(cat <<'EOF'\n...git
361
- # push...\nEOF\n)"`, or `gh pr comment --body "...git push main..."`).
362
- cmd_scan = _strip_text_flag_values(_strip_heredocs(cmd))
430
+ # push...\nEOF\n)"`, or `gh pr comment --body "...git push main..."`), then
431
+ # normalize interposed git global options so `git -C dir push` is matched
432
+ # like `git push` (2026-07 review).
433
+ cmd_scan = _normalize_git_globals(_strip_text_flag_values(_strip_heredocs(cmd)))
434
+ # A heredoc fed to an interpreter DOES execute its body — scan those too, so
435
+ # `bash <<'EOF' … git push … EOF` is not a bypass (2026-07 review).
436
+ exec_bodies = _executing_heredoc_bodies(cmd)
437
+ if exec_bodies:
438
+ cmd_scan += "\n" + _normalize_git_globals(_strip_text_flag_values(exec_bodies))
363
439
 
364
440
  for pattern, target, message in COMMAND_RULES:
365
441
  if not pattern.search(cmd_scan):
@@ -463,7 +539,7 @@ def cmd_push(branch: str | None, max_retries: int, *, force: bool = False) -> in
463
539
  push_cmd = ["git", "push", "-u", "origin", branch]
464
540
  if force:
465
541
  push_cmd.append("--force-with-lease")
466
- proc = subprocess.run(push_cmd)
542
+ proc = subprocess.run(push_cmd) # noqa: S603 — fixed git argv + validated branch name, never a shell string
467
543
  if proc.returncode == 0:
468
544
  sys.stdout.write(f"push: pushed {branch} ({expected_sha})\n")
469
545
  return 0
@@ -559,7 +635,7 @@ def cmd_finish(pr_number: int | None, review_cycle: int | None) -> int:
559
635
  monitor_args = ["bash", str(script), str(pr_number), "--merge"]
560
636
  if review_cycle is not None:
561
637
  monitor_args += ["--review-cycle", str(review_cycle)]
562
- return subprocess.run(monitor_args).returncode
638
+ return subprocess.run(monitor_args).returncode # noqa: S603 — fixed bash argv + resolved script path, never a shell string
563
639
 
564
640
 
565
641
  _VALID_TYPES = {"feat", "fix", "chore", "docs", "test"}
@@ -620,10 +696,18 @@ def cmd_create_pr_nojira(
620
696
  if rc != 0:
621
697
  return rc
622
698
 
623
- code, url = _gh(["pr", "view", "--json", "url", "-q", ".url"])
624
- if code == 0 and url.strip():
625
- sys.stdout.write(f"Draft PR already exists: {url.strip()}\n")
626
- return 0
699
+ # `gh pr view` with no selector also resolves the most recent CLOSED/MERGED
700
+ # PR for the branch — reusing a branch name after a merge must open a new
701
+ # PR, not report the merged one as "already exists" (matches check_pr_opened).
702
+ code, out = _gh(["pr", "view", "--json", "url,state"])
703
+ if code == 0:
704
+ try:
705
+ data = json.loads(out or "{}")
706
+ except json.JSONDecodeError:
707
+ data = {}
708
+ if data.get("state") == "OPEN" and data.get("url"):
709
+ sys.stdout.write(f"Draft PR already exists: {data['url']}\n")
710
+ return 0
627
711
 
628
712
  # Conventional Commits, no scope = no linked issue (ADR-006)
629
713
  pr_title = f"{type_}: {title}"
@@ -4,9 +4,13 @@
4
4
  # Requires: gh, python3 (stdlib only — no jq dependency).
5
5
  #
6
6
  # Usage:
7
- # .claude/scripts/monitor_pr.sh <pr-number> [--merge] [--review-cycle N] [--no-review]
7
+ # .claude/scripts/monitor_pr.sh <pr-number> [--merge] [--review-cycle N] [--no-review] [--admin]
8
8
  #
9
9
  # --merge: squash-merge and delete branch automatically when all checks pass.
10
+ # --admin: allow an admin override when the PR is BLOCKED by branch protection
11
+ # AFTER the review gate passed (e.g. an unresolved conversation). Without it,
12
+ # a post-review BLOCKED state fails with guidance instead of silently
13
+ # overriding the protection setup_github.sh provisioned (2026-07 review).
10
14
  # --review-cycle N: current review fix cycle count (0-based, default 0).
11
15
  # When N >= MAX_REVIEW_CYCLES and review/decision is still failing or pending,
12
16
  # force-merges with --admin.
@@ -29,33 +33,49 @@
29
33
  set -euo pipefail
30
34
 
31
35
  PR_NUMBER="${1:-}"
32
- MODE="${2:-}"
36
+ MODE=""
33
37
  REVIEW_CYCLE=0
34
38
  MAX_REVIEW_CYCLES=2
35
39
  NO_REVIEW=0
40
+ ALLOW_ADMIN=0
36
41
 
37
42
  if [ -z "$PR_NUMBER" ]; then
38
- echo "Usage: monitor_pr.sh <pr-number> [--merge] [--review-cycle N] [--no-review]" >&2
43
+ echo "Usage: monitor_pr.sh <pr-number> [--merge] [--review-cycle N] [--no-review] [--admin]" >&2
39
44
  exit 1
40
45
  fi
41
46
 
42
- if [ -n "$MODE" ] && [ "$MODE" != "--merge" ]; then
43
- echo "Unknown option: $MODE" >&2
44
- exit 2
45
- fi
46
-
47
- # Parse remaining flags (order-independent after position 2).
48
- # Shift past <pr-number> and optional --merge; remaining args are flags.
47
+ # Parse flags (order-independent). --merge is just another flag: the usage
48
+ # line presents every flag as independent, so `monitor_pr.sh 12 --no-review`
49
+ # must not be rejected for lacking --merge in position 2.
49
50
  shift 1 # drop PR_NUMBER
50
- [ "$MODE" = "--merge" ] && shift 1 # drop --merge if present
51
51
  while [ $# -gt 0 ]; do
52
52
  case "$1" in
53
- --review-cycle) REVIEW_CYCLE="${2:-0}"; shift 2 ;;
53
+ --merge) MODE="--merge"; shift ;;
54
+ --review-cycle)
55
+ # Validate before `shift 2`: with no value, the shift fails under set -e
56
+ # and aborts with no message (Copilot review).
57
+ if [ $# -lt 2 ]; then
58
+ echo "--review-cycle requires a numeric value" >&2
59
+ exit 2
60
+ fi
61
+ REVIEW_CYCLE="$2"; shift 2 ;;
54
62
  --review-cycle=*) REVIEW_CYCLE="${1#*=}"; shift ;;
55
63
  --no-review) NO_REVIEW=1; shift ;;
64
+ --admin) ALLOW_ADMIN=1; shift ;;
56
65
  *) echo "Unknown option: $1" >&2; exit 2 ;;
57
66
  esac
58
67
  done
68
+ case "$REVIEW_CYCLE" in
69
+ '' | *[!0-9]*) echo "--review-cycle must be a non-negative integer (got '$REVIEW_CYCLE')" >&2; exit 2 ;;
70
+ esac
71
+
72
+ # --admin, --no-review and --review-cycle only take effect while merging. Warn
73
+ # loudly if they were passed without --merge so the flag isn't silently a no-op.
74
+ if [ "$MODE" != "--merge" ]; then
75
+ if [ "$ALLOW_ADMIN" -eq 1 ] || [ "$NO_REVIEW" -eq 1 ] || [ "$REVIEW_CYCLE" -ne 0 ]; then
76
+ echo "WARNING: --admin/--no-review/--review-cycle only apply with --merge; ignoring (monitor-only run)." >&2
77
+ fi
78
+ fi
59
79
 
60
80
  _count_pending() {
61
81
  echo "$1" | python3 -c "
@@ -212,6 +232,7 @@ while { [ "$REVIEW_DECISION" = "REVIEW_REQUIRED" ] || [ "$REVIEW_DECISION" = "UN
212
232
  # Bot reviewers like Codex post comments without changing reviewDecision.
213
233
  if [ "$REVIEW_DECISION" = "REVIEW_REQUIRED" ] && _has_review_activity; then
214
234
  echo " Review comments detected — proceeding without waiting for formal approval."
235
+ REVIEW_ACTIVITY=1
215
236
  break
216
237
  fi
217
238
  CHECKS=$(gh pr checks "$PR_NUMBER" --json name,state,bucket 2>/dev/null) || CHECKS="[]"
@@ -241,8 +262,15 @@ if [ "$REVIEW_DECISION" = "CHANGES_REQUESTED" ]; then
241
262
  fi
242
263
 
243
264
  if [ "$REVIEW_DECISION" = "REVIEW_REQUIRED" ]; then
244
- echo "PR #$PR_NUMBER: review/decision still pending after ${REVIEW_TIMEOUT}s no reviewer has acted."
245
- echo " Full PR: $(gh pr view "$PR_NUMBER" --json url -q '.url' 2>/dev/null || true)"
265
+ if [ "${REVIEW_ACTIVITY:-0}" -eq 1 ]; then
266
+ # The wait loop broke early because reviews were posted (e.g. a bot's
267
+ # COMMENTED review) — surface them instead of claiming nobody acted.
268
+ echo "PR #$PR_NUMBER: review comments posted, but no formal approval yet:"
269
+ _print_review_comments
270
+ else
271
+ echo "PR #$PR_NUMBER: review/decision still pending after ${REVIEW_TIMEOUT}s — no reviewer has acted."
272
+ echo " Full PR: $(gh pr view "$PR_NUMBER" --json url -q '.url' 2>/dev/null || true)"
273
+ fi
246
274
 
247
275
  if [ "$MODE" = "--merge" ]; then
248
276
  if [ "$REVIEW_CYCLE" -ge "$MAX_REVIEW_CYCLES" ]; then
@@ -272,8 +300,21 @@ if [ "$MODE" = "--merge" ]; then
272
300
  exit 1
273
301
  fi
274
302
  elif [ "$MERGE_STATE" = "BLOCKED" ]; then
275
- echo "PR is blocked by review protection merging with admin override."
276
- _admin_merge
303
+ # The review gate already passed to reach here, so BLOCKED means a DIFFERENT
304
+ # branch-protection rule is unmet — most often an unresolved review thread.
305
+ # Auto-admin-merging past it on cycle 0 silently defeats the protection this
306
+ # very tool set up, so it requires an explicit --admin opt-in (2026-07
307
+ # review; backported from the template copy).
308
+ if [ "$ALLOW_ADMIN" -eq 1 ]; then
309
+ echo "PR is blocked by branch protection — merging with admin override (--admin)."
310
+ _admin_merge
311
+ else
312
+ echo "ERROR: PR #$PR_NUMBER is BLOCKED by branch protection after the review gate" >&2
313
+ echo " passed — typically an unresolved review conversation, or a required" >&2
314
+ echo " check that has not reported. Resolve the blocker, or re-run with --admin" >&2
315
+ echo " to override." >&2
316
+ exit 1
317
+ fi
277
318
  else
278
319
  if ! _run_gh pr merge "$PR_NUMBER" --squash --delete-branch; then
279
320
  if ! _run_gh pr merge "$PR_NUMBER" --squash --delete-branch --auto; then
@@ -41,8 +41,13 @@ git clone "https://github.com/${REPO_SLUG}.wiki.git" "$WIKI_DIR"
41
41
  cp "$SOURCE_FILE" "$WIKI_DIR/Home.md"
42
42
 
43
43
  cd "$WIKI_DIR"
44
- for page in "${PRUNE_PAGES[@]}"; do
45
- [[ -f "$page" ]] && git rm -q "$page" && echo "Pruned $page"
44
+ # ${arr[@]+...} guard: expanding an empty array under `set -u` is a fatal
45
+ # "unbound variable" on bash 3.2-4.3 (stock macOS), aborting before the commit.
46
+ for page in ${PRUNE_PAGES[@]+"${PRUNE_PAGES[@]}"}; do
47
+ if [[ -f "$page" ]]; then
48
+ git rm -q "$page"
49
+ echo "Pruned $page"
50
+ fi
46
51
  done
47
52
  git add Home.md
48
53
  if git diff --cached --quiet; then
@@ -8,7 +8,7 @@
8
8
  {
9
9
  "type": "command",
10
10
  "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/github_command_guard.sh",
11
- "timeout": 10
11
+ "timeout": 60
12
12
  }
13
13
  ]
14
14
  }
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env bash
2
+ # pre-push gate for the project-init repo itself (dogfood).
3
+ #
4
+ # Runs the SAME `just ci` (lint + tests) that CI runs, before the push leaves
5
+ # the machine — so nothing red reaches a PR and the push→CI-fail→fix→re-push
6
+ # loop is caught locally. This is the local↔CI parity gate whose absence let a
7
+ # fresh-scaffold lint failure ship (the scaffolder's CI caught it only after a
8
+ # push, and even then incompletely).
9
+ #
10
+ # Enabled automatically by `just setup` (git config core.hooksPath .githooks).
11
+ # Bypass in an emergency with: git push --no-verify
12
+ set -euo pipefail
13
+
14
+ if command -v just >/dev/null 2>&1; then
15
+ # `just ci` tests the working tree, but the push ships the committed tree.
16
+ # Skip (fail-open) on a dirty worktree rather than test a tree that isn't what
17
+ # gets pushed — a WIP fix could mask a failure, or unrelated WIP fail a clean
18
+ # push. CI stays the backstop.
19
+ if [ -n "$(git status --porcelain 2>/dev/null)" ]; then
20
+ echo "pre-push: working tree is dirty — skipping the 'just ci' gate" >&2
21
+ echo " (it would test the worktree, not the commit being pushed)." >&2
22
+ echo " Commit or stash your changes to run the gate before pushing." >&2
23
+ else
24
+ echo "pre-push: running 'just ci' (lint + tests)…"
25
+ if ! just ci; then
26
+ echo ""
27
+ echo "❌ pre-push: 'just ci' failed — fix the errors above before pushing."
28
+ echo " (bypass in an emergency with: git push --no-verify)"
29
+ exit 1
30
+ fi
31
+ fi
32
+ else
33
+ echo "pre-push: 'just' not found — skipping local CI gate (CI still runs)." >&2
34
+ fi
@@ -14,35 +14,59 @@ jobs:
14
14
  name: Lint and test
15
15
  runs-on: ubuntu-24.04
16
16
  steps:
17
- - uses: actions/checkout@v6
17
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
18
18
 
19
19
  - name: Install uv
20
- uses: astral-sh/setup-uv@v8.1.0
20
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
21
21
  with:
22
22
  version: "0.11.7"
23
23
  enable-cache: true
24
24
  cache-dependency-glob: "uv.lock"
25
25
  python-version: "3.12"
26
26
 
27
+ # shellcheck ships preinstalled on ubuntu-24.04; shfmt does not. The
28
+ # scaffolded-output lint guard (test_shell_lint_gate.py) skips when its
29
+ # tool is absent, so without this step the shfmt guard would silently
30
+ # no-op in CI — a green check that tested nothing. Pinned + checksum-
31
+ # verified, mirroring the install the scaffolded ci.yml.tmpl ships.
32
+ - name: Install shfmt
33
+ run: |
34
+ mkdir -p "$HOME/.local/bin"
35
+ tmp="$(mktemp -d)"
36
+ curl -sSfL https://github.com/mvdan/sh/releases/download/v3.8.0/shfmt_v3.8.0_linux_amd64 -o "$tmp/shfmt_v3.8.0_linux_amd64"
37
+ curl -sSfL https://github.com/mvdan/sh/releases/download/v3.8.0/sha256sums.txt -o "$tmp/sha256sums.txt"
38
+ ( cd "$tmp" && grep 'shfmt_v3.8.0_linux_amd64$' sha256sums.txt | sha256sum -c - )
39
+ chmod +x "$tmp/shfmt_v3.8.0_linux_amd64"
40
+ mv "$tmp/shfmt_v3.8.0_linux_amd64" "$HOME/.local/bin/shfmt"
41
+ echo "$HOME/.local/bin" >> "$GITHUB_PATH"
42
+
27
43
  - name: Sync dev dependencies
28
- run: uv sync --extra dev --locked
44
+ run: uv sync --group dev --locked
29
45
 
30
46
  - name: Lint (ruff)
31
47
  run: uv run ruff check .
32
48
 
33
49
  - name: Tests (pytest) — parallel mode
34
- # Falls back to single-threaded if xdist not available
35
- run: uv run pytest -n auto --tb=short -q 2>/dev/null || uv run pytest --tb=short -q
50
+ # Use xdist when importable, else single-threaded decided by an
51
+ # explicit capability check, not `|| retry`, so a genuinely failing
52
+ # suite is not run twice with its first-pass stderr hidden (2026-07
53
+ # review).
54
+ run: |
55
+ if uv run python -c "import xdist" 2>/dev/null; then
56
+ uv run pytest -n auto --tb=short -q
57
+ else
58
+ uv run pytest --tb=short -q
59
+ fi
36
60
 
37
61
  wheel-smoke:
38
62
  name: Wheel smoke test
39
63
  runs-on: ubuntu-24.04
40
64
  needs: lint-and-test
41
65
  steps:
42
- - uses: actions/checkout@v6
66
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
43
67
 
44
68
  - name: Install uv
45
- uses: astral-sh/setup-uv@v8.1.0
69
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
46
70
  with:
47
71
  version: "0.11.7"
48
72
  enable-cache: true
@@ -89,12 +113,12 @@ jobs:
89
113
  name: Secret scan (gitleaks)
90
114
  runs-on: ubuntu-24.04
91
115
  steps:
92
- - uses: actions/checkout@v6
116
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
93
117
  with:
94
118
  # Full history so leaked commits are caught, not just the latest diff
95
119
  fetch-depth: 0
96
120
 
97
- - uses: gitleaks/gitleaks-action@v3
121
+ - uses: gitleaks/gitleaks-action@e0c47f4f8be36e29cdc102c57e68cb5cbf0e8d1e # v3
98
122
  env:
99
123
  GITHUB_TOKEN: ${{ github.token }}
100
124
 
@@ -104,10 +128,10 @@ jobs:
104
128
  name: ShellCheck (scaffolded scripts)
105
129
  runs-on: ubuntu-24.04
106
130
  steps:
107
- - uses: actions/checkout@v6
131
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
108
132
 
109
133
  - name: Install uv
110
- uses: astral-sh/setup-uv@v8.1.0
134
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
111
135
  with:
112
136
  version: "0.11.7"
113
137
  enable-cache: true
@@ -146,8 +170,8 @@ jobs:
146
170
  outputs:
147
171
  shell: ${{ steps.filter.outputs.shell }}
148
172
  steps:
149
- - uses: actions/checkout@v6
150
- - uses: dorny/paths-filter@v3
173
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
174
+ - uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3
151
175
  id: filter
152
176
  with:
153
177
  filters: |
@@ -170,10 +194,10 @@ jobs:
170
194
  if: needs.changes.outputs.shell == 'true'
171
195
  runs-on: macos-latest
172
196
  steps:
173
- - uses: actions/checkout@v6
197
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
174
198
 
175
199
  - name: Install uv
176
- uses: astral-sh/setup-uv@v8.1.0
200
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
177
201
  with:
178
202
  version: "0.11.7"
179
203
  python-version: "3.12"
@@ -228,10 +252,10 @@ jobs:
228
252
  run:
229
253
  shell: bash # GitHub's "bash" on Windows is Git Bash — the supported path
230
254
  steps:
231
- - uses: actions/checkout@v6
255
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
232
256
 
233
257
  - name: Install uv
234
- uses: astral-sh/setup-uv@v8.1.0
258
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
235
259
  with:
236
260
  version: "0.11.7"
237
261
  python-version: "3.12"
@@ -35,10 +35,10 @@ jobs:
35
35
  name: Build site
36
36
  runs-on: ubuntu-24.04
37
37
  steps:
38
- - uses: actions/checkout@v6
38
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
39
39
 
40
40
  - name: Install uv
41
- uses: astral-sh/setup-uv@v8.1.0
41
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
42
42
  with:
43
43
  version: "0.11.7"
44
44
  enable-cache: true
@@ -54,7 +54,7 @@ jobs:
54
54
  run: uv run mkdocs build --strict
55
55
 
56
56
  - name: Upload Pages artifact
57
- uses: actions/upload-pages-artifact@v3
57
+ uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
58
58
  with:
59
59
  path: site
60
60
 
@@ -72,4 +72,4 @@ jobs:
72
72
  steps:
73
73
  - name: Deploy to GitHub Pages
74
74
  id: deployment
75
- uses: actions/deploy-pages@v4
75
+ uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4
@@ -5,11 +5,21 @@
5
5
  # Cutting a release:
6
6
  # 1. Bump version in pyproject.toml AND src/project_init/__init__.py
7
7
  # 2. git tag vX.Y.Z && push the tag
8
+ # — or, where a tag can't be pushed directly, run the "Tag Release"
9
+ # workflow (tag-release.yml): it verifies + creates the tag and then
10
+ # dispatches THIS workflow on the new tag ref.
8
11
  name: Release
9
12
 
10
13
  on:
11
14
  push:
12
15
  tags: ["v*"]
16
+ # Dispatchable on an EXISTING v* tag ref (tag-release.yml does this after
17
+ # creating the tag — a GITHUB_TOKEN tag push never triggers the tag-push
18
+ # path above, by GitHub's recursive-workflow rule). Every step below reads
19
+ # the tag from the run ref, so a dispatch on a non-tag ref fails the
20
+ # version guard cleanly. Keeping the run ON the tag ref also satisfies the
21
+ # pypi environment's v*-tags-only deployment rule (ADR-011).
22
+ workflow_dispatch: {}
13
23
 
14
24
  permissions:
15
25
  contents: write
@@ -18,13 +28,13 @@ jobs:
18
28
  release:
19
29
  runs-on: ubuntu-24.04
20
30
  steps:
21
- - uses: actions/checkout@v6
31
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
22
32
  with:
23
33
  # Full history — git-cliff needs prior tags to scope --latest.
24
34
  fetch-depth: 0
25
35
 
26
36
  - name: Install uv
27
- uses: astral-sh/setup-uv@v8.1.0
37
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
28
38
  with:
29
39
  version: "0.11.7"
30
40
 
@@ -40,7 +50,7 @@ jobs:
40
50
  run: uv build
41
51
 
42
52
  - name: Generate changelog (latest tag)
43
- uses: orhun/git-cliff-action@v4
53
+ uses: orhun/git-cliff-action@f50e11560dce63f7c33227798f90b924471a88b5 # v4
44
54
  with:
45
55
  config: cliff.toml
46
56
  args: --latest
@@ -48,7 +58,7 @@ jobs:
48
58
  OUTPUT: RELEASE_NOTES.md
49
59
 
50
60
  - name: Create GitHub Release
51
- uses: softprops/action-gh-release@v3
61
+ uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3
52
62
  with:
53
63
  # Only the build artifacts — an unscoped glob also picks up the
54
64
  # tracked dist/.gitignore and uploads it as a stray
@@ -72,10 +82,10 @@ jobs:
72
82
  contents: read
73
83
  id-token: write
74
84
  steps:
75
- - uses: actions/checkout@v6
85
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
76
86
 
77
87
  - name: Install uv
78
- uses: astral-sh/setup-uv@v8.1.0
88
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
79
89
  with:
80
90
  version: "0.11.7"
81
91
 
@@ -83,4 +93,4 @@ jobs:
83
93
  run: uv build
84
94
 
85
95
  - name: Publish to PyPI
86
- uses: pypa/gh-action-pypi-publish@release/v1
96
+ uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # release/v1
@@ -31,6 +31,10 @@ jobs:
31
31
  PR_NUMBER: ${{ github.event.pull_request.number }}
32
32
  SHA: ${{ github.event.pull_request.head.sha }}
33
33
  REPO: ${{ github.repository }}
34
+ # Route the event value through env, not inline ${{ }} in the script —
35
+ # keeps the whole workflow to one untrusted-input discipline (2026-07
36
+ # review). GitHub-generated URL, so risk is low; consistency matters.
37
+ REVIEW_URL: ${{ github.event.review.html_url }}
34
38
  run: |
35
39
  DECISION=$(gh pr view "$PR_NUMBER" --repo "$REPO" --json reviewDecision -q '.reviewDecision // ""')
36
40
  case "$DECISION" in
@@ -45,4 +49,4 @@ jobs:
45
49
  --field state="$STATE" \
46
50
  --field description="$DESCRIPTION" \
47
51
  --field context="review/decision" \
48
- --field target_url="${{ github.event.review.html_url }}"
52
+ --field target_url="$REVIEW_URL"