claude-dev-env 2.4.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +26 -59
- package/_shared/pr-loop/scripts/_claude_permissions_common.py +84 -0
- package/_shared/pr-loop/scripts/code_rules_gate.py +6 -3
- package/_shared/pr-loop/scripts/code_rules_gate_parts/CLAUDE.md +12 -2
- package/_shared/pr-loop/scripts/code_rules_gate_parts/baseline_import_isolation.py +309 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/staged_test_regression.py +540 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/staged_test_running.py +206 -70
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/__init__.py +1 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/_repo_test_helpers.py +76 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_baseline_import_isolation.py +248 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_staged_test_regression.py +309 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_staged_test_running.py +91 -58
- package/_shared/pr-loop/scripts/grant_project_claude_permissions.py +306 -306
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/claude_permissions_constants.py +44 -0
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/code_rules_gate_constants.py +202 -0
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/copilot_quota_constants.py +24 -24
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/stale_worktree_rule_sweep_constants.py +107 -107
- package/_shared/pr-loop/scripts/revoke_project_claude_permissions.py +290 -48
- package/_shared/pr-loop/scripts/tests/test_claude_permissions_common.py +42 -2
- package/_shared/pr-loop/scripts/tests/test_claude_permissions_constants.py +36 -0
- package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +100 -1
- package/_shared/pr-loop/scripts/tests/test_fix_hookspath.py +497 -497
- package/_shared/pr-loop/scripts/tests/test_revoke_project_claude_permissions.py +311 -2
- package/_shared/pr-loop/scripts/tests/test_stale_worktree_rule_sweep.py +301 -301
- package/_shared/pr-loop/scripts/tests/test_stale_worktree_rule_sweep_constants.py +85 -85
- package/_shared/pr-loop/worker-spawn.md +1 -1
- package/agents/CLAUDE.md +3 -2
- package/agents/caveman.md +0 -1
- package/agents/clasp-deployment-orchestrator.md +0 -1
- package/agents/clean-coder.md +0 -1
- package/agents/code-advisor.md +0 -1
- package/agents/code-quality-agent.md +1 -2
- package/agents/code-verifier.md +36 -8
- package/agents/deep-research.md +0 -1
- package/agents/docs-agent.md +0 -1
- package/agents/git-commit-crafter.md +0 -1
- package/agents/issue-tracker.md +42 -0
- package/agents/plan-packet-validator.md +0 -1
- package/agents/pr-description-writer.md +0 -1
- package/agents/test_agent_frontmatter.py +67 -18
- package/audit-rubrics/category_rubrics/category-o-docstring-vs-impl-drift.md +143 -141
- package/bin/CLAUDE.md +68 -5
- package/bin/codex-compat.mjs +104 -0
- package/bin/codex-compat.test.mjs +51 -0
- package/bin/ever-shipped-skills.mjs +1 -0
- package/bin/install-constants.mjs +88 -0
- package/bin/install.mjs +1138 -114
- package/bin/install.prune.test.mjs +869 -19
- package/bin/install.test.mjs +906 -2
- package/codex-capability-map.json +13 -0
- package/commands/implement.md +1 -1
- package/commands/right-size.md +1 -1
- package/docs/CLAUDE.md +1 -0
- package/docs/CODE_RULES.md +2 -0
- package/docs/codex-compatibility.md +25 -0
- package/docs/host-pool-health-monitor.md +102 -0
- package/docs/nas-ssh-invocation.md +96 -12
- package/docs/references/CLAUDE.md +4 -2
- package/docs/references/advisor-tool.md +13 -0
- package/docs/references/code-review-enforcement.md +35 -0
- package/docs/references/team-advisor-skill.md +14 -0
- package/hooks/blocking/CLAUDE.md +4 -0
- package/hooks/blocking/code_review_pr_create_gate.py +7 -3
- package/hooks/blocking/code_review_push_gate.py +9 -4
- package/hooks/blocking/code_review_stamp_directory_write_blocker.py +8 -0
- package/hooks/blocking/config/__init__.py +5 -5
- package/hooks/blocking/config/code_review_enforcement_constants.py +40 -7
- package/hooks/blocking/config/test_code_review_enforcement_constants.py +58 -0
- package/hooks/blocking/config/verified_commit_constants.py +160 -159
- package/hooks/blocking/eli11_reply_enforcer.py +479 -0
- package/hooks/blocking/gh_body_arg_blocker.py +1 -1
- package/hooks/blocking/nas_ssh_binary_enforcer.py +8 -46
- package/hooks/blocking/orchestrator_refresh_reschedule_gate.py +256 -0
- package/hooks/blocking/pre_tool_use_dispatcher.py +24 -24
- package/hooks/blocking/shell_substitution_blocker.py +129 -0
- package/hooks/blocking/state_description_blocker.py +1 -1
- package/hooks/blocking/stop_dispatcher.py +1 -1
- package/hooks/blocking/test_bash_pre_tool_use_dispatcher.py +2 -3
- package/hooks/blocking/test_code_review_pr_create_gate.py +14 -0
- package/hooks/blocking/test_code_review_push_gate.py +16 -0
- package/hooks/blocking/test_code_review_stamp_directory_write_blocker.py +19 -0
- package/hooks/blocking/test_eli11_reply_enforcer.py +457 -0
- package/hooks/blocking/test_orchestrator_refresh_reschedule_gate.py +231 -0
- package/hooks/blocking/test_pre_tool_use_dispatcher.py +10 -1
- package/hooks/blocking/test_shell_substitution_blocker.py +124 -0
- package/hooks/blocking/test_stop_dispatcher.py +23 -0
- package/hooks/blocking/test_unscoped_search_blocker.py +102 -0
- package/hooks/blocking/test_verdict_directory_write_blocker.py +804 -808
- package/hooks/blocking/test_verification_verdict_store.py +54 -0
- package/hooks/blocking/test_verified_commit_gate.py +581 -581
- package/hooks/blocking/test_verified_commit_message_accuracy_blocker.py +131 -131
- package/hooks/blocking/unscoped_search_blocker.py +391 -0
- package/hooks/blocking/verdict_directory_write_blocker.py +687 -687
- package/hooks/blocking/verification_verdict_store.py +1039 -1036
- package/hooks/blocking/verified_commit_message_accuracy_blocker.py +167 -167
- package/hooks/blocking/verifier_verdict_minter.py +280 -280
- package/hooks/git-hooks/CLAUDE.md +3 -0
- package/hooks/git-hooks/conftest.py +30 -0
- package/hooks/git-hooks/gate_utils.py +2 -2
- package/hooks/git-hooks/git_hooks_constants/__init__.py +41 -2
- package/hooks/git-hooks/pre_push.py +75 -4
- package/hooks/git-hooks/pre_push_base_reference.py +166 -0
- package/hooks/git-hooks/test_config.py +0 -15
- package/hooks/git-hooks/test_gate_utils.py +3 -15
- package/hooks/git-hooks/test_pre_commit.py +1 -15
- package/hooks/git-hooks/test_pre_push.py +257 -23
- package/hooks/git-hooks/test_pre_push_base_reference.py +339 -0
- package/hooks/hooks.json +10 -12
- package/hooks/hooks_constants/CLAUDE.md +7 -2
- package/hooks/hooks_constants/bash_pre_tool_use_dispatcher_constants.py +4 -4
- package/hooks/hooks_constants/eli11_reply_enforcer_constants.py +101 -0
- package/hooks/hooks_constants/enter_worktree_prefetch_constants.py +18 -18
- package/hooks/hooks_constants/nas_ssh_binary_enforcer_constants.py +2 -8
- package/hooks/hooks_constants/orchestrator_refresh_reschedule_gate_constants.py +48 -0
- package/hooks/hooks_constants/ruff_integration_constants.py +16 -0
- package/hooks/hooks_constants/shell_command_segments.py +82 -0
- package/hooks/hooks_constants/shell_substitution_blocker_constants.py +67 -0
- package/hooks/hooks_constants/stop_dispatcher_constants.py +1 -0
- package/hooks/hooks_constants/test_bash_pre_tool_use_dispatcher_constants.py +5 -6
- package/hooks/hooks_constants/test_stop_dispatcher_constants.py +1 -0
- package/hooks/hooks_constants/unscoped_search_blocker_constants.py +153 -0
- package/hooks/lifecycle/enter_worktree_origin_prefetch.py +163 -146
- package/hooks/lifecycle/test_enter_worktree_origin_prefetch.py +185 -178
- package/hooks/pyproject.toml +1 -0
- package/hooks/validators/CLAUDE.md +1 -0
- package/hooks/validators/config/__init__.py +0 -0
- package/hooks/validators/config/directory_exemption_constants.py +183 -0
- package/hooks/validators/config/test_directory_exemption_constants.py +21 -0
- package/hooks/validators/conftest.py +4 -0
- package/hooks/validators/ruff_integration.py +49 -5
- package/hooks/validators/run_all_validators.py +206 -9
- package/hooks/validators/test_directory_exemption_constants.py +185 -0
- package/hooks/validators/test_python_antipattern_checks.py +110 -5
- package/hooks/validators/test_ruff_integration.py +92 -1
- package/hooks/validators/test_run_all_validators.py +115 -68
- package/hooks/validators/test_run_all_validators_pretooluse.py +159 -1
- package/package.json +13 -3
- package/rules/CLAUDE.md +17 -22
- package/rules/agent-spawn-protocol.md +6 -6
- package/rules/anti-corollary-tests.md +1 -1
- package/rules/bdd.md +1 -1
- package/rules/cleanup-temp-files.md +10 -4
- package/rules/code-standards.md +7 -0
- package/rules/conservative-action.md +1 -5
- package/rules/context7.md +0 -4
- package/rules/destructive-commands.md +47 -0
- package/rules/doc-inventory-integrity.md +48 -0
- package/rules/doc-prose-cuts.md +58 -0
- package/rules/docstring-prose-matches-implementation.md +53 -44
- package/rules/durable-post-artifacts.md +0 -4
- package/rules/eli11-replies.md +31 -0
- package/rules/explore-thoroughly.md +4 -4
- package/rules/falsify-before-green.md +68 -0
- package/rules/file-global-constants.md +1 -1
- package/rules/filesystem-search.md +51 -0
- package/rules/gh-cli-conventions.md +27 -0
- package/rules/git-workflow.md +26 -0
- package/rules/hedging-claims.md +9 -0
- package/rules/long-horizon-autonomy.md +0 -4
- package/rules/measurement-denominators.md +48 -0
- package/rules/nas-ssh-invocation.md +23 -5
- package/rules/parallel-tools.md +2 -2
- package/rules/plain-illustrative-docstrings.md +3 -7
- package/rules/plain-language.md +2 -0
- package/rules/proof-of-work-pr-comments.md +0 -4
- package/rules/re-stage-before-commit.md +2 -0
- package/rules/research-mode.md +10 -0
- package/rules/shell-invocation.md +21 -0
- package/rules/testing.md +4 -0
- package/rules/verified-commit-gate-skip.md +3 -27
- package/rules/verify-before-asking.md +5 -0
- package/rules/windows-filesystem-safe.md +1 -1
- package/rules/workers-done-before-complete.md +4 -0
- package/scripts/CLAUDE.md +1 -0
- package/scripts/Capture-PoolHealth.ps1 +410 -0
- package/scripts/Migrate-ShellPolicy.ps1 +1 -1
- package/scripts/_code_review_test_support.py +404 -0
- package/scripts/claude_chain_runner.py +141 -1
- package/scripts/codex_capability_bridge.py +171 -0
- package/scripts/codex_compat_materializer.py +1087 -0
- package/scripts/codex_compat_watcher.py +502 -0
- package/scripts/conftest.py +16 -1
- package/scripts/dev_env_scripts_constants/CLAUDE.md +1 -1
- package/scripts/dev_env_scripts_constants/claude_chain_constants.py +9 -0
- package/scripts/dev_env_scripts_constants/code_review_constants.py +37 -0
- package/scripts/invoke_code_review.py +11 -4
- package/scripts/resolve_worker_spawn.py +626 -626
- package/scripts/spawn_grok_batch.py +672 -672
- package/scripts/sync_to_cursor/rules.py +0 -10
- package/scripts/test_claude_chain_runner.py +131 -0
- package/scripts/test_invoke_code_review.py +85 -908
- package/scripts/test_invoke_code_review_chain.py +70 -0
- package/scripts/test_invoke_code_review_cli.py +192 -0
- package/scripts/test_invoke_code_review_contract.py +256 -0
- package/scripts/test_invoke_code_review_git.py +123 -0
- package/scripts/test_invoke_code_review_mode.py +99 -0
- package/scripts/test_resolve_worker_spawn.py +1014 -1014
- package/scripts/tests/test_code_review_constants.py +80 -0
- package/scripts/tests/test_codex_capability_bridge.py +91 -0
- package/scripts/tests/test_codex_compat_materializer.py +632 -0
- package/scripts/tests/test_codex_compat_watcher.py +599 -0
- package/scripts/tests/test_sync_to_cursor.py +0 -1
- package/skills/CLAUDE.md +2 -0
- package/skills/auditing-claude-config/SKILL.md +114 -114
- package/skills/autoconverge/SKILL.md +427 -427
- package/skills/autoconverge/reference/convergence.md +24 -3
- package/skills/autoconverge/workflow/CLAUDE.md +1 -0
- package/skills/autoconverge/workflow/converge.clean-audit.test.mjs +3 -3
- package/skills/autoconverge/workflow/converge.contract.test.mjs +1263 -1263
- package/skills/autoconverge/workflow/converge.mjs +168 -1
- package/skills/autoconverge/workflow/converge.p2-advance.test.mjs +202 -0
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a11d903476b803493.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a26213978adeef6fb.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a3def0d15ed9d9110.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a41f41b1b708ee3b7.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a758b880abecc3ff7.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a8897b89656b1bd16.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-abd463d744a1437bc.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ad19d027ae8ee1816.jsonl +2 -2
- package/skills/autoconverge/workflow/fixtures/wf_run/workflows/wf_881252e6-700.json +265 -265
- package/skills/bugteam/reference/copilot-gap-analysis.md +1 -1
- package/skills/closeout/SKILL.md +33 -50
- package/skills/codex-review/scripts/codex_review_scripts_constants/run_constants.py +8 -0
- package/skills/codex-review/scripts/run_codex_review.py +233 -1
- package/skills/codex-review/scripts/test_run_codex_review.py +189 -0
- package/skills/condensing-instructions/SKILL.md +72 -0
- package/skills/copilot-review/SKILL.md +119 -119
- package/skills/e-code-review/SKILL.md +52 -0
- package/skills/e-code-review/reference/fix.md +54 -0
- package/skills/e-code-review/reference/loop.md +43 -0
- package/skills/e-code-review/reference/low.md +57 -0
- package/skills/e-code-review/reference/medium.md +153 -0
- package/skills/e-code-review/reference/xhigh.md +182 -0
- package/skills/e-simplify/SKILL.md +97 -0
- package/skills/fresh-branch/CLAUDE.md +1 -1
- package/skills/fresh-branch/SKILL.md +5 -6
- package/skills/fresh-branch/scripts/create_fresh_branch.py +42 -24
- package/skills/fresh-branch/scripts/fresh_branch_scripts_constants/fresh_branch_cli_constants.py +1 -3
- package/skills/fresh-branch/scripts/test_create_fresh_branch.py +30 -126
- package/skills/issue-tracker/SKILL.md +92 -0
- package/skills/issue-tracker/reference/epic-and-sub-issue-model.md +55 -0
- package/skills/issue-tracker/reference/handoff-schema.md +64 -0
- package/skills/issue-tracker/reference/operation-matrix.md +41 -0
- package/skills/orchestrator/SKILL.md +177 -22
- package/skills/orchestrator/scripts/status_gate.py +625 -0
- package/skills/orchestrator/scripts/status_gate_constants/__init__.py +1 -0
- package/skills/orchestrator/scripts/status_gate_constants/config/__init__.py +1 -0
- package/skills/orchestrator/scripts/status_gate_constants/config/constants.py +47 -0
- package/skills/orchestrator/scripts/test_status_gate.py +439 -0
- package/skills/orchestrator-refresh/SKILL.md +129 -35
- package/skills/plan-to-pr/SKILL.md +155 -0
- package/skills/plan-to-pr/reference/final-validation-tasks.md +15 -0
- package/skills/plan-to-pr/reference/model-routing.md +36 -0
- package/skills/plan-to-pr/reference/packet-contract.md +43 -0
- package/skills/plan-to-pr/reference/packet-schema.json +57 -0
- package/skills/plan-to-pr/reference/process-inventory.md +22 -0
- package/skills/plan-to-pr/reference/review-loop.md +33 -0
- package/skills/plan-to-pr/reference/run-record.schema.json +27 -0
- package/skills/plan-to-pr/reference/self-audit-tasks.md +15 -0
- package/skills/plan-to-pr/reference/task-seeds.md +14 -0
- package/skills/plan-to-pr/reference/task-ticket.md +38 -0
- package/skills/plan-to-pr/scripts/config/__init__.py +1 -0
- package/skills/plan-to-pr/scripts/config/constants.py +193 -0
- package/skills/plan-to-pr/scripts/create_packet.py +173 -0
- package/skills/plan-to-pr/scripts/test_create_packet.py +102 -0
- package/skills/plan-to-pr/scripts/test_validate_packet.py +256 -0
- package/skills/plan-to-pr/scripts/test_validate_protocol.py +135 -0
- package/skills/plan-to-pr/scripts/test_validate_run.py +158 -0
- package/skills/plan-to-pr/scripts/validate_packet.py +655 -0
- package/skills/plan-to-pr/scripts/validate_protocol.py +622 -0
- package/skills/plan-to-pr/scripts/validate_run.py +173 -0
- package/skills/plan-to-pr/test_skill_contract.py +207 -0
- package/skills/plan-to-pr/test_task_ticket_contract.py +151 -0
- package/skills/pr-converge/SKILL.md +472 -469
- package/skills/pr-converge/reference/examples.md +3 -3
- package/skills/pr-converge/reference/fix-protocol.md +1 -1
- package/skills/pr-converge/reference/ground-rules.md +7 -4
- package/skills/pr-converge/reference/multi-pr-orchestration.md +4 -1
- package/skills/pr-converge/reference/per-tick.md +5 -5
- package/skills/pr-converge/reference/progress-checklist.md +1 -1
- package/skills/pr-converge/scripts/check_convergence_gates.py +279 -279
- package/skills/pr-converge/scripts/test_check_convergence_codex.py +507 -507
- package/skills/pr-converge/scripts/test_check_convergence_gates.py +84 -84
- package/skills/pr-converge/test_step5_host_branch.py +1 -1
- package/skills/pr-fix-protocol/SKILL.md +1 -1
- package/skills/privacy-hygiene/SKILL.md +68 -68
- package/skills/privacy-hygiene/reference/sweep-procedure.md +1 -1
- package/skills/prototype/workflows/promotion.md +1 -1
- package/skills/release-notes-html/SKILL.md +164 -0
- package/skills/session-log/SKILL.md +1 -1
- package/skills/task-build/CLAUDE.md +8 -7
- package/skills/task-build/SKILL.md +16 -8
- package/skills/task-build/reference/tool-routing.md +19 -0
- package/rules/claude-md-orphan-file.md +0 -28
- package/rules/cleanup-command-forms.md +0 -23
- package/rules/code-reviews.md +0 -11
- package/rules/env-var-table-code-drift.md +0 -10
- package/rules/gh-body-file.md +0 -5
- package/rules/gh-paginate.md +0 -3
- package/rules/hook-prose-matches-detector.md +0 -15
- package/rules/no-historical-clutter.md +0 -26
- package/rules/no-inline-destructive-literals.md +0 -9
- package/rules/no-justification-noise.md +0 -61
- package/rules/package-inventory-stale-entry.md +0 -25
- package/rules/right-sized-engineering.md +0 -28
- package/rules/self-contained-docs.md +0 -17
- package/rules/shell-invocation-policy.md +0 -5
- package/rules/tdd.md +0 -7
- package/skills/closeout/reference/issue-body-templates.md +0 -108
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
"""Behavioral tests for the review and Bugbot convergence gate leaves.
|
|
2
|
-
|
|
3
|
-
::
|
|
4
|
-
|
|
5
|
-
_flatten_paginated_reviews(two pages) -> newest-first flat list
|
|
6
|
-
_bugbot_run_conclusion_detail(success) -> (True, "check run ...")
|
|
7
|
-
_check_bugbot(named complete run) -> (True, "check run ...")
|
|
8
|
-
|
|
9
|
-
Each test drives the real leaf, stubbing only the ``gh`` transport helpers.
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
from __future__ import annotations
|
|
13
|
-
|
|
14
|
-
import json
|
|
15
|
-
|
|
16
|
-
import pytest
|
|
17
|
-
|
|
18
|
-
import check_convergence_gates as gates
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def test_flatten_paginated_reviews_flattens_and_sorts_newest_first() -> None:
|
|
22
|
-
pages = [
|
|
23
|
-
[{"id": 1, "submitted_at": "2026-01-01T00:00:00Z"}],
|
|
24
|
-
[{"id": 2, "submitted_at": "2026-03-01T00:00:00Z"}],
|
|
25
|
-
]
|
|
26
|
-
flattened = gates._flatten_paginated_reviews(json.dumps(pages))
|
|
27
|
-
assert flattened is not None
|
|
28
|
-
assert [each_review["id"] for each_review in flattened] == [2, 1]
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def test_flatten_paginated_reviews_returns_none_for_non_list_payload() -> None:
|
|
32
|
-
assert (
|
|
33
|
-
gates._flatten_paginated_reviews(json.dumps({"message": "Not Found"})) is None
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def test_bugbot_run_conclusion_detail_passes_on_a_complete_conclusion() -> None:
|
|
38
|
-
complete_conclusion = gates.ALL_BUGBOT_CHECK_RUN_COMPLETE_CONCLUSIONS[0]
|
|
39
|
-
passed, detail = gates._bugbot_run_conclusion_detail(
|
|
40
|
-
{"id": 55, "conclusion": complete_conclusion, "html_url": ""}
|
|
41
|
-
)
|
|
42
|
-
assert passed is True
|
|
43
|
-
assert "check run 55" in detail
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def test_check_bugbot_reports_success_when_the_named_run_is_complete(
|
|
47
|
-
monkeypatch: pytest.MonkeyPatch,
|
|
48
|
-
) -> None:
|
|
49
|
-
complete_conclusion = gates.ALL_BUGBOT_CHECK_RUN_COMPLETE_CONCLUSIONS[0]
|
|
50
|
-
run_name = f"x {gates.BUGBOT_CHECK_RUN_NAME_SUBSTRING} y"
|
|
51
|
-
payload = {
|
|
52
|
-
"check_runs": [
|
|
53
|
-
{
|
|
54
|
-
"name": run_name,
|
|
55
|
-
"id": 9,
|
|
56
|
-
"conclusion": complete_conclusion,
|
|
57
|
-
"html_url": "",
|
|
58
|
-
}
|
|
59
|
-
]
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
def _stub_gh_api(endpoint_path: str) -> tuple[int, str]:
|
|
63
|
-
return 0, json.dumps(payload)
|
|
64
|
-
|
|
65
|
-
monkeypatch.setattr(gates, "_gh_api", _stub_gh_api)
|
|
66
|
-
passed, detail = gates._check_bugbot(owner="o", repo="r", sha="abc")
|
|
67
|
-
assert passed is True
|
|
68
|
-
assert "check run 9" in detail
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
def should_evaluate_mergeable_from_pr_object_clean() -> None:
|
|
72
|
-
passed, detail = gates._evaluate_mergeable_from_pr_object(
|
|
73
|
-
{"mergeable": True, "mergeable_state": "clean"}
|
|
74
|
-
)
|
|
75
|
-
assert passed is True
|
|
76
|
-
assert detail == "clean"
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
def should_evaluate_mergeable_from_pr_object_unknown() -> None:
|
|
80
|
-
passed, detail = gates._evaluate_mergeable_from_pr_object(
|
|
81
|
-
{"mergeable": None, "mergeable_state": "unknown"}
|
|
82
|
-
)
|
|
83
|
-
assert passed is False
|
|
84
|
-
assert detail == "unknown"
|
|
1
|
+
"""Behavioral tests for the review and Bugbot convergence gate leaves.
|
|
2
|
+
|
|
3
|
+
::
|
|
4
|
+
|
|
5
|
+
_flatten_paginated_reviews(two pages) -> newest-first flat list
|
|
6
|
+
_bugbot_run_conclusion_detail(success) -> (True, "check run ...")
|
|
7
|
+
_check_bugbot(named complete run) -> (True, "check run ...")
|
|
8
|
+
|
|
9
|
+
Each test drives the real leaf, stubbing only the ``gh`` transport helpers.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import json
|
|
15
|
+
|
|
16
|
+
import pytest
|
|
17
|
+
|
|
18
|
+
import check_convergence_gates as gates
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_flatten_paginated_reviews_flattens_and_sorts_newest_first() -> None:
|
|
22
|
+
pages = [
|
|
23
|
+
[{"id": 1, "submitted_at": "2026-01-01T00:00:00Z"}],
|
|
24
|
+
[{"id": 2, "submitted_at": "2026-03-01T00:00:00Z"}],
|
|
25
|
+
]
|
|
26
|
+
flattened = gates._flatten_paginated_reviews(json.dumps(pages))
|
|
27
|
+
assert flattened is not None
|
|
28
|
+
assert [each_review["id"] for each_review in flattened] == [2, 1]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def test_flatten_paginated_reviews_returns_none_for_non_list_payload() -> None:
|
|
32
|
+
assert (
|
|
33
|
+
gates._flatten_paginated_reviews(json.dumps({"message": "Not Found"})) is None
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def test_bugbot_run_conclusion_detail_passes_on_a_complete_conclusion() -> None:
|
|
38
|
+
complete_conclusion = gates.ALL_BUGBOT_CHECK_RUN_COMPLETE_CONCLUSIONS[0]
|
|
39
|
+
passed, detail = gates._bugbot_run_conclusion_detail(
|
|
40
|
+
{"id": 55, "conclusion": complete_conclusion, "html_url": ""}
|
|
41
|
+
)
|
|
42
|
+
assert passed is True
|
|
43
|
+
assert "check run 55" in detail
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_check_bugbot_reports_success_when_the_named_run_is_complete(
|
|
47
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
48
|
+
) -> None:
|
|
49
|
+
complete_conclusion = gates.ALL_BUGBOT_CHECK_RUN_COMPLETE_CONCLUSIONS[0]
|
|
50
|
+
run_name = f"x {gates.BUGBOT_CHECK_RUN_NAME_SUBSTRING} y"
|
|
51
|
+
payload = {
|
|
52
|
+
"check_runs": [
|
|
53
|
+
{
|
|
54
|
+
"name": run_name,
|
|
55
|
+
"id": 9,
|
|
56
|
+
"conclusion": complete_conclusion,
|
|
57
|
+
"html_url": "",
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
def _stub_gh_api(endpoint_path: str) -> tuple[int, str]:
|
|
63
|
+
return 0, json.dumps(payload)
|
|
64
|
+
|
|
65
|
+
monkeypatch.setattr(gates, "_gh_api", _stub_gh_api)
|
|
66
|
+
passed, detail = gates._check_bugbot(owner="o", repo="r", sha="abc")
|
|
67
|
+
assert passed is True
|
|
68
|
+
assert "check run 9" in detail
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def should_evaluate_mergeable_from_pr_object_clean() -> None:
|
|
72
|
+
passed, detail = gates._evaluate_mergeable_from_pr_object(
|
|
73
|
+
{"mergeable": True, "mergeable_state": "clean"}
|
|
74
|
+
)
|
|
75
|
+
assert passed is True
|
|
76
|
+
assert detail == "clean"
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def should_evaluate_mergeable_from_pr_object_unknown() -> None:
|
|
80
|
+
passed, detail = gates._evaluate_mergeable_from_pr_object(
|
|
81
|
+
{"mergeable": None, "mergeable_state": "unknown"}
|
|
82
|
+
)
|
|
83
|
+
assert passed is False
|
|
84
|
+
assert detail == "unknown"
|
|
@@ -32,7 +32,7 @@ NEVER_PUSHES_PHRASE = "never pushes"
|
|
|
32
32
|
EMPTY_STDIN_PHRASE = "empty"
|
|
33
33
|
CWD_FLAG = "--cwd"
|
|
34
34
|
OPUS_MODEL = "opus"
|
|
35
|
-
HIGH_EFFORT_SLASH = "/code-review
|
|
35
|
+
HIGH_EFFORT_SLASH = "/code-review ultra --fix"
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
def _read_markdown(markdown_path: Path) -> str:
|
|
@@ -20,7 +20,7 @@ The caller passes: its identity, the PR scope, the PR worktree path, this round'
|
|
|
20
20
|
|
|
21
21
|
## Executor choice
|
|
22
22
|
|
|
23
|
-
- **Single-PR loops** (no shared `state.json`): the lead spawns `Agent(subagent_type: "clean-coder")` to write the fix. Stop when `Agent` is unavailable. A spawned clean-coder starts in its own working directory, so its prompt names the PR worktree path and directs it to edit, stage, and commit there.
|
|
23
|
+
- **Single-PR loops** (no shared `state.json`): the lead spawns `Agent(subagent_type: "clean-coder", model: "sonnet")` — worker-model routing per [`skills/orchestrator/SKILL.md`](../orchestrator/SKILL.md#workflow-agent-routing); resolver-supplied sonnet-equivalent on third-party hosts — to write the fix. Stop when `Agent` is unavailable. A spawned clean-coder starts in its own working directory, so its prompt names the PR worktree path and directs it to edit, stage, and commit there.
|
|
24
24
|
- **Multi-PR orchestration** (shared `state.json`): a per-PR clean-coder teammate owns edits, replies, and state writes; the orchestrator holds back from inline edits. The teammate obligations — reply before writing state, which state fields to set, idle handoff — live in the calling skill's multi-PR reference.
|
|
25
25
|
|
|
26
26
|
Run every git command in the PR worktree. `git add`, `git commit`, and `git push` act on the repo of the current working directory, so a cross-repo PR's fix lands in the PR's repo only when the working directory is its worktree.
|
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: privacy-hygiene
|
|
3
|
-
description: Full-repo sweep for personal data and secrets before commit or durable GitHub post. Use when preparing a PR, cleaning a leak, or when `pii_prevention_blocker` denies a write, post, or commit. Triggers on "privacy hygiene", "personal data", "secret sweep", "sanitize repository", "/privacy-hygiene".
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# privacy-hygiene
|
|
7
|
-
|
|
8
|
-
## Overview
|
|
9
|
-
|
|
10
|
-
Find and remove personal data and high-confidence secrets before they land in git history or a durable GitHub post. The `pii_prevention_blocker` hook blocks the common cases at write, post, and commit time. This skill is the full sweep when you need a broader pass or a remediation plan.
|
|
11
|
-
|
|
12
|
-
**Announce at start:** "Running privacy-hygiene sweep."
|
|
13
|
-
|
|
14
|
-
## When to run a full sweep
|
|
15
|
-
|
|
16
|
-
- Before the first push of a branch that touched logs, screenshots, config samples, or machine-local paths
|
|
17
|
-
- After a hook block on email, home path, LAN address, or secret material
|
|
18
|
-
- Before opening a PR to a repository that is public (or will be made public)
|
|
19
|
-
- After pasting support tickets, env dumps, or terminal transcripts into the tree
|
|
20
|
-
|
|
21
|
-
## What the automated gate blocks
|
|
22
|
-
|
|
23
|
-
| Category | Blocked examples | Allowed residual |
|
|
24
|
-
|---|---|---|
|
|
25
|
-
| Email | `user@example.com` | `user@example.com`, `user@example.org`, `user@example.net` |
|
|
26
|
-
| Home path | `C:/Users/example/...`, `/Users/example/...`, `/home/example/...` | `C:/Users/example/...`, `C:/Users/<you>/...`, `/Users/alice/...` |
|
|
27
|
-
| LAN address | Unlisted `10.x` / `172.16–31.x` / `192.168.x` | Public addresses; your NAS host from `CLAUDE_NAS_HOST` or `~/.claude/local-identity.json`; entries in `ALL_ALLOWLISTED_PRIVATE_IP_ADDRESSES` |
|
|
28
|
-
| Secret | `ghp_…`, `github_pat_…`, `AKIA…`, PEM private-key headers | Public keys, redacted `***`, env var names without values |
|
|
29
|
-
|
|
30
|
-
Surfaces:
|
|
31
|
-
|
|
32
|
-
1. **Write / Edit / MultiEdit** — payload text about to land on disk (via PreToolUse dispatcher)
|
|
33
|
-
2. **Durable posts** — `gh pr/issue create|comment|edit|review` bodies and GitHub MCP body/comment fields (Bash and PowerShell)
|
|
34
|
-
3. **git commit** — staged blob text (non-exempt paths) on Bash and PowerShell, including `git.exe` and flag forms (`--no-verify`, `-c`, `-C`). Commit message bodies (`-m` / `-F`) are out of scope for the automated gate
|
|
35
|
-
|
|
36
|
-
## Sweep procedure
|
|
37
|
-
|
|
38
|
-
Run the full-tree sweep in
|
|
39
|
-
[`reference/sweep-procedure.md`](reference/sweep-procedure.md): scope the tree,
|
|
40
|
-
run the ripgrep pass for the four high-confidence pattern families (email, home
|
|
41
|
-
path, LAN address, secret), review each hit against the ignore list, and
|
|
42
|
-
remediate. It also lists the accepted residual — what to leave in place rather
|
|
43
|
-
than over-scrub. The ripgrep command is the only full-tree pass; the write-time
|
|
44
|
-
`pii_prevention_blocker` scans one payload at a time.
|
|
45
|
-
|
|
46
|
-
## Enable on any machine / public repository
|
|
47
|
-
|
|
48
|
-
Install or reinstall the package so hooks and this skill land under `~/.claude/`:
|
|
49
|
-
|
|
50
|
-
```
|
|
51
|
-
cd packages/claude-dev-env
|
|
52
|
-
node bin/install.mjs
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
Hooks register via `hooks/hooks.json` into `~/.claude/settings.json`. Once installed, the same gates apply in every repository the agent touches — private or public.
|
|
56
|
-
|
|
57
|
-
## Open knobs
|
|
58
|
-
|
|
59
|
-
- **NAS / LAN allowlist:** Unlisted private IPs are blocked. The scanner resolves your NAS host from `CLAUDE_NAS_HOST`, then `~/.claude/local-identity.json` (`nas.host`), and allowlists it when it is a private address, so the committed tree holds no real host. `ALL_ALLOWLISTED_PRIVATE_IP_ADDRESSES` in `hooks_constants` holds the static allowlist for any host every machine must share.
|
|
60
|
-
- **Commit-scan exempt repositories:** named owner/repo slugs skip the staged-commit PII scan only. Set `CLAUDE_PII_EXEMPT_REPOS` (comma-separated `owner/repo` values) or list them under `pii_exempt_repositories` in `~/.claude/local-identity.json`. Matching uses the repository's `remote.origin.url` and accepts only the exact host `github.com` (https, ssh scheme, or scp-style). A repository with no readable origin is never exempt (fail-closed to scanning). Write / Edit / MultiEdit and durable post bodies still scan in every repository.
|
|
61
|
-
- **Public maintainer identity:** when a real email or name is intentional product surface, keep it and note that in the PR body so reviewers do not treat it as a leak.
|
|
62
|
-
|
|
63
|
-
## What this skill does not do
|
|
64
|
-
|
|
65
|
-
- Does not rewrite git history without explicit user approval
|
|
66
|
-
- Does not rotate credentials for you
|
|
67
|
-
- Does not replace the write-time hook — it complements it
|
|
68
|
-
- Does not scan commit-message text (`-m` / `-F`); keep messages free of secrets yourself
|
|
1
|
+
---
|
|
2
|
+
name: privacy-hygiene
|
|
3
|
+
description: Full-repo sweep for personal data and secrets before commit or durable GitHub post. Use when preparing a PR, cleaning a leak, or when `pii_prevention_blocker` denies a write, post, or commit. Triggers on "privacy hygiene", "personal data", "secret sweep", "sanitize repository", "/privacy-hygiene".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# privacy-hygiene
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Find and remove personal data and high-confidence secrets before they land in git history or a durable GitHub post. The `pii_prevention_blocker` hook blocks the common cases at write, post, and commit time. This skill is the full sweep when you need a broader pass or a remediation plan.
|
|
11
|
+
|
|
12
|
+
**Announce at start:** "Running privacy-hygiene sweep."
|
|
13
|
+
|
|
14
|
+
## When to run a full sweep
|
|
15
|
+
|
|
16
|
+
- Before the first push of a branch that touched logs, screenshots, config samples, or machine-local paths
|
|
17
|
+
- After a hook block on email, home path, LAN address, or secret material
|
|
18
|
+
- Before opening a PR to a repository that is public (or will be made public)
|
|
19
|
+
- After pasting support tickets, env dumps, or terminal transcripts into the tree
|
|
20
|
+
|
|
21
|
+
## What the automated gate blocks
|
|
22
|
+
|
|
23
|
+
| Category | Blocked examples | Allowed residual |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| Email | `user@example.com` | `user@example.com`, `user@example.org`, `user@example.net` |
|
|
26
|
+
| Home path | `C:/Users/example/...`, `/Users/example/...`, `/home/example/...` | `C:/Users/example/...`, `C:/Users/<you>/...`, `/Users/alice/...` |
|
|
27
|
+
| LAN address | Unlisted `10.x` / `172.16–31.x` / `192.168.x` | Public addresses; your NAS host from `CLAUDE_NAS_HOST` or `~/.claude/local-identity.json`; entries in `ALL_ALLOWLISTED_PRIVATE_IP_ADDRESSES` |
|
|
28
|
+
| Secret | `ghp_…`, `github_pat_…`, `AKIA…`, PEM private-key headers | Public keys, redacted `***`, env var names without values |
|
|
29
|
+
|
|
30
|
+
Surfaces:
|
|
31
|
+
|
|
32
|
+
1. **Write / Edit / MultiEdit** — payload text about to land on disk (via PreToolUse dispatcher)
|
|
33
|
+
2. **Durable posts** — `gh pr/issue create|comment|edit|review` bodies and GitHub MCP body/comment fields (Bash and PowerShell)
|
|
34
|
+
3. **git commit** — staged blob text (non-exempt paths) on Bash and PowerShell, including `git.exe` and flag forms (`--no-verify`, `-c`, `-C`). Commit message bodies (`-m` / `-F`) are out of scope for the automated gate
|
|
35
|
+
|
|
36
|
+
## Sweep procedure
|
|
37
|
+
|
|
38
|
+
Run the full-tree sweep in
|
|
39
|
+
[`reference/sweep-procedure.md`](reference/sweep-procedure.md): scope the tree,
|
|
40
|
+
run the ripgrep pass for the four high-confidence pattern families (email, home
|
|
41
|
+
path, LAN address, secret), review each hit against the ignore list, and
|
|
42
|
+
remediate. It also lists the accepted residual — what to leave in place rather
|
|
43
|
+
than over-scrub. The ripgrep command is the only full-tree pass; the write-time
|
|
44
|
+
`pii_prevention_blocker` scans one payload at a time.
|
|
45
|
+
|
|
46
|
+
## Enable on any machine / public repository
|
|
47
|
+
|
|
48
|
+
Install or reinstall the package so hooks and this skill land under `~/.claude/`:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
cd packages/claude-dev-env
|
|
52
|
+
node bin/install.mjs
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Hooks register via `hooks/hooks.json` into `~/.claude/settings.json`. Once installed, the same gates apply in every repository the agent touches — private or public.
|
|
56
|
+
|
|
57
|
+
## Open knobs
|
|
58
|
+
|
|
59
|
+
- **NAS / LAN allowlist:** Unlisted private IPs are blocked. The scanner resolves your NAS host from `CLAUDE_NAS_HOST`, then `~/.claude/local-identity.json` (`nas.host`), and allowlists it when it is a private address, so the committed tree holds no real host. `ALL_ALLOWLISTED_PRIVATE_IP_ADDRESSES` in `hooks_constants` holds the static allowlist for any host every machine must share.
|
|
60
|
+
- **Commit-scan exempt repositories:** named owner/repo slugs skip the staged-commit PII scan only. Set `CLAUDE_PII_EXEMPT_REPOS` (comma-separated `owner/repo` values) or list them under `pii_exempt_repositories` in `~/.claude/local-identity.json`. Matching uses the repository's `remote.origin.url` and accepts only the exact host `github.com` (https, ssh scheme, or scp-style). A repository with no readable origin is never exempt (fail-closed to scanning). Write / Edit / MultiEdit and durable post bodies still scan in every repository.
|
|
61
|
+
- **Public maintainer identity:** when a real email or name is intentional product surface, keep it and note that in the PR body so reviewers do not treat it as a leak.
|
|
62
|
+
|
|
63
|
+
## What this skill does not do
|
|
64
|
+
|
|
65
|
+
- Does not rewrite git history without explicit user approval
|
|
66
|
+
- Does not rotate credentials for you
|
|
67
|
+
- Does not replace the write-time hook — it complements it
|
|
68
|
+
- Does not scan commit-message text (`-m` / `-F`); keep messages free of secrets yourself
|
|
@@ -49,7 +49,7 @@ Review each hit. Ignore:
|
|
|
49
49
|
## 4. Re-check before commit / post
|
|
50
50
|
|
|
51
51
|
- Stage only clean files
|
|
52
|
-
- Prefer `--body-file` for `gh` posts (also required by the gh-
|
|
52
|
+
- Prefer `--body-file` for `gh` posts (also required by the gh-cli-conventions rule)
|
|
53
53
|
- Let `pii_prevention_blocker` re-run on the next Write / commit / post
|
|
54
54
|
|
|
55
55
|
## Accepted residual (do not over-scrub)
|
|
@@ -15,7 +15,7 @@ The task seeds carry the full ordered detail. The shape:
|
|
|
15
15
|
3. **Bring content as an uncommitted diff.** Copy the POC's file changes into the new branch's working tree. Do not cherry-pick or merge the sandbox commits; the sandbox history stays behind.
|
|
16
16
|
4. **Cleanup.** Remove scratch files, debug dumps, and temp helpers the POC created (`cleanup-temp-files` rule).
|
|
17
17
|
5. **Privacy sweep** via `privacy-hygiene` over the diff.
|
|
18
|
-
6. **Verify** with the `code-verifier` agent in a fresh context. This is where standards re-engage. Expect findings and a repair loop — the POC was un-TDD'd.
|
|
18
|
+
6. **Verify** with the `code-verifier` agent — `model: sonnet`, worker-model routing per [`skills/orchestrator/SKILL.md`](../../orchestrator/SKILL.md#workflow-agent-routing); resolver-supplied sonnet-equivalent on third-party hosts — in a fresh context. This is where standards re-engage. Expect findings and a repair loop — the POC was un-TDD'd.
|
|
19
19
|
7. **Commit and PR.** Only on a clean verdict, run `/commit`, then open a draft PR per the `git-workflow` rule.
|
|
20
20
|
8. **State the honest limitations** from `reference/honest-limitations.md` in the PR body or to the user.
|
|
21
21
|
9. **Converge** by handing the PR to `autoconverge` by default; use `pr-converge` for paced ticks or `bugteam` for an open-loop audit.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release-notes-html
|
|
3
|
+
description: Build a polished self-contained HTML product launch and release-notes page from work completed in the current session, using available repository state, source-of-truth files, tests, approvals, artifacts, commits, pull requests, previews, and release evidence. Use when the user asks to build release notes, create a launch page, document completed work, produce feature-release HTML, or turn the session into product-facing release notes.
|
|
4
|
+
when_to_use: Invoke for requests such as "build release notes for the work you've done," "create release notes HTML," "make a product launch page," "document this completed feature," or "turn our work into a polished release page."
|
|
5
|
+
disable-model-invocation: false
|
|
6
|
+
user-invocable: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
Build a polished, self-contained HTML product launch and release-notes page for the work completed in this session.
|
|
10
|
+
|
|
11
|
+
Use the current conversation, task history, repository state, completed changes, test results, approvals, generated artifacts, plans, handoffs, file paths, commits, pull requests, and other evidence already available in the session as the source of truth.
|
|
12
|
+
|
|
13
|
+
Recover the feature name, purpose, capabilities, specifications, usage instructions, validation results, release status, and first production use directly from the available context. Inspect relevant files and repository artifacts when access is available.
|
|
14
|
+
|
|
15
|
+
Ask one concise clarification question only when the session does not contain enough information to identify the completed feature or its supporting evidence.
|
|
16
|
+
|
|
17
|
+
## Execution
|
|
18
|
+
|
|
19
|
+
Act as the orchestrator.
|
|
20
|
+
|
|
21
|
+
Create a task ledger covering:
|
|
22
|
+
|
|
23
|
+
- Evidence collection
|
|
24
|
+
- Feature and release-state synthesis
|
|
25
|
+
- Page structure
|
|
26
|
+
- HTML creation
|
|
27
|
+
- Evidence audit
|
|
28
|
+
- Visual and browser review
|
|
29
|
+
- Final delivery
|
|
30
|
+
|
|
31
|
+
Assign file inspection and HTML creation to executor workers when worker tools are available. The orchestrator owns the structure, factual acceptance, and final audit.
|
|
32
|
+
|
|
33
|
+
## Evidence rules
|
|
34
|
+
|
|
35
|
+
Use only facts supported by:
|
|
36
|
+
|
|
37
|
+
- The current conversation
|
|
38
|
+
- Current session tasks and results
|
|
39
|
+
- Repository files and git state
|
|
40
|
+
- Named source-of-truth files
|
|
41
|
+
- Generated reports, ledgers, plans, and acceptance packets
|
|
42
|
+
- Explicit user approvals
|
|
43
|
+
- Test and CI output already available
|
|
44
|
+
- Pull request and commit data available to the session
|
|
45
|
+
|
|
46
|
+
Locate the strongest source for each claim.
|
|
47
|
+
|
|
48
|
+
Preserve exact:
|
|
49
|
+
|
|
50
|
+
- Feature and package names
|
|
51
|
+
- File paths
|
|
52
|
+
- Commands
|
|
53
|
+
- Dimensions
|
|
54
|
+
- Flags
|
|
55
|
+
- Identifiers
|
|
56
|
+
- JSON keys
|
|
57
|
+
- Test totals
|
|
58
|
+
- Pull request numbers
|
|
59
|
+
- Branch and release status
|
|
60
|
+
|
|
61
|
+
Place exact technical values inside `<code>` elements.
|
|
62
|
+
|
|
63
|
+
Include previews, approval claims, test counts, merged status, and production-use claims when the available evidence supports them.
|
|
64
|
+
|
|
65
|
+
## Page content
|
|
66
|
+
|
|
67
|
+
Produce one cohesive launch page with a clear hierarchy that a non-engineer can skim.
|
|
68
|
+
|
|
69
|
+
Include the sections that the completed work supports:
|
|
70
|
+
|
|
71
|
+
1. Hero with the feature name and primary benefit
|
|
72
|
+
2. A brief explanation of what the feature enables
|
|
73
|
+
3. Major capability highlights
|
|
74
|
+
4. How to run or use it
|
|
75
|
+
5. Exact specifications
|
|
76
|
+
6. Quality, validation, and safety coverage
|
|
77
|
+
7. First production use, debut project, or approved example
|
|
78
|
+
8. Current availability or completion status
|
|
79
|
+
|
|
80
|
+
Adapt the section names and structure to the actual project. Give every heading a useful takeaway.
|
|
81
|
+
|
|
82
|
+
## Tone
|
|
83
|
+
|
|
84
|
+
Write the page as the launch of a completed new capability.
|
|
85
|
+
|
|
86
|
+
Use present-state product copy focused on:
|
|
87
|
+
|
|
88
|
+
- What it is
|
|
89
|
+
- What the user can accomplish
|
|
90
|
+
- How it works
|
|
91
|
+
- How to use it
|
|
92
|
+
- What guarantees or validations it provides
|
|
93
|
+
- Where it has already been applied
|
|
94
|
+
|
|
95
|
+
Keep implementation history, discarded approaches, debugging chronology, and internal justification outside the page unless they are essential to using the feature.
|
|
96
|
+
|
|
97
|
+
## Voice rules
|
|
98
|
+
|
|
99
|
+
The reader primarily absorbs headings, bolded leads, and the first sentence of each block.
|
|
100
|
+
|
|
101
|
+
1. Every title states a plain-language claim.
|
|
102
|
+
2. Each sentence carries one idea.
|
|
103
|
+
3. Lead with reader meaning, then explain the mechanism.
|
|
104
|
+
4. Explain specialized terms at first use.
|
|
105
|
+
5. Keep exact technical values verbatim inside `<code>` elements.
|
|
106
|
+
6. Limit cards to two sentences.
|
|
107
|
+
7. Limit list items to three sentences.
|
|
108
|
+
8. Give each section a one-sentence subtitle that adds information.
|
|
109
|
+
9. Make the complete story understandable from headings and bolded leads alone.
|
|
110
|
+
10. Use concise, active sentences.
|
|
111
|
+
11. Use present-state language throughout.
|
|
112
|
+
12. Give every important fact one clear location.
|
|
113
|
+
|
|
114
|
+
## Design
|
|
115
|
+
|
|
116
|
+
Create one valid HTML file with self-contained CSS. CDN-hosted fonts are acceptable.
|
|
117
|
+
|
|
118
|
+
Use:
|
|
119
|
+
|
|
120
|
+
- Strong visual hierarchy
|
|
121
|
+
- Spacious typography
|
|
122
|
+
- Scannable cards and sections
|
|
123
|
+
- Responsive desktop and narrow-screen layouts
|
|
124
|
+
- Accessible contrast
|
|
125
|
+
- Clear treatment of code, specifications, and commands
|
|
126
|
+
- An inviting product-launch presentation rather than dense documentation
|
|
127
|
+
|
|
128
|
+
Use an approved preview or product image when one is already available and supported by the session.
|
|
129
|
+
|
|
130
|
+
## Output location
|
|
131
|
+
|
|
132
|
+
Choose the output location from an explicit path already stated in the session.
|
|
133
|
+
|
|
134
|
+
When no output path has been established, write the file beside the project’s existing results, release, report, or acceptance artifacts using a clear name such as:
|
|
135
|
+
|
|
136
|
+
`RELEASE_NOTES.html`
|
|
137
|
+
|
|
138
|
+
Use the operating-system temporary directory only when no project location can be determined safely.
|
|
139
|
+
|
|
140
|
+
Write the file atomically and create its parent directory when required.
|
|
141
|
+
|
|
142
|
+
## Acceptance audit
|
|
143
|
+
|
|
144
|
+
Before delivery:
|
|
145
|
+
|
|
146
|
+
- Verify every factual claim against the available evidence.
|
|
147
|
+
- Review every heading for a clear takeaway.
|
|
148
|
+
- Review every sentence for one idea.
|
|
149
|
+
- Confirm specialized terms receive plain explanations.
|
|
150
|
+
- Confirm exact technical values remain verbatim.
|
|
151
|
+
- Confirm headings and bolded leads communicate the whole story.
|
|
152
|
+
- Confirm the page is readable at desktop and narrow browser widths.
|
|
153
|
+
- Confirm the output is one complete, valid HTML file.
|
|
154
|
+
- Open the completed page in Chrome or the available default browser when the environment supports it.
|
|
155
|
+
- Correct every issue found during the audit.
|
|
156
|
+
|
|
157
|
+
## Delivery
|
|
158
|
+
|
|
159
|
+
Reply with:
|
|
160
|
+
|
|
161
|
+
1. The full absolute path to the HTML file.
|
|
162
|
+
2. One sentence describing what the release-notes page covers.
|
|
163
|
+
|
|
164
|
+
Stop after delivering the completed page.
|
|
@@ -25,7 +25,7 @@ Sessions come in many shapes — convergence loops, feature builds, research div
|
|
|
25
25
|
- **The `Artifact` tool wraps the file in a document skeleton at publish time.** It adds `<!doctype html>…<head>…</head><body>` around whatever the file holds — write page content only (a `<title>`, a `<style>` block, and the body markup). Do not include `<!DOCTYPE>`, `<html>`, `<head>`, or `<body>` tags in the file itself.
|
|
26
26
|
- **The `Artifact` tool redeploys to the same URL only within the current run.** Editing the session's HTML file in a later step of this same skill run and calling `Artifact` again does not mint a new URL — it updates the same published page in place. A fresh session has no memory of an artifact's URL from an earlier run, so republishing a session report written in a prior session always mints a new URL (there is no other way to target the old one without the user supplying it).
|
|
27
27
|
- **Vault paths sit outside `.claude/`.** Headless vault paths (e.g., `$OBSIDIAN_VAULT_PATH`) resolve outside the project tree. Session reports use HTML regardless of vault location — the Artifact tool needs a written file to publish.
|
|
28
|
-
- **Sessions describe current state by convention.** The state_description_blocker hook does not scan .html, but the rule at `~/.claude/rules/
|
|
28
|
+
- **Sessions describe current state by convention.** The state_description_blocker hook does not scan .html, but the rule at `~/.claude/rules/doc-prose-cuts.md` applies as a writing standard — skip historical and comparative language when composing the report; the rule file lists the full trigger set.
|
|
29
29
|
- **`write_existing_file_blocker` rejects Write on existing paths.** Use Write only when creating a fresh session report; use Edit for the vault-context append in step 3.
|
|
30
30
|
- **Obsidian frontmatter index is HTML-blind.** Obsidian's native YAML-frontmatter parser reads only `.md` files. HTML files do not appear in Obsidian's frontmatter index. Search by content still works; search by `type: session-report` does not.
|
|
31
31
|
|
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
# task-build
|
|
2
2
|
|
|
3
|
-
Gathers every open task in the current session and registers each one
|
|
3
|
+
Gathers every open task in the current session and registers each one with the best available task or plan tool.
|
|
4
4
|
|
|
5
5
|
**Trigger:** `/task-build`, "build my task list", "capture these tasks", "add open tasks to the task list", "track these".
|
|
6
6
|
|
|
7
7
|
## Purpose
|
|
8
8
|
|
|
9
|
-
Collects outstanding work from the conversation, `$ARGUMENTS`, and any plan documents or
|
|
9
|
+
Collects outstanding work from the conversation, `$ARGUMENTS`, and any plan documents or task items raised this session, then registers one item per open task — skipping anything already tracked or already complete.
|
|
10
10
|
|
|
11
11
|
## Key files
|
|
12
12
|
|
|
13
13
|
| File | Purpose |
|
|
14
14
|
|---|---|
|
|
15
|
-
| `SKILL.md` |
|
|
15
|
+
| `SKILL.md` | Complete task discovery and registration workflow |
|
|
16
|
+
| `reference/tool-routing.md` | Progressive-disclosure routing and fallback rules |
|
|
16
17
|
|
|
17
18
|
## How the skill runs
|
|
18
19
|
|
|
19
|
-
1.
|
|
20
|
+
1. Reads the current list or visible plan with the selected host tool — prevents duplicates.
|
|
20
21
|
2. Scans `$ARGUMENTS`, the conversation, and any plan or checklist items for open, actionable work.
|
|
21
|
-
3.
|
|
22
|
-
4. Reports how many tasks were added and how many were already tracked.
|
|
22
|
+
3. Prefers `update_plan`; otherwise uses `TaskList`/`TaskCreate`, then `TodoWrite` as the fallback. See `reference/tool-routing.md` for field mapping.
|
|
23
|
+
4. Reports the selected tool, how many tasks were added, and how many were already tracked.
|
|
23
24
|
|
|
24
25
|
## Conventions
|
|
25
26
|
|
|
26
27
|
- This skill only records tasks — it does not start, assign, or complete them.
|
|
27
|
-
- Use
|
|
28
|
+
- Use the matching host operation to set status after the list is built.
|
|
28
29
|
- `disable-model-invocation: true` is not set; the skill uses model judgment to classify open vs. complete items.
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: task-build
|
|
3
|
-
description: "Gather
|
|
3
|
+
description: "Gather open session tasks and register them with the best available task or plan tool. Triggers: '/task-build', 'build my task list', 'capture these tasks', 'add open tasks to the task list', 'track these', task list, update plan."
|
|
4
4
|
argument-hint: "[optional: a list of tasks to capture, or omit to scan the session]"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Task Build
|
|
8
8
|
|
|
9
|
-
Collect every open task and put it on the session task list
|
|
9
|
+
Collect every open task and put it on the session task list or plan using the best available host tool. Read [tool-routing.md](reference/tool-routing.md) only when choosing or adapting the host-tool path.
|
|
10
10
|
|
|
11
11
|
## Instructions
|
|
12
12
|
|
|
13
|
-
1. **Read the current list first.**
|
|
13
|
+
1. **Read the current list first.** Use the read operation paired with the selected host tool when one exists. If `update_plan` is the selected tool, inspect the current visible plan when available because `update_plan` replaces the full plan.
|
|
14
14
|
|
|
15
15
|
2. **Find every open task.** Gather all outstanding work from these sources:
|
|
16
16
|
- `$ARGUMENTS`, when the user passed a list.
|
|
@@ -19,13 +19,21 @@ Collect every open task and put it on the session task list. Each open task beco
|
|
|
19
19
|
|
|
20
20
|
An open task is any concrete, actionable item that is not finished. Skip anything already complete and anything already on the list.
|
|
21
21
|
|
|
22
|
-
3. **
|
|
23
|
-
- `subject` — a short imperative title (e.g. "Fix login redirect").
|
|
24
|
-
- `description` — what the task involves and how to tell it is done.
|
|
25
|
-
- `activeForm` — the present-continuous form for the spinner (e.g. "Fixing login redirect"), when it adds clarity.
|
|
22
|
+
3. **Register one item per task.** Prefer `update_plan` when it is available. Otherwise use the first supported task-list method described in [tool-routing.md](reference/tool-routing.md), preserving the complete existing list when the selected tool replaces it.
|
|
26
23
|
|
|
27
24
|
4. **Report the result.** State how many tasks you added and how many were already tracked, then list the new subjects.
|
|
28
25
|
|
|
29
26
|
## Scope
|
|
30
27
|
|
|
31
|
-
This skill only records tasks. It does not start, assign, or complete them.
|
|
28
|
+
This skill only records tasks. It does not start, assign, or complete them. Report the selected tool, how many items were added, and how many were already tracked. Use the matching host operation to change status later.
|
|
29
|
+
|
|
30
|
+
## File index
|
|
31
|
+
|
|
32
|
+
| File | Purpose |
|
|
33
|
+
|---|---|
|
|
34
|
+
| `SKILL.md` | Task discovery and registration hub |
|
|
35
|
+
| `reference/tool-routing.md` | On-demand host-tool selection and field mapping |
|
|
36
|
+
|
|
37
|
+
## Folder map
|
|
38
|
+
|
|
39
|
+
- `reference/` — host-tool routing details loaded only when needed
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Task Tool Routing
|
|
2
|
+
|
|
3
|
+
Use the first available path in this order:
|
|
4
|
+
|
|
5
|
+
1. **`update_plan`** — preferred when exposed. Call it once with the complete plan. Map each task to `{step, status}`. Use `pending`, `in_progress`, or `completed`.
|
|
6
|
+
2. **`TaskList` + `TaskCreate`** — use the existing task-list workflow when `update_plan` is unavailable. Create one task per new item with `subject`, `description`, and optional `activeForm`.
|
|
7
|
+
3. **`TodoWrite`** — use when neither `update_plan` nor `TaskCreate` is exposed. Preserve the host's required schema and register the complete current task set.
|
|
8
|
+
|
|
9
|
+
Do not invent a tool name. Tool availability means the callable tool is exposed in the current session, not merely mentioned in documentation or in another host's skill.
|
|
10
|
+
|
|
11
|
+
## Status and replacement rules
|
|
12
|
+
|
|
13
|
+
- When a tool replaces the complete list, include existing unfinished items in the replacement payload.
|
|
14
|
+
- When a tool supports incremental creation, skip duplicates and completed items.
|
|
15
|
+
- If no task or plan tool is exposed, report that fact and keep the work unregistered; do not use a markdown checklist as a substitute.
|
|
16
|
+
|
|
17
|
+
## Reporting
|
|
18
|
+
|
|
19
|
+
State the selected tool, the number of new items, the number already tracked, and the new task subjects. If the fallback path was used, name the unavailable preferred tools briefly.
|