claude-dev-env 1.92.1 → 1.93.1

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 (215) hide show
  1. package/CLAUDE.md +6 -2
  2. package/_shared/CLAUDE.md +2 -1
  3. package/_shared/advisor/CLAUDE.md +21 -0
  4. package/_shared/advisor/advisor-protocol.md +142 -0
  5. package/_shared/advisor/scripts/config/advisor_scripts_constants/__init__.py +1 -0
  6. package/_shared/advisor/scripts/config/advisor_scripts_constants/model_tier_run_validator_constants.py +86 -0
  7. package/_shared/advisor/scripts/model_tier_run_validator.py +246 -0
  8. package/_shared/advisor/scripts/pyproject.toml +3 -0
  9. package/_shared/advisor/scripts/tests/test_model_tier_run_validator.py +302 -0
  10. package/_shared/advisor/scripts/tests/test_tier_model_ids.py +180 -0
  11. package/_shared/advisor/scripts/tier_model_ids.py +164 -0
  12. package/_shared/pr-loop/CLAUDE.md +1 -0
  13. package/_shared/pr-loop/precatch-rubric.md +65 -0
  14. package/_shared/pr-loop/scripts/CLAUDE.md +1 -1
  15. package/_shared/pr-loop/scripts/code_rules_gate.py +260 -14
  16. package/_shared/pr-loop/scripts/post_audit_thread.py +1 -1
  17. package/_shared/pr-loop/scripts/pr_loop_shared_constants/CLAUDE.md +1 -1
  18. package/_shared/pr-loop/scripts/pr_loop_shared_constants/code_rules_gate_constants.py +20 -0
  19. package/_shared/pr-loop/scripts/pr_loop_shared_constants/reviews_disabled_constants.py +2 -1
  20. package/_shared/pr-loop/scripts/reviewer_availability.py +42 -12
  21. package/_shared/pr-loop/scripts/reviews_disabled.py +65 -21
  22. package/_shared/pr-loop/scripts/terminology_sweep.py +69 -21
  23. package/_shared/pr-loop/scripts/tests/CLAUDE.md +1 -1
  24. package/_shared/pr-loop/scripts/tests/fixtures/{copilot_internal_user_jonecho.json → copilot_internal_user_example.json} +1 -1
  25. package/_shared/pr-loop/scripts/tests/test_agent_config_carveout.py +1 -1
  26. package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +292 -2
  27. package/_shared/pr-loop/scripts/tests/test_copilot_quota.py +8 -8
  28. package/_shared/pr-loop/scripts/tests/test_reviewer_availability.py +18 -5
  29. package/_shared/pr-loop/scripts/tests/test_reviews_disabled.py +56 -5
  30. package/_shared/pr-loop/scripts/tests/test_terminology_sweep.py +104 -17
  31. package/agents/CLAUDE.md +3 -2
  32. package/agents/clasp-deployment-orchestrator.md +2 -2
  33. package/agents/code-advisor.md +7 -5
  34. package/agents/code-verifier.md +6 -2
  35. package/agents/session-advisor.md +27 -0
  36. package/audit-rubrics/category_rubrics/category-j-code-rules-compliance.md +1 -1
  37. package/audit-rubrics/category_rubrics/category-k-codebase-conflicts.md +1 -1
  38. package/audit-rubrics/prompts/category-a-api-contracts.md +2 -2
  39. package/audit-rubrics/prompts/category-b-selector-engine-compat.md +2 -2
  40. package/audit-rubrics/prompts/category-c-resource-cleanup.md +2 -2
  41. package/audit-rubrics/prompts/category-d-scoping-and-ordering.md +2 -2
  42. package/audit-rubrics/prompts/category-e-dead-code.md +2 -2
  43. package/audit-rubrics/prompts/category-f-silent-failures.md +2 -2
  44. package/audit-rubrics/prompts/category-g-bounds-and-overflow.md +2 -2
  45. package/audit-rubrics/prompts/category-h-security-boundaries.md +2 -2
  46. package/audit-rubrics/prompts/category-i-concurrency.md +2 -2
  47. package/audit-rubrics/prompts/category-j-code-rules-compliance.md +2 -2
  48. package/audit-rubrics/prompts/category-k-codebase-conflicts.md +2 -2
  49. package/audit-rubrics/prompts/category-l-behavior-equivalence.md +2 -2
  50. package/audit-rubrics/prompts/category-m-producer-consumer-cardinality.md +2 -2
  51. package/audit-rubrics/prompts/category-n-test-name-scenario-verifier.md +2 -2
  52. package/audit-rubrics/prompts/category-o-docstring-vs-impl-drift.md +2 -2
  53. package/audit-rubrics/prompts/category-p-name-vs-behavior-contract.md +2 -2
  54. package/bin/CLAUDE.md +1 -0
  55. package/bin/expand_home_directory_tokens.mjs +75 -0
  56. package/bin/install.mjs +21 -7
  57. package/bin/install.test.mjs +220 -10
  58. package/hooks/CLAUDE.md +1 -1
  59. package/hooks/blocking/CLAUDE.md +4 -1
  60. package/hooks/blocking/_path_setup.py +13 -0
  61. package/hooks/blocking/bash_pre_tool_use_dispatcher.py +281 -0
  62. package/hooks/blocking/code_rules_dead_module_constant.py +88 -16
  63. package/hooks/blocking/code_rules_enforcer.py +6 -0
  64. package/hooks/blocking/code_rules_imports_logging.py +34 -1
  65. package/hooks/blocking/code_rules_paths_syspath.py +1 -1
  66. package/hooks/blocking/code_rules_test_layout.py +272 -0
  67. package/hooks/blocking/nas_ssh_binary_enforcer.py +22 -12
  68. package/hooks/blocking/pii_prevention_blocker.py +781 -0
  69. package/hooks/blocking/pii_scanner.py +365 -0
  70. package/hooks/blocking/pre_tool_use_dispatcher.py +3 -3
  71. package/hooks/blocking/stop_dispatcher.py +84 -0
  72. package/hooks/blocking/test__path_setup.py +39 -0
  73. package/hooks/blocking/test_bash_dispatcher_interpreter_starts.py +61 -0
  74. package/hooks/blocking/test_bash_pre_tool_use_dispatcher.py +294 -0
  75. package/hooks/blocking/test_code_rules_enforcer_cross_skill_duplicate.py +1 -1
  76. package/hooks/blocking/test_code_rules_enforcer_dead_config_field.py +2 -2
  77. package/hooks/blocking/test_code_rules_enforcer_dead_module_constant.py +51 -0
  78. package/hooks/blocking/test_code_rules_enforcer_dead_module_constant_read_cap.py +103 -0
  79. package/hooks/blocking/test_code_rules_enforcer_dot_test_pattern.py +1 -1
  80. package/hooks/blocking/test_code_rules_enforcer_file_global_constants.py +1 -1
  81. package/hooks/blocking/test_code_rules_enforcer_hardcoded_user_path.py +11 -11
  82. package/hooks/blocking/test_code_rules_enforcer_naive_datetime.py +1 -1
  83. package/hooks/blocking/test_code_rules_enforcer_same_file_inline_duplicate.py +1 -1
  84. package/hooks/blocking/test_code_rules_enforcer_test_layout.py +111 -0
  85. package/hooks/blocking/test_code_rules_enforcer_type_checking_scope.py +76 -0
  86. package/hooks/blocking/test_destructive_command_blocker.py +29 -9
  87. package/hooks/blocking/test_gh_body_arg_blocker.py +3 -3
  88. package/hooks/blocking/test_nas_ssh_binary_enforcer.py +96 -39
  89. package/hooks/blocking/test_pii_prevention_blocker.py +905 -0
  90. package/hooks/blocking/test_pii_prevention_windows_git_path.py +41 -0
  91. package/hooks/blocking/test_pii_scanner.py +190 -0
  92. package/hooks/blocking/test_pr_description_enforcer_pr_number.py +1 -1
  93. package/hooks/blocking/test_pre_tool_use_dispatcher.py +14 -13
  94. package/hooks/blocking/test_stop_dispatcher.py +187 -0
  95. package/hooks/blocking/test_verdict_directory_write_blocker.py +1 -1
  96. package/hooks/blocking/test_volatile_path_in_post_blocker.py +3 -3
  97. package/hooks/blocking/volatile_path_in_post_blocker.py +54 -5
  98. package/hooks/diagnostic/migrations/README.md +25 -26
  99. package/hooks/diagnostic/test_hook_log_extractor.py +10 -10
  100. package/hooks/hooks.json +10 -120
  101. package/hooks/hooks_constants/CLAUDE.md +12 -3
  102. package/hooks/hooks_constants/bash_pre_tool_use_dispatcher_constants.py +78 -0
  103. package/hooks/hooks_constants/dead_module_constant_constants.py +1 -0
  104. package/hooks/hooks_constants/hosted_hook_runner.py +73 -0
  105. package/hooks/hooks_constants/local_identity.py +182 -0
  106. package/hooks/hooks_constants/nas_ssh_binary_enforcer_constants.py +4 -37
  107. package/hooks/hooks_constants/pii_prevention_constants.py +295 -0
  108. package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +4 -0
  109. package/hooks/hooks_constants/python_style_checks_constants.py +15 -0
  110. package/hooks/hooks_constants/stop_dispatcher_constants.py +26 -0
  111. package/hooks/hooks_constants/test_bash_pre_tool_use_dispatcher_constants.py +87 -0
  112. package/hooks/hooks_constants/test_hardcoded_user_path_constants.py +2 -2
  113. package/hooks/hooks_constants/test_hosted_hook_runner.py +101 -0
  114. package/hooks/hooks_constants/test_layout_constants.py +28 -0
  115. package/hooks/hooks_constants/test_local_identity.py +88 -0
  116. package/hooks/hooks_constants/test_session_env_cleanup_constants.py +1 -1
  117. package/hooks/hooks_constants/test_stop_dispatcher_constants.py +32 -0
  118. package/hooks/validators/README.md +5 -6
  119. package/hooks/validators/__init__.py +2 -2
  120. package/hooks/validators/python_style_checks.py +298 -243
  121. package/hooks/validators/run_all_validators.py +6 -0
  122. package/hooks/validators/test_python_style_checks.py +278 -163
  123. package/package.json +2 -2
  124. package/rules/CLAUDE.md +2 -1
  125. package/rules/bdd.md +1 -1
  126. package/rules/nas-ssh-invocation.md +6 -4
  127. package/rules/no-justification-noise.md +61 -0
  128. package/scripts/test_setup_project_paths.py +1 -1
  129. package/skills/CLAUDE.md +6 -3
  130. package/skills/_shared/pr-loop/scripts/_path_resolver.py +2 -2
  131. package/skills/_shared/pr-loop/scripts/build_audit_prompt.py +1 -1
  132. package/skills/_shared/pr-loop/scripts/build_fix_prompt.py +1 -1
  133. package/skills/_shared/pr-loop/scripts/test__path_resolver.py +42 -3
  134. package/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +11 -11
  135. package/skills/_shared/pr-loop/scripts/test_build_fix_prompt.py +26 -3
  136. package/skills/_shared/pr-loop/scripts/test_preflight_worktree.py +49 -25
  137. package/skills/autoconverge/CLAUDE.md +3 -3
  138. package/skills/autoconverge/SKILL.md +113 -35
  139. package/skills/autoconverge/reference/CLAUDE.md +2 -2
  140. package/skills/autoconverge/reference/convergence.md +44 -22
  141. package/skills/autoconverge/reference/gotchas.md +11 -0
  142. package/skills/autoconverge/reference/stop-conditions.md +23 -13
  143. package/skills/autoconverge/workflow/CLAUDE.md +2 -1
  144. package/skills/autoconverge/workflow/converge.clean-audit.test.mjs +15 -19
  145. package/skills/autoconverge/workflow/converge.contract.test.mjs +43 -42
  146. package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +141 -16
  147. package/skills/autoconverge/workflow/converge.fix-recovery.test.mjs +2 -2
  148. package/skills/autoconverge/workflow/converge.mjs +329 -68
  149. package/skills/autoconverge/workflow/converge.path-aware.test.mjs +1 -1
  150. package/skills/autoconverge/workflow/converge.precatch.test.mjs +152 -0
  151. package/skills/autoconverge/workflow/converge.run-input.test.mjs +3 -3
  152. package/skills/autoconverge/workflow/converge_multi.run-input.test.mjs +15 -15
  153. package/skills/autoconverge/workflow/test_convergence_summary.py +6 -6
  154. package/skills/bdd-protocol/SKILL.md +4 -5
  155. package/skills/bdd-protocol/references/anti-patterns.md +1 -1
  156. package/skills/bugteam/SKILL.md +8 -0
  157. package/skills/bugteam/reference/copilot-gap-analysis.md +20 -20
  158. package/skills/bugteam/reference/obstacles/audit-walk-categories.md +1 -1
  159. package/skills/bugteam/reference/team-setup.md +7 -5
  160. package/skills/bugteam/scripts/reflow_skill_md.py +1 -1
  161. package/skills/copilot-finding-triage/SKILL.md +124 -0
  162. package/skills/copilot-finding-triage/reference/tier-rubric.md +49 -0
  163. package/skills/copilot-finding-triage/scripts/conftest.py +8 -0
  164. package/skills/copilot-finding-triage/scripts/copilot_finding_triage_constants/__init__.py +0 -0
  165. package/skills/copilot-finding-triage/scripts/copilot_finding_triage_constants/config/__init__.py +0 -0
  166. package/skills/copilot-finding-triage/scripts/copilot_finding_triage_constants/config/notify_ntfy_constants.py +32 -0
  167. package/skills/copilot-finding-triage/scripts/notify_ntfy.py +192 -0
  168. package/skills/copilot-finding-triage/scripts/test_notify_ntfy.py +141 -0
  169. package/skills/copilot-finding-triage/templates/notification.md +34 -0
  170. package/skills/copilot-review/SKILL.md +8 -6
  171. package/skills/findbugs/SKILL.md +4 -0
  172. package/skills/fixbugs/SKILL.md +8 -7
  173. package/skills/gotcha/CLAUDE.md +2 -2
  174. package/skills/gotcha/SKILL.md +4 -4
  175. package/skills/log-audit/SKILL.md +4 -6
  176. package/skills/monitor-open-prs/CLAUDE.md +1 -1
  177. package/skills/monitor-open-prs/SKILL.md +6 -1
  178. package/skills/orchestrator/SKILL.md +74 -78
  179. package/skills/orchestrator-refresh/SKILL.md +24 -12
  180. package/skills/post-audit-findings/SKILL.md +5 -9
  181. package/skills/pr-consistency-audit/SKILL.md +5 -1
  182. package/skills/pr-converge/CLAUDE.md +1 -1
  183. package/skills/pr-converge/SKILL.md +86 -47
  184. package/skills/pr-converge/reference/CLAUDE.md +1 -1
  185. package/skills/pr-converge/reference/convergence-gates.md +20 -17
  186. package/skills/pr-converge/reference/examples.md +63 -47
  187. package/skills/pr-converge/reference/fix-protocol.md +15 -15
  188. package/skills/pr-converge/reference/ground-rules.md +11 -7
  189. package/skills/pr-converge/reference/multi-pr-orchestration.md +6 -5
  190. package/skills/pr-converge/reference/per-tick.md +129 -107
  191. package/skills/pr-converge/reference/state-schema.md +15 -10
  192. package/skills/pr-converge/scripts/check_convergence.py +5 -4
  193. package/skills/pr-converge/scripts/test_check_convergence.py +6 -4
  194. package/skills/pr-fix-protocol/SKILL.md +3 -8
  195. package/skills/pr-loop-cloud-transport/SKILL.md +102 -0
  196. package/skills/pr-loop-cloud-transport/reference/identity-and-hooks.md +40 -0
  197. package/skills/pr-loop-cloud-transport/reference/substitution-matrix.md +48 -0
  198. package/skills/pr-loop-lifecycle/SKILL.md +5 -9
  199. package/skills/pr-scope-resolve/SKILL.md +3 -6
  200. package/skills/privacy-hygiene/SKILL.md +114 -0
  201. package/skills/qbug/SKILL.md +8 -8
  202. package/skills/rebase/SKILL.md +5 -1
  203. package/skills/refine/SKILL.md +4 -5
  204. package/skills/reviewer-gates/SKILL.md +7 -11
  205. package/skills/session-log/SKILL.md +4 -1
  206. package/skills/skill-builder/SKILL.md +3 -6
  207. package/skills/structure-prompt/SKILL.md +4 -5
  208. package/skills/team-advisor/SKILL.md +56 -0
  209. package/skills/test_markdown_link_integrity.py +10 -6
  210. package/skills/update/SKILL.md +5 -1
  211. package/skills/usage-pause/SKILL.md +14 -5
  212. package/skills/usage-pause/scripts/resolve_usage_window.py +83 -5
  213. package/skills/usage-pause/scripts/test_resolve_usage_window.py +185 -17
  214. package/skills/usage-pause/scripts/usage_pause_constants/resolve_usage_window_constants.py +4 -3
  215. package/skills/verified-build/SKILL.md +4 -9
@@ -0,0 +1,48 @@
1
+ # gh-to-MCP operation substitution matrix
2
+
3
+ Route every `gh` operation a PR-loop skill names through its cloud path. Load the MCP schemas first (SKILL.md Step 1) — a call before its schema loads fails with `InputValidationError`. Every row traces to a live probe or the operation inventory recorded in `docs/references/cloud-pr-loop-compatibility.md` in the source repo.
4
+
5
+ ## Contents
6
+
7
+ - The operation matrix
8
+ - Pagination rules
9
+ - The REST fallback and its scope
10
+
11
+ ## The operation matrix
12
+
13
+ | Operation | Local mechanism | Cloud path |
14
+ |---|---|---|
15
+ | Read PR / mergeability / draft state | `gh pr view`, `gh api pulls/N` | `mcp__github__pull_request_read(method="get")` |
16
+ | PR diff / files / commits / checks | `gh pr diff`, `gh api ...` | `mcp__github__pull_request_read(method="get_diff"/"get_files"/"get_commits"/"get_check_runs")` |
17
+ | List reviews / review threads | `gh api --paginate --slurp \| jq` | `mcp__github__pull_request_read(method="get_reviews"/"get_review_comments")` |
18
+ | Post / update / close issue | `gh issue create/edit/close` | `mcp__github__issue_write(method="create"/"update")`; close an issue with `method="update", state="closed"` |
19
+ | Post issue or PR comment | `gh issue comment`, `gh pr comment` | `mcp__github__add_issue_comment` |
20
+ | Post review with inline comments | `gh api pulls/N/reviews` POST | `mcp__github__pull_request_review_write(method="create")` → `mcp__github__add_comment_to_pending_review` per finding → `mcp__github__pull_request_review_write(method="submit_pending", event="COMMENT")` |
21
+ | Reply to a review comment | `gh api pulls/N/comments/ID/replies` | `mcp__github__add_reply_to_pull_request_comment` (numeric `discussion_r` id) |
22
+ | Resolve / unresolve a thread | `gh api graphql resolveReviewThread` | `mcp__github__pull_request_review_write(method="resolve_thread"/"unresolve_thread", threadId="PRRT_...")` |
23
+ | Request the Copilot reviewer | `gh api POST pulls/N/requested_reviewers` | `mcp__github__request_copilot_review`. The call completes with no output and no in-band confirmation either way; confirm by a Copilot review landing on the PR. |
24
+ | Mark ready / send to draft | `gh pr ready`, `gh pr ready --undo` | `mcp__github__update_pull_request(draft=false / draft=true)`, with a read-back confirming the draft state each way |
25
+ | Create a PR | `gh pr create --draft` | `mcp__github__create_pull_request(draft=true)` |
26
+ | Edit a PR body or title | `gh pr edit` | `mcp__github__update_pull_request(body=..., title=...)` |
27
+ | Cross-repo PR search | `gh search prs --owner X --state open` | `mcp__github__search_pull_requests(query="user:X is:open", perPage=30)` |
28
+ | Check runs on a SHA | `gh api commits/SHA/check-runs` | `mcp__github__pull_request_read(method="get_check_runs")`, or REST for owners the app connection covers |
29
+ | CI logs | `gh run view --log` | `mcp__github__actions_list` / `mcp__github__actions_get` / `mcp__github__get_job_logs` |
30
+ | Clone another repo | `gh repo clone` | `git clone https://github.com/owner/repo` (session-scoped), or `mcp__Claude_Code_Remote__add_repo` first |
31
+ | Copilot quota | `gh api copilot_internal/user` | None. Treat quota as unknown; call `mcp__github__request_copilot_review`, then read `copilot_down` from what lands on the PR (SKILL.md Step 5). |
32
+ | Second reviewer identity | `gh auth switch`, `BUGTEAM_REVIEWER_ACCOUNT` | None. One MCP identity — the `mcp__github__get_me` login. `COMMENT` reviews on own PRs work; `APPROVE`/`REQUEST_CHANGES` on own PRs are blocked by GitHub. |
33
+
34
+ ## Pagination rules
35
+
36
+ - `mcp__github__pull_request_read(method="get_reviews")` paginates with `page` + `perPage`.
37
+ - `mcp__github__pull_request_read(method="get_review_comments")` paginates with `perPage` + an `after` cursor.
38
+ - Always pass `perPage` on `mcp__github__search_pull_requests`: an unpaginated owner-wide search overflows the tool-result limit.
39
+
40
+ ## The REST fallback and its scope
41
+
42
+ Raw REST through the agent proxy works only for owners the Claude GitHub App connection covers; a repo outside that coverage answers 403. The client shape:
43
+
44
+ ```
45
+ curl -H "Authorization: Bearer $GH_TOKEN" --cacert /root/.ccr/ca-bundle.crt https://api.github.com/repos/<owner>/<repo>/...
46
+ ```
47
+
48
+ GraphQL through the proxy is pinned to a served set of PR-review operations, so a hand-written `gh api graphql` query has no cloud path — read review threads through `mcp__github__pull_request_read(method="get_review_comments")` and resolve them through `mcp__github__pull_request_review_write(method="resolve_thread", ...)`.
@@ -1,15 +1,11 @@
1
1
  ---
2
2
  name: pr-loop-lifecycle
3
3
  description: >-
4
- Opens and closes a PR-loop run: the .claude/** permission grant (with the
5
- auto-mode AskUserQuestion escalation when the classifier blocks it),
6
- worktree preflight and cwd routing, then the ordered close — conditional
7
- TeamDelete for team callers, worktree teardown, working-tree clean, PR
8
- description rewrite composed by the lead, the always-run permission
9
- revoke, and the caller-parameterized final report. Invoked by PR-loop
10
- orchestrators (bugteam, pr-converge, autoconverge, qbug) at run start and
11
- run end, including error exits; not for general git cleanup or permission
12
- management outside a PR loop.
4
+ Opens and closes a PR-loop run: the .claude/** permission grant, worktree
5
+ preflight, and cwd routing at the start; teardown, permission revoke, and
6
+ final report at the end. Invoked by PR-loop orchestrators (bugteam,
7
+ pr-converge, autoconverge, qbug); not for general git cleanup outside a PR
8
+ loop.
13
9
  ---
14
10
 
15
11
  # PR Loop Lifecycle
@@ -2,12 +2,9 @@
2
2
  name: pr-scope-resolve
3
3
  description: >-
4
4
  Resolves the audit/fix target for a PR-loop skill: owner, repo, PR number,
5
- head ref, base ref, PR URL, and starting head SHA via
6
- pull_request_read(method="get"), a search_pull_requests branch fallback, then a
7
- git merge-base upstream-diff fallback, ending in the canonical refusal line
8
- when no target exists. Invoked by PR-loop orchestrators (pr-converge,
9
- bugteam, qbug, findbugs, fixbugs) as their first step; not for general git
10
- questions or branch management.
5
+ head and base refs, PR URL, and head SHA, with a canonical refusal when no
6
+ target exists. Invoked by PR-loop orchestrators (pr-converge, bugteam, qbug,
7
+ findbugs, fixbugs) first; not for general git questions.
11
8
  ---
12
9
 
13
10
  # PR Scope Resolve
@@ -0,0 +1,114 @@
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 | `person@company.io` | `user@example.com`, `user@example.org`, `user@example.net` |
26
+ | Home path | `C:/Users/realname/...`, `/Users/realname/...`, `/home/realname/...` | `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
+ ### 1. Scope the tree
39
+
40
+ ```
41
+ git status -sb
42
+ git diff --stat
43
+ git diff --cached --stat
44
+ ```
45
+
46
+ Prefer the branch diff vs `origin/main` for PR prep:
47
+
48
+ ```
49
+ git fetch origin main
50
+ git diff --name-only origin/main...HEAD
51
+ ```
52
+
53
+ ### 2. Search for high-confidence patterns
54
+
55
+ Run from the repo root (PowerShell-friendly example):
56
+
57
+ ```
58
+ rg -n --hidden -g '!node_modules' -g '!.git' -e '@[A-Za-z0-9.-]+\.[A-Za-z]{2,}' -e 'Users[/\\][^/\\]+' -e '/home/[^/]+' -e '\b(10\.\d+\.\d+\.\d+|192\.168\.\d+\.\d+|172\.(1[6-9]|2\d|3[0-1])\.\d+\.\d+)\b' -e '\b(ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{20,}\b' -e '\bgithub_pat_[A-Za-z0-9_]{20,}\b' -e '\bAKIA[0-9A-Z]{16}\b' -e '-----BEGIN [A-Z ]*PRIVATE KEY-----'
59
+ ```
60
+
61
+ Review each hit. Ignore:
62
+
63
+ - Test fixtures under `test_*.py` / `*_test.py` / `/tests/` (synthetic only)
64
+ - `LICENSE` / copyright notice identity that is intentional and public
65
+ - This package's own `pii_scanner` / `pii_prevention_constants` modules
66
+ - Documented placeholders (`user@example.com`, `C:/Users/<you>/`)
67
+
68
+ ### 3. Remediate
69
+
70
+ | Hit | Fix |
71
+ |---|---|
72
+ | Real email | Replace with `user@example.com` or remove |
73
+ | Home path | Use `Path.home()`, `~`, or `C:/Users/<you>/` |
74
+ | LAN address | Remove, use a hostname, or — for your own NAS — set the host in `CLAUDE_NAS_HOST` or `~/.claude/local-identity.json`, both of which stay out of git |
75
+ | Credential material | Remove from the tree; rotate the credential; load from env/secret store |
76
+ | Already committed | Rewrite is not enough if already pushed — rotate secrets; scrub history only with explicit user approval |
77
+
78
+ ### 4. Re-check before commit / post
79
+
80
+ - Stage only clean files
81
+ - Prefer `--body-file` for `gh` posts (also required by the gh-body-file rule)
82
+ - Let `pii_prevention_blocker` re-run on the next Write / commit / post
83
+
84
+ ## Accepted residual (do not over-scrub)
85
+
86
+ - LICENSE copyright lines naming a legal person or org that owns the work
87
+ - Intentional public maintainer identity published on purpose
88
+ - Example domains reserved for documentation (`example.com` and siblings)
89
+ - Placeholder home users (`example`, `user`, `alice`, `<you>`, `YOUR_USER`)
90
+ - The NAS host you configure locally (allowlisted at scan time, never committed)
91
+ - Public addresses and docs that name private ranges without a live host (still prefer hostnames)
92
+
93
+ ## Enable on any machine / public repository
94
+
95
+ Install or reinstall the package so hooks and this skill land under `~/.claude/`:
96
+
97
+ ```
98
+ cd packages/claude-dev-env
99
+ node bin/install.mjs
100
+ ```
101
+
102
+ 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.
103
+
104
+ ## Open knobs
105
+
106
+ - **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.
107
+ - **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.
108
+
109
+ ## What this skill does not do
110
+
111
+ - Does not rewrite git history without explicit user approval
112
+ - Does not rotate credentials for you
113
+ - Does not replace the write-time hook — it complements it
114
+ - Does not scan commit-message text (`-m` / `-F`); keep messages free of secrets yourself
@@ -1,14 +1,10 @@
1
1
  ---
2
2
  name: qbug
3
3
  description: >-
4
- Required baseline review for every new PR. Runs the /bugteam audit fix
5
- commit push cycle via one clean-coder subagent (not a full team), looping
6
- until convergence or stuck. Uses the same CODE_RULES gate, A–P category
7
- rubric, and per-loop PR review shape as /bugteam without TeamCreate,
8
- teammates, per-loop clean-room, or a loop cap. Invoke /bugteam instead for
9
- larger PRs that need per-loop bias isolation or a hard loop cap. Triggers:
10
- '/qbug', 'quick bug audit', 'solo bug audit', 'baseline PR review',
11
- 'bugteam without a team'.
4
+ Required baseline review for every new PR: runs the /bugteam audit, fix,
5
+ commit, and push cycle through one clean-coder subagent (not a full team),
6
+ looping until convergence or stuck. Triggers: '/qbug', 'quick bug audit',
7
+ 'solo bug audit', 'baseline PR review', 'bugteam without a team'.
12
8
  ---
13
9
 
14
10
  # qbug
@@ -25,6 +21,10 @@ Shared artifacts with /bugteam are referenced below by path, using the `${CLAUDE
25
21
  - **Audit contract** (finding schema, proof-of-absence, adversarial pass, Haiku secondary, post-fix self-audit, diagnostics JSON): [`_shared/pr-loop/audit-contract.md`](../../_shared/pr-loop/audit-contract.md)
26
22
  - PR comment lifecycle shape: [`bugteam/SKILL.md`](../bugteam/SKILL.md#audit-posting)
27
23
 
24
+ ## Transport check (before any GitHub step)
25
+
26
+ Run `command -v gh`; when it succeeds, run `gh auth status`; once the PR scope is resolved, run `gh api repos/<owner>/<repo> --jq .permissions.push` and take `true` as the pass. When any check fails, run the `pr-loop-cloud-transport` skill first and route every `gh` operation in this skill through its substitution matrix.
27
+
28
28
  ## When this skill applies
29
29
 
30
30
  `/qbug` once authorizes the full cycle (no loop cap — runs until `converged` or `stuck`; user can interrupt at any time).
@@ -1,6 +1,10 @@
1
1
  ---
2
2
  name: rebase
3
- description: Rebase a branch onto its base ref with the verification gates needed to catch logically broken results before pushing. Use when the user invokes `/rebase`, says "rebase this branch", "PR has merge conflicts", "rebase onto main", or asks for a force-push to update a remote branch's history. Critical for stacked PRs where the base merged via squash, and for any rebase that includes deletions or renames.
3
+ description: >-
4
+ Rebases a branch onto its base ref with the verification gates that catch
5
+ logically broken results before pushing. Use when the user invokes `/rebase`,
6
+ says 'rebase this branch', 'PR has merge conflicts', or 'rebase onto main', or
7
+ asks for a force-push to update a remote branch's history.
4
8
  ---
5
9
 
6
10
  # /rebase
@@ -1,11 +1,10 @@
1
1
  ---
2
2
  name: refine
3
3
  description: >-
4
- Interview-driven plan refiner with built-in audit loop: fans out research agents,
5
- interviews via AskUserQuestion (mandatory survives no-question directives), writes
6
- the plan to the Obsidian vault under Research/<topic>/<slug>.md, then loops audit and
7
- fix until clean. Triggers: /refine, "refine this", "turn this into a plan", "flesh
8
- this out", "make a spec for this", "let's plan this out", or any vague idea to mature
4
+ Interview-driven plan refiner: fans out research agents, interviews through
5
+ AskUserQuestion, writes to the Obsidian vault, then loops audit and fix.
6
+ Triggers: /refine, 'refine this', 'turn this into a plan', 'flesh this out',
7
+ 'make a spec for this', 'let's plan this out', or any vague idea to mature
9
8
  into a plan.
10
9
  ---
11
10
 
@@ -1,16 +1,10 @@
1
1
  ---
2
2
  name: reviewer-gates
3
3
  description: >-
4
- Runs the availability gates a PR-loop orchestrator checks before engaging an
5
- external reviewer: the CLAUDE_REVIEWS_DISABLED opt-out parse (bugbot,
6
- bugteam, and copilot tokens via reviews_disabled.py), the once-per-run
7
- Copilot premium-quota pre-check (copilot_quota.py with copilot_down
8
- semantics), and the Cursor Bugbot trigger/acknowledge/CI-detect flow
9
- (check_bugbot_ci.py with the literal `bugbot run` comment). Invoked by
10
- PR-loop orchestrators — pr-converge, autoconverge, bugteam, qbug, findbugs,
11
- copilot-review, monitor-open-prs — at run start and at each reviewer
12
- engagement point. Not a general code-review skill; it decides whether a
13
- reviewer runs, never what the reviewer finds.
4
+ Runs the availability gates a PR-loop orchestrator checks before it starts an
5
+ external reviewer: the CLAUDE_REVIEWS_DISABLED opt-out, the once-per-run
6
+ Copilot quota pre-check, and the Cursor Bugbot trigger, acknowledge, and
7
+ CI-detect flow. Decides whether a reviewer runs, never what it finds.
14
8
  ---
15
9
 
16
10
  # Reviewer Gates
@@ -34,13 +28,15 @@ The `CLAUDE_REVIEWS_DISABLED` environment variable is a comma-separated token li
34
28
  | `bugbot` | Cursor Bugbot triggering and polling |
35
29
  | `copilot` | GitHub Copilot review requests and polling |
36
30
 
31
+ Cursor Bugbot is off by default: it runs only when `CLAUDE_REVIEWS_ENABLED` lists `bugbot`, and a `bugbot` token in `CLAUDE_REVIEWS_DISABLED` keeps it off even when the opt-in lists it.
32
+
37
33
  Run the shared parser — never an inline shell parse:
38
34
 
39
35
  ```bash
40
36
  python "$HOME/.claude/_shared/pr-loop/scripts/reviews_disabled.py" --reviewer <bugbot|bugteam|copilot>
41
37
  ```
42
38
 
43
- - **Exit 0** — the named reviewer is opted out. A skill whose whole run depends on that reviewer responds with its refusal line and stops. The template: `/<caller> is disabled via CLAUDE_REVIEWS_DISABLED.` A loop that merely includes the reviewer as one gate marks the reviewer down (`bugbot_down = true`, `copilot_down = true`) and continues on its remaining signals.
39
+ - **Exit 0** — the named reviewer is disabled for this run (opted out, or, for Bugbot, off by default without the `CLAUDE_REVIEWS_ENABLED` opt-in). A skill whose whole run depends on that reviewer responds with its refusal line and stops. A copilot- or bugteam-dependent caller names the opt-out: `/<caller> is disabled via CLAUDE_REVIEWS_DISABLED.` A Bugbot-dependent caller off by default names the opt-in the run needs: `/<caller> is disabled: Cursor Bugbot needs a bugbot token in CLAUDE_REVIEWS_ENABLED.` A loop that merely includes the reviewer as one gate marks the reviewer down (`bugbot_down = true`, `copilot_down = true`) and continues on its remaining signals.
44
40
  - **Exit 1** — the reviewer is available; continue.
45
41
 
46
42
  ## Gate 2: Copilot quota pre-check (once per run)
@@ -1,7 +1,10 @@
1
1
  ---
2
2
  name: session-log
3
3
  description: >-
4
- Log a session report by composing a self-contained HTML page and publishing it with the Artifact tool, then track vault context, extract unrecorded decisions, tidy the project's session folder, and output a /rename command. Use when the user says /session-log, journal this session, log this work, session report, or any variation of "summarize/log/record this session". Also triggers on "save session", "capture session", or "document what we did".
4
+ Logs a session report as an HTML page, tracks vault context, extracts
5
+ decisions, and outputs a /rename command. Use for /session-log, 'journal this
6
+ session', 'log this work', 'session report', 'summarize/log/record this
7
+ session', 'save session', 'capture session', or 'document what we did'.
5
8
  ---
6
9
 
7
10
  # Session Log
@@ -1,12 +1,9 @@
1
1
  ---
2
2
  name: skill-builder
3
3
  description: >-
4
- Orchestrates the complete skill-building lifecycle using best-practice-driven
5
- development. Routes through type classification, folder scaffolding, skill
6
- writing (via skill-writer), self-audit against a 38-point checklist, and
7
- iterative refinement from real usage observations. Use when creating new
8
- skills, improving existing skills, or optimizing skill descriptions.
9
- Triggers: 'build a skill', 'new skill workflow', 'improve this skill',
4
+ Runs the skill-building lifecycle: type classification, scaffolding, writing
5
+ through skill-writer, self-audit against a checklist, and refinement from real
6
+ usage. Triggers: 'build a skill', 'new skill workflow', 'improve this skill',
10
7
  'optimize skill description', 'skill development lifecycle'.
11
8
  ---
12
9
 
@@ -1,11 +1,10 @@
1
1
  ---
2
2
  name: structure-prompt
3
3
  description: >-
4
- Restructure a user-provided prompt: order blocks, replace persona framing with task
5
- constraints, enforce per-category dispositions, expand placeholder tokens via the
6
- sibling rubric or AskUserQuestion, add file:line citations, mark the canonical
7
- sub-bucket, sharpen adversarial-pass phrasing. Triggers: /structure-prompt, "optimize
8
- this prompt", "minimally invasive edit" to a prompt artifact, "tighten this prompt".
4
+ Restructures a user-provided prompt: orders blocks, swaps persona framing for
5
+ task constraints, expands placeholder tokens, and adds file:line citations.
6
+ Triggers: /structure-prompt, 'optimize this prompt', 'minimally invasive edit'
7
+ to a prompt artifact, or 'tighten this prompt'.
9
8
  ---
10
9
 
11
10
  # structure-prompt
@@ -0,0 +1,56 @@
1
+ ---
2
+ name: team-advisor
3
+ description: >-
4
+ Spawn one warm session-advisor at the strongest reachable tier and consult
5
+ it before big decisions, completion, commits, or when stuck. Triggers:
6
+ 'team-advisor', 'team advisor', 'second opinion', 'advisor', 'consult',
7
+ 'verify', 'validate', 'commit', 'push'.
8
+ ---
9
+
10
+ # Team Advisor
11
+
12
+ ## Principle
13
+
14
+ One warm, addressable advisor available at the strongest model tier the session can reach. The session sends concise briefs when a decision benefits from a second opinion: before acting on a plan, at completion, before commits, when stuck, when reconsidering the approach, or when an agent deems it necessary and beneficial to the user's goals.
15
+
16
+ ## Follow the shared protocol
17
+
18
+ **Detect the host profile first** (Host profiles in
19
+ [`_shared/advisor/advisor-protocol.md`](../../_shared/advisor/advisor-protocol.md)
20
+ — e.g. `ADVISOR_HOST_PROFILE` or `GROK_BUILD`). Do not start a model-floor
21
+ walk until the host is known.
22
+
23
+ This session is the shared advisor's sole consumer, so its model floor is
24
+ simply this session's own tier — no routing table to take a max against.
25
+
26
+ **Claude host:** follow the shared protocol for the model-floor walk, the
27
+ warm-up spawn and charter, the consult format and cadence, drift-respawn, and
28
+ the CLI fallback — using `team-advisor-agent` as the name and this session as
29
+ the only consumer (skip the "who you are and your assignment" opener in each
30
+ consult; a single-consumer session doesn't need it).
31
+
32
+ **Grok host:** use the self-as-advisor path in the shared protocol: this
33
+ session answers ENDORSE / CORRECTION / PLAN / STOP itself. Do not spawn a
34
+ Claude `session-advisor` subagent and do not walk the Claude multi-tier
35
+ ladder.
36
+
37
+ ## Constraints
38
+
39
+ - One `team-advisor-agent` per session, owned by this session for its whole
40
+ lifecycle (spawn, drift-respawn, shutdown) — see
41
+ [`_shared/advisor/advisor-protocol.md`](../../_shared/advisor/advisor-protocol.md).
42
+ - Never spawn the warm agent, or its CLI fallback, at a tier below this
43
+ session's own tier.
44
+ - The warm agent (or its CLI equivalent) only answers. It never edits a
45
+ file, never runs a build or test, and never posts anything on the
46
+ session's behalf.
47
+
48
+ ## File Index
49
+
50
+ | File | Purpose |
51
+ |---|---|
52
+ | `SKILL.md` | Pointer to the shared advisor protocol; this session's consumer-specific wiring and constraints. |
53
+
54
+ ## Folder Map
55
+
56
+ - `SKILL.md` — complete team-advisor workflow instructions.
@@ -1,9 +1,10 @@
1
- """Link-integrity check for the skills tree and the shared pr-loop docs.
1
+ """Link-integrity check for the skills tree and shared protocol docs.
2
2
 
3
- Walks every markdown file under ``skills/`` and ``_shared/pr-loop/`` and
4
- resolves each relative markdown link target against the linking file's
5
- directory. A link whose target file or directory does not exist on disk is
6
- reported with its source file and line number, and the test fails.
3
+ Walks every markdown file under ``skills/``, ``_shared/pr-loop/``, and
4
+ ``_shared/advisor/`` and resolves each relative markdown link target against
5
+ the linking file's directory. A link whose target file or directory does not
6
+ exist on disk is reported with its source file and line number, and the test
7
+ fails.
7
8
  """
8
9
 
9
10
  from __future__ import annotations
@@ -14,6 +15,7 @@ from pathlib import Path
14
15
 
15
16
  SKILLS_ROOT = Path(__file__).parent
16
17
  SHARED_PR_LOOP_ROOT = SKILLS_ROOT.parent / "_shared" / "pr-loop"
18
+ SHARED_ADVISOR_ROOT = SKILLS_ROOT.parent / "_shared" / "advisor"
17
19
 
18
20
  MARKDOWN_LINK_PATTERN = re.compile(r"\]\(([^)\s]+)\)")
19
21
  FENCE_MARKER = "```"
@@ -34,10 +36,12 @@ def _iter_markdown_files() -> list[Path]:
34
36
  """List every markdown file the integrity check covers.
35
37
 
36
38
  Returns:
37
- All ``.md`` files under the skills tree and the shared pr-loop tree.
39
+ All ``.md`` files under the skills tree, the shared pr-loop tree, and
40
+ the shared advisor tree.
38
41
  """
39
42
  all_markdown_files = sorted(SKILLS_ROOT.rglob("*.md"))
40
43
  all_markdown_files.extend(sorted(SHARED_PR_LOOP_ROOT.rglob("*.md")))
44
+ all_markdown_files.extend(sorted(SHARED_ADVISOR_ROOT.rglob("*.md")))
41
45
  return all_markdown_files
42
46
 
43
47
 
@@ -1,6 +1,10 @@
1
1
  ---
2
2
  name: update
3
- description: Fast-forwards a local git repository's main branch to a remote's main, after confirming both the local repo path and the source remote through AskUserQuestion. Fetches the chosen remote, checks that the move is a true fast-forward (never a force, never a merge commit), and updates main whether or not main is the checked-out branch. When main is not the checked-out branch, it then offers to switch the checkout to main so the update reaches the files on disk. Use when the user says "/update", "update main", "fast-forward main", "sync main from origin", "pull latest main into <path>", or "bring main up to date". Triggers on "/update", "update main", "fast-forward main", "sync main".
3
+ description: >-
4
+ Fast-forwards a local repository's main branch to a remote's main after
5
+ confirming the repo path and source remote through AskUserQuestion. Use when
6
+ the user says '/update', 'update main', 'fast-forward main', 'sync main from
7
+ origin', 'pull latest main into <path>', or 'bring main up to date'.
4
8
  ---
5
9
 
6
10
  # update
@@ -1,6 +1,10 @@
1
1
  ---
2
2
  name: usage-pause
3
- description: Waits out the account's 5-hour usage window in ScheduleWakeup stages that keep every agent context warm. Resolves the window's reset time and remaining headroom by probing the OAuth usage endpoint, or takes a manual override ('/usage-pause 10:20pm', '/usage-pause 74m'). Warns and stops when the weekly limit is near its cap. Each wakeup pings live and idle-warm agents with a one-line no-new-work checkpoint and records finished results; the final wakeup restores the crons the skill cancelled at pause time. Triggers: '/usage-pause', 'pause until the usage window resets', 'wait out the usage limit', 'usage limit pause'.
3
+ description: >-
4
+ Waits out the account's 5-hour usage window in ScheduleWakeup stages that keep
5
+ every agent context warm. Accepts a manual override like '/usage-pause
6
+ 10:20pm' or '/usage-pause 74m'. Triggers: '/usage-pause', 'pause until the
7
+ usage window resets', 'wait out the usage limit', 'usage limit pause'.
4
8
  argument-hint: "[reset time like 10:20pm | duration like 74m]"
5
9
  ---
6
10
 
@@ -39,16 +43,21 @@ On exit 2 the script prints `{"error": ...}`. Ask the user for a manual reset ti
39
43
 
40
44
  ### Probe mechanism
41
45
 
42
- The resolver reads the Claude Code CLI's OAuth access token from `~/.claude/.credentials.json` (`claudeAiOauth.accessToken`, honored only while its `expiresAt` sits in the future) and sends `GET https://api.anthropic.com/api/oauth/usage` with `Authorization: Bearer <token>` and `anthropic-beta: oauth-2025-04-20`. This is the same endpoint the interactive `/usage` panel reads. The response carries a `five_hour` bucket and a `seven_day` bucket, each with `utilization` (percent spent) and `resets_at`.
46
+ The resolver gets a bearer token from one of two sources and sends `GET https://api.anthropic.com/api/oauth/usage` with `Authorization: Bearer <token>` and `anthropic-beta: oauth-2025-04-20`. This is the same endpoint the interactive `/usage` panel reads. The response carries a `five_hour` bucket and a `seven_day` bucket, each with `utilization` (percent spent) and `resets_at`.
43
47
 
44
- Fallbacks, in order: an expired or unreadable stored token, a failed request, or a response with no readable `five_hour` reset time all end in exit 2 — the manual-override ask above. The manual path works with no probe at all, so the skill functions even when the credential file is stale.
48
+ Token sources, in order:
49
+
50
+ - The Claude Code CLI's OAuth access token in `~/.claude/.credentials.json` (`claudeAiOauth.accessToken`, honored only while its `expiresAt` sits in the future).
51
+ - The session ingress token in the file named by the `CLAUDE_SESSION_INGRESS_TOKEN_FILE` environment variable, read when the credential file token is unavailable. Claude Code cloud sessions set this variable and omit the credential file.
52
+
53
+ Fallbacks, in order: no usable token from either source, a failed request, or a response with no readable `five_hour` reset time all end in exit 2 — the manual-override ask above. The manual path works with no probe at all, so the skill functions even when both token sources are stale.
45
54
 
46
55
  Why this probe and not the others:
47
56
 
48
57
  - The interactive `/usage` panel shows the same data but has no scriptable output.
49
58
  - `claude -p --output-format json` spends usage to answer and its metadata reports per-call token counts, not the account window clock.
50
59
  - `anthropic-ratelimit-*` response headers cover API-key Messages traffic, not the subscription session window, and reading them also costs a request.
51
- - Refreshing the OAuth token from a script is out of scope: token rotation would desync the refresh token the CLI has on disk and log the CLI out. The resolver only ever reads the credential file.
60
+ - Refreshing the OAuth token from a script is out of scope: token rotation would desync the refresh token the CLI has on disk and log the CLI out. The resolver only ever reads its token sources.
52
61
 
53
62
  ## Weekly limit guard
54
63
 
@@ -101,7 +110,7 @@ Fill each `<slot>` at schedule time: `<remaining_stage_durations>` is the tail o
101
110
  | `SKILL.md` | This flow: resolve, weekly guard, stage chain, templates |
102
111
  | `scripts/resolve_usage_window.py` | The window resolver and stage planner CLI |
103
112
  | `scripts/test_resolve_usage_window.py` | Behavioral tests for parsing, staging, token reading, extraction, CLI |
104
- | `scripts/usage_pause_constants/resolve_usage_window_constants.py` | Endpoint, credential keys, stage sizing, thresholds, result keys |
113
+ | `scripts/usage_pause_constants/resolve_usage_window_constants.py` | Endpoint, credential keys, the session ingress token env var, stage sizing, thresholds, result keys |
105
114
 
106
115
  ## Gotchas
107
116