@monte3l/groundwork 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/README.md +23 -0
  2. package/bin/m3l-groundwork.mjs +10 -0
  3. package/dist/assets.d.ts +20 -0
  4. package/dist/assets.js +79 -0
  5. package/dist/caps.d.ts +25 -0
  6. package/dist/caps.js +69 -0
  7. package/dist/conflicts.d.ts +12 -0
  8. package/dist/conflicts.js +77 -0
  9. package/dist/emit.d.ts +7 -0
  10. package/dist/emit.js +42 -0
  11. package/dist/git.d.ts +3 -0
  12. package/dist/git.js +9 -0
  13. package/dist/harness/conformance.d.ts +20 -0
  14. package/dist/harness/conformance.js +18 -0
  15. package/dist/harness/frontmatter.d.ts +38 -0
  16. package/dist/harness/frontmatter.js +204 -0
  17. package/dist/harness/grade.d.ts +4 -0
  18. package/dist/harness/grade.js +105 -0
  19. package/dist/harness/rules.d.ts +55 -0
  20. package/dist/harness/rules.js +580 -0
  21. package/dist/harness/types.d.ts +32 -0
  22. package/dist/harness/types.js +9 -0
  23. package/dist/inventory.d.ts +63 -0
  24. package/dist/inventory.js +66 -0
  25. package/dist/jsonc.d.ts +14 -0
  26. package/dist/jsonc.js +83 -0
  27. package/dist/main.d.ts +24 -0
  28. package/dist/main.js +297 -0
  29. package/dist/merge-json.d.ts +74 -0
  30. package/dist/merge-json.js +135 -0
  31. package/dist/mode.d.ts +19 -0
  32. package/dist/mode.js +53 -0
  33. package/dist/packs.d.ts +61 -0
  34. package/dist/packs.js +186 -0
  35. package/dist/plugin.d.ts +23 -0
  36. package/dist/plugin.js +79 -0
  37. package/dist/report.d.ts +4 -0
  38. package/dist/report.js +323 -0
  39. package/dist/survey/fs-walk.d.ts +14 -0
  40. package/dist/survey/fs-walk.js +60 -0
  41. package/dist/survey/survey-docs.d.ts +4 -0
  42. package/dist/survey/survey-docs.js +69 -0
  43. package/dist/survey/survey-harness.d.ts +4 -0
  44. package/dist/survey/survey-harness.js +121 -0
  45. package/dist/survey/survey-shape.d.ts +4 -0
  46. package/dist/survey/survey-shape.js +182 -0
  47. package/dist/survey/survey-toolchain.d.ts +4 -0
  48. package/dist/survey/survey-toolchain.js +217 -0
  49. package/dist/survey/survey.d.ts +5 -0
  50. package/dist/survey/survey.js +21 -0
  51. package/dist/survey/types.d.ts +117 -0
  52. package/dist/survey/types.js +8 -0
  53. package/dist/tokens.d.ts +13 -0
  54. package/dist/tokens.js +13 -0
  55. package/dist/toolchain/conformance.d.ts +20 -0
  56. package/dist/toolchain/conformance.js +30 -0
  57. package/dist/toolchain/grade.d.ts +4 -0
  58. package/dist/toolchain/grade.js +244 -0
  59. package/dist/toolchain/rules.d.ts +118 -0
  60. package/dist/toolchain/rules.js +706 -0
  61. package/dist/toolchain/tsconfig-chain.d.ts +36 -0
  62. package/dist/toolchain/tsconfig-chain.js +116 -0
  63. package/dist/toolchain/types.d.ts +27 -0
  64. package/dist/toolchain/types.js +9 -0
  65. package/package.json +59 -0
  66. package/plugin/skills/customize/SKILL.md +305 -0
  67. package/plugin/src/domain-map.ts +134 -0
  68. package/plugin/src/index.ts +4 -0
  69. package/plugin/src/kind-facet-map.ts +174 -0
  70. package/plugin/src/pack-map.ts +65 -0
  71. package/templates/core/.claude/agents/Explore.md +43 -0
  72. package/templates/core/.claude/agents/code-implementer.md +258 -0
  73. package/templates/core/.claude/agents/code-reviewer.md +163 -0
  74. package/templates/core/.claude/agents/silent-failure-hunter.md +191 -0
  75. package/templates/core/.claude/agents/test-author.md +211 -0
  76. package/templates/core/.claude/hooks/guard-branch-isolation.mjs +123 -0
  77. package/templates/core/.claude/hooks/guard-double-background.mjs +113 -0
  78. package/templates/core/.claude/hooks/guard-git-push-signed.mjs +90 -0
  79. package/templates/core/.claude/hooks/guard-hub-src-writes.mjs +88 -0
  80. package/templates/core/.claude/hooks/guard-js-extension.mjs +66 -0
  81. package/templates/core/.claude/hooks/guard-no-commonjs.mjs +105 -0
  82. package/templates/core/.claude/hooks/guard-protected-paths.mjs +45 -0
  83. package/templates/core/.claude/hooks/guard-secret-writes.mjs +183 -0
  84. package/templates/core/.claude/hooks/inject-decision-gate.mjs +119 -0
  85. package/templates/core/.claude/hooks/post-edit-verify.mjs +150 -0
  86. package/templates/core/.claude/rules/agent-dispatch.md +121 -0
  87. package/templates/core/.claude/rules/refactoring.md +52 -0
  88. package/templates/core/.claude/rules/src.md +114 -0
  89. package/templates/core/.claude/rules/tests.md +129 -0
  90. package/templates/core/.claude/settings.json +111 -0
  91. package/templates/core/.claude/skills/creating-prs/SKILL.md +132 -0
  92. package/templates/core/.claude/skills/finishing-work/SKILL.md +117 -0
  93. package/templates/core/.claude/skills/harness-guidance/SKILL.md +140 -0
  94. package/templates/core/.claude/skills/harness-guidance/references/official-sources.md +58 -0
  95. package/templates/core/.claude/skills/starting-work/SKILL.md +94 -0
  96. package/templates/core/.claude/skills/triaging-ci/SKILL.md +111 -0
  97. package/templates/core/.claude/skills/typescript-guidance/SKILL.md +143 -0
  98. package/templates/core/.claude/skills/typescript-guidance/references/typescript-sources.md +102 -0
  99. package/templates/core/.claude/skills/writing-commits/SKILL.md +248 -0
  100. package/templates/core/.github/workflows/ci.yml +123 -0
  101. package/templates/core/.github/workflows/dependency-review.yml +26 -0
  102. package/templates/core/.github/workflows/security-audit.yml +54 -0
  103. package/templates/core/.node-version +1 -0
  104. package/templates/core/.prettierignore +5 -0
  105. package/templates/core/.prettierrc.json +4 -0
  106. package/templates/core/CLAUDE.md +127 -0
  107. package/templates/core/README.md +24 -0
  108. package/templates/core/_gitignore +19 -0
  109. package/templates/core/_npmrc +1 -0
  110. package/templates/core/bin/check-exports.mjs +92 -0
  111. package/templates/core/bin/check-harness.mjs +27 -0
  112. package/templates/core/bin/check-node-version.mjs +51 -0
  113. package/templates/core/bin/check-toolchain.mjs +20 -0
  114. package/templates/core/bin/lib/agent-roster.mjs +8 -0
  115. package/templates/core/bin/lib/frontmatter.mjs +210 -0
  116. package/templates/core/bin/lib/harness-rules.mjs +916 -0
  117. package/templates/core/bin/lib/protected-paths.mjs +23 -0
  118. package/templates/core/bin/lib/report.mjs +56 -0
  119. package/templates/core/bin/lib/signed-range.mjs +178 -0
  120. package/templates/core/bin/lib/toolchain-rules.mjs +1264 -0
  121. package/templates/core/bin/lib/verify-steps.mjs +131 -0
  122. package/templates/core/bin/lib/verify-steps.packs.json +1 -0
  123. package/templates/core/bin/lint-commit.mjs +50 -0
  124. package/templates/core/bin/strip-claude-trailers.mjs +25 -0
  125. package/templates/core/bin/verify.mjs +64 -0
  126. package/templates/core/commitlint.config.js +11 -0
  127. package/templates/core/docs/research/harness-refresh.md +27 -0
  128. package/templates/core/docs/research/typescript-refresh.md +32 -0
  129. package/templates/core/eslint.config.js +105 -0
  130. package/templates/core/knip.json +6 -0
  131. package/templates/core/lefthook.yml +39 -0
  132. package/templates/core/package.json +58 -0
  133. package/templates/core/pnpm-workspace.yaml +13 -0
  134. package/templates/core/src/index.ts +12 -0
  135. package/templates/core/tests/index.test.ts +8 -0
  136. package/templates/core/tsconfig.base.json +36 -0
  137. package/templates/core/tsconfig.build.json +10 -0
  138. package/templates/core/tsconfig.json +11 -0
  139. package/templates/core/vitest.config.ts +32 -0
  140. package/templates/packs/README.md +81 -0
  141. package/templates/packs/harness-extras/files/.claude/agents/type-design-analyzer.md +188 -0
  142. package/templates/packs/harness-extras/files/.claude/hooks/guard-readonly-bash.mjs +324 -0
  143. package/templates/packs/harness-extras/files/.claude/hooks/reinject-compact-handoff.mjs +197 -0
  144. package/templates/packs/harness-extras/files/.claude/hooks/write-compact-handoff.mjs +180 -0
  145. package/templates/packs/harness-extras/files/bin/check-file-budget.mjs +407 -0
  146. package/templates/packs/harness-extras/files/bin/file-budget-baseline.json +1 -0
  147. package/templates/packs/harness-extras/pack.json +65 -0
  148. package/templates/packs/statusline/files/.claude/hooks/statusline-layout.mjs +365 -0
  149. package/templates/packs/statusline/files/.claude/hooks/statusline.mjs +996 -0
  150. package/templates/packs/statusline/files/.claude/hooks/subagent-statusline.mjs +203 -0
  151. package/templates/packs/statusline/pack.json +31 -0
@@ -0,0 +1,58 @@
1
+ # Official Anthropic sources — the allowlist
2
+
3
+ The single source list consulted by `harness-guidance` in both modes.
4
+ Editing this file is the one edit site when Anthropic moves, renames, or
5
+ adds a domain.
6
+
7
+ ## Domain allowlist
8
+
9
+ Pass verbatim as `WebSearch`'s `allowed_domains`:
10
+
11
+ ```
12
+ anthropic.com, www.anthropic.com, claude.com, www.claude.com,
13
+ platform.claude.com, code.claude.com, docs.claude.com, docs.anthropic.com
14
+ ```
15
+
16
+ Anthropic's engineering posts, research papers, and news all live under
17
+ `anthropic.com` (including `/engineering`, `/research`, `/news`), so this
18
+ one allowlist covers whitepapers and blog posts as well as docs.
19
+
20
+ ## GitHub caveat
21
+
22
+ `allowed_domains` filters by domain, not path, so a bare `github.com`
23
+ allowance would let through any repo. Agents may include `github.com` and
24
+ `raw.githubusercontent.com` in their search domains, but must **only cite or
25
+ fetch URLs under the `anthropics` GitHub org** — `github.com/anthropics/...`
26
+ or `raw.githubusercontent.com/anthropics/...` — and drop any other GitHub
27
+ result, even a highly-ranked one.
28
+
29
+ ## First-class sources to enumerate directly
30
+
31
+ Search ranking is not exhaustive — a recent post can be silently missed
32
+ unless an agent is told to check these directly:
33
+
34
+ - **Claude Code CHANGELOG** —
35
+ `https://raw.githubusercontent.com/anthropics/claude-code/main/CHANGELOG.md`.
36
+ The authoritative, version-ordered record of Claude Code feature and
37
+ behavior changes. Because it's version-ordered, it can be read as a
38
+ **delta** from a known prior version — the primary input for refresh
39
+ mode's Step 2.
40
+ - **Blog / news / engineering / research index pages** — enumerate directly:
41
+ - `https://www.anthropic.com/news`
42
+ - `https://www.anthropic.com/engineering`
43
+ - `https://www.anthropic.com/research`
44
+ - `https://claude.com/blog`
45
+
46
+ ## Current-date anchor
47
+
48
+ Every agent brief must state today's date explicitly. A `retrieved <date>`
49
+ stamp otherwise depends on the spoke inferring the date itself, which is
50
+ unreliable.
51
+
52
+ ## Coverage discipline
53
+
54
+ Reject any non-allowlisted domain outright and say so in the report, rather
55
+ than substituting a community blog, a third-party summary, or a Stack
56
+ Overflow answer for missing official coverage. If a facet turns up no
57
+ official source, that is itself a reportable finding (a coverage gap), not
58
+ a reason to lower the bar.
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: starting-work
3
+ description: >-
4
+ The pre-work decision gate for any task that will change code. Invoke it
5
+ FIRST -- before reading, investigating, or editing anything -- for
6
+ "implement", "build", "add", "fix the bug where ...", "refactor", or any
7
+ request to change behavior, even when the change is unnamed or you have not
8
+ seen the code yet. Inspects git state, recommends a branch (feat/fix <slug>)
9
+ and push target, and decides whether a PR is required, all confirmed before
10
+ any write. Skip for research and questions that change nothing.
11
+ ---
12
+
13
+ # starting-work
14
+
15
+ This skill is the single place the project answers "where do I do this
16
+ work?" before touching anything. `guard-branch-isolation.mjs` hard-blocks
17
+ writes to `src/**` and `tests/**` while `HEAD` is `main` — that's a
18
+ backstop, not a plan: if you discover it when a write is rejected, you're
19
+ already mid-task with a dirty tree. This skill is the workflow half — it
20
+ branches _before_ the block can fire.
21
+
22
+ ## The contract
23
+
24
+ **Infer and recommend all decisions, then confirm every one with the user in
25
+ a single round. Do not write files or create a branch until the user has
26
+ confirmed.** The user is always free to override a recommendation; your job
27
+ is to make the right default obvious, not to force it.
28
+
29
+ ## Steps
30
+
31
+ ### 1 — Inspect git state (read-only)
32
+
33
+ ```bash
34
+ git rev-parse --abbrev-ref HEAD # branch name; "HEAD" means detached
35
+ git status --porcelain # is the tree already dirty?
36
+ ```
37
+
38
+ - A detached HEAD sitting on the `main` commit is treated as `main` for
39
+ isolation purposes — it's the same tree state the guard protects.
40
+ - **Re-run this inspection after any conversational gap, not just at the
41
+ start.** The branch is not a stable fact across a long session.
42
+
43
+ ### 2 — Infer the change scope
44
+
45
+ From the task in front of you, work out **which paths will be edited** and
46
+ whether any are _guarded_ (under `src/**` or `tests/**`). This drives the PR
47
+ decision and whether isolation is even required. A docs-only or `.claude/`
48
+ -only change touches no guarded path, so the guard won't fire and a PR may
49
+ be optional; a change under `src/` or `tests/` always needs isolation and a
50
+ PR.
51
+
52
+ ### 3 — Recommend each decision
53
+
54
+ - **Branch** — recommend `feat/<slug>` (or `fix/<slug>` for a bug fix), with
55
+ the slug derived from the task (kebab-case, short). If the repo is already
56
+ on a suitable non-`main` branch, recommend **staying** on it. Never
57
+ recommend `main` or a detached-on-`main` HEAD for guarded work.
58
+ - **PR required?** — **yes** whenever a guarded path is in scope: land via
59
+ PR, never a direct commit to `main`. For docs/config-only changes, note
60
+ that a PR is optional but still recommended.
61
+ - **Push target** — `origin <the recommended branch>`. Never `origin main`.
62
+
63
+ ### 4 — Confirm with the user (blocking)
64
+
65
+ Ask every decision that applies in **one** `AskUserQuestion` call — branch,
66
+ PR-required, and push target — one question per decision, with your inferred
67
+ recommendation listed **first** and labelled "(Recommended)". For the
68
+ branch, offer the inferred `feat/<slug>` plus an "Other" path for a custom
69
+ slug. Make it explicit in your framing that **nothing is written and no
70
+ branch is created until they confirm** — this is the whole point of the
71
+ gate.
72
+
73
+ If the user has _already_ told you the branch to use (e.g. "do it on
74
+ `fix/foo`"), don't re-ask that dimension — treat it as confirmed and only
75
+ surface the decisions still open.
76
+
77
+ ### 5 — Act on the confirmed decisions
78
+
79
+ ```bash
80
+ git switch -c feat/<slug> # or fix/<slug>
81
+ ```
82
+
83
+ Verify `HEAD` is neither `main` nor detached-on-`main` before handing back;
84
+ if it is, loop back to Step 4 rather than proceeding into a write that the
85
+ guard will reject. When **resuming an existing feature branch** that may
86
+ have fallen behind, resync it with `origin/main` before working (or defer to
87
+ the resync step in `creating-prs`) so the branch does not drift from the
88
+ base over multiple sessions.
89
+
90
+ ### 6 — Hand back
91
+
92
+ Report a one-line summary of the confirmed decisions — branch, PR
93
+ (yes/no), push target — so the calling skill or the user proceeds with the
94
+ context recorded.
@@ -0,0 +1,111 @@
1
+ ---
2
+ name: triaging-ci
3
+ description: >-
4
+ Diagnose a CI failure via gh CLI: resolve the failing run, fetch logs, map the
5
+ failure to its pipeline step, report root cause plus the exact local repro
6
+ command, and present 3-5 fix options. Use for /triaging-ci, "why did CI fail",
7
+ "CI is failing", "debug the CI run", or a specific run ID/URL. GitHub stance:
8
+ gh CLI.
9
+ ---
10
+
11
+ Diagnose why a GitHub Actions CI run failed by fetching its logs via `gh` and
12
+ mapping the failure back to the specific pipeline step and root cause, then
13
+ present 3–5 solution options for the user to choose from. This skill does not
14
+ apply fixes — it ends with options, not actions.
15
+
16
+ ## Steps
17
+
18
+ ### 1 — Resolve the run
19
+
20
+ If the user provided an explicit run ID or URL, extract the numeric ID from it.
21
+
22
+ Otherwise, find the most recent failed run on the current branch:
23
+
24
+ ```bash
25
+ gh run list --branch $(git rev-parse --abbrev-ref HEAD) \
26
+ --limit 5 \
27
+ --json databaseId,status,conclusion,name,createdAt
28
+ ```
29
+
30
+ Pick the most recent entry whose `conclusion` is `"failure"`.
31
+
32
+ If no failed run exists on the current branch (empty result or all passing), widen
33
+ the search to the 10 most recent runs across all branches:
34
+
35
+ ```bash
36
+ gh run list --limit 10 \
37
+ --json databaseId,status,conclusion,name,headBranch,createdAt
38
+ ```
39
+
40
+ If a failed run exists in the broader search, proceed with that run and note the
41
+ branch it came from. If no failed run exists anywhere in the recent history, report
42
+ that clearly and stop — there is nothing to triage.
43
+
44
+ **Zero runs at all (not even queued) is a different problem from a failed
45
+ run** — a dropped webhook event, not a code failure. If a push landed but no
46
+ run was ever created for its head SHA, first confirm it isn't isolated to
47
+ this push — check whether a different, unrelated PR pushed around the same
48
+ time shows the identical gap. If so, it's likely a one-off delivery drop,
49
+ not a repo config problem; a safe, reversible fix is an empty-commit push
50
+ (`git commit --allow-empty -m "chore: retrigger CI"`) to fire a fresh event,
51
+ rather than auditing Actions permissions or workflow triggers.
52
+
53
+ ### 2 — Fetch the failing job logs
54
+
55
+ Pull only the logs from steps that failed:
56
+
57
+ ```bash
58
+ gh run view <id> --log-failed
59
+ ```
60
+
61
+ If that command returns nothing (the run was cancelled, or all steps are
62
+ technically "successful" but a post-step failed), fall back to the full log:
63
+
64
+ ```bash
65
+ gh run view <id> --log
66
+ ```
67
+
68
+ Do not reproduce the entire log output — find and keep only the region around
69
+ the first failure, typically the last 50–100 lines before the run aborted.
70
+
71
+ ### 3 — Map to the pipeline step
72
+
73
+ `.github/workflows/ci.yml`'s lanes each run `node bin/verify.mjs --step <id>`
74
+ against a step id from `bin/lib/verify-steps.mjs` — that file's `cmd` field
75
+ IS the local reproduction command, so mapping a failing CI step to its local
76
+ command is always: find the `## <step name>` line the log shows, match it to
77
+ the step's `name` in `bin/lib/verify-steps.mjs`, and reproduce with that
78
+ step's `cmd` array joined as a shell command (or just `node bin/verify.mjs
79
+ --step <id>` directly). The step name usually appears verbatim in the log
80
+ lines (e.g. `Run pnpm lint` or `##[error]...`).
81
+
82
+ ### 4 — Report the diagnosis
83
+
84
+ Output a concise structured report — no prose padding:
85
+
86
+ ```
87
+ ## CI Triage — Run #<id>
88
+
89
+ **Failed step:** <step name>
90
+ **Reproduce locally:** <exact command, e.g. `node bin/verify.mjs --step lint`>
91
+ **Root cause:** <one sentence>
92
+ **Error excerpt:**
93
+ <quoted lines from the log — enough to identify the file/rule/test>
94
+ **Assessment:** <Real failure | Likely flake — explain why>
95
+ ```
96
+
97
+ A "likely flake" is a transient runner issue: network timeout downloading
98
+ dependencies, OOM on a large test run, a GitHub-side runner error, or a retry
99
+ that would probably pass. Everything else is a real failure requiring a code fix.
100
+
101
+ ### 5 — Present solution options
102
+
103
+ After the diagnosis, present 3–5 solution options in a separate
104
+ `## Solution Options` section so the diagnosis stays readable on its own. For
105
+ each option include: a one-line description, the exact command or change
106
+ needed, and the main tradeoff. Do not apply any fix — leave the choice to the
107
+ user.
108
+
109
+ If triaging several failed runs in one pass, write the per-run reports to a
110
+ file and keep the chat reply to a short summary table — don't paste every
111
+ report inline.
@@ -0,0 +1,143 @@
1
+ ---
2
+ name: typescript-guidance
3
+ description: >-
4
+ Dual-mode TypeScript guidance skill. `research` mode answers a single
5
+ TypeScript/toolchain question from owner-normative upstream sources only
6
+ (typescriptlang.org, the devblog, microsoft/TypeScript releases,
7
+ nodejs.org type stripping, typescript-eslint.io, attw, publint). `refresh`
8
+ mode sweeps this project's whole TypeScript-facing surface — tsconfig,
9
+ eslint, packaging, and the test config/approach — against a living
10
+ tracker and produces a remediation plan. Use for /typescript-guidance,
11
+ "what does the TypeScript team say about X", "are we behind on
12
+ TypeScript", "is our tsconfig still current", or before changing a
13
+ compiler flag. Not how this project's config is wired today — that's
14
+ CLAUDE.md and the config files themselves.
15
+ ---
16
+
17
+ # typescript-guidance
18
+
19
+ One skill, two modes, sharing one allowlist
20
+ (`references/typescript-sources.md`) so they can't drift apart. Pick the
21
+ mode from how you were invoked: a specific question → `research`; a
22
+ periodic or `/customize`-driven sweep → `refresh`.
23
+
24
+ **Must only run in the main (hub) agent, never inside a subagent** — it ends
25
+ in `EnterPlanMode` (refresh) or an `AskUserQuestion` (either mode,
26
+ occasionally), neither of which a subagent can do.
27
+
28
+ **No files are written by this skill itself** in research mode by default;
29
+ refresh mode writes to exactly one file, the tracker, in Step 5.
30
+
31
+ ## Authority (read this before either mode)
32
+
33
+ This skill has authority over **every TypeScript-facing file in the
34
+ project** — `tsconfig.base.json`, `tsconfig.json`, `eslint.config.js`,
35
+ `vitest.config.ts` (config **and** the testing approach itself, not just
36
+ its config shape), `package.json`'s TypeScript-toolchain entries, packaging
37
+ (`exports`, `check-exports.mjs`), and the toolchain steps in
38
+ `.github/workflows/*.yml`. An interview-derived emphasis (from
39
+ `/customize`'s kind-to-facet table) tells this skill which facet to research
40
+ **most deeply**, never which facets it may or may not touch. A facet with
41
+ low priority still gets swept; it just gets less dedicated attention per run.
42
+
43
+ ## Research mode
44
+
45
+ 1. **Scope the topic.** Read the topic from the invocation or the
46
+ surrounding task; at most **one** clarifying question, otherwise infer
47
+ and proceed. Derive **3–5 orthogonal facets** — one per Explore agent.
48
+ Derive a kebab-case slug for the optional Step 5 snapshot.
49
+ 2. **Fan out.** Read `references/typescript-sources.md` first, then spawn
50
+ **all agents in a single message**. Each brief carries: one facet; the
51
+ allowlist + GitHub caveat pasted verbatim; today's date; "do not stop at
52
+ the first matching source — fetch every distinct one"; "reject any
53
+ non-allowlisted domain outright and say so"; "you hold no write tool —
54
+ findings travel only in your response"; the findings format below; and a
55
+ ~8,000-character (~2,000-token) return cap. Always `subagent_type:
56
+ "Explore"`, breadth `"very thorough"`.
57
+
58
+ Findings format, one block per source:
59
+
60
+ ```
61
+ SOURCE: <URL>
62
+ TIER: T1 | T2
63
+ CLAIM: <the specific claim, quoted or tightly paraphrased>
64
+ CONFLICT-WITH: <another SOURCE, if this claim contradicts it — omit if none>
65
+ ```
66
+
67
+ 3. **Aggregate & synthesize.** Read every agent's full inline findings —
68
+ digests are for triage, not synthesis. Assign `S1, S2, …` deduping; merge
69
+ agreement into single consensus points tagged with all supporting ids;
70
+ flag contradictions. Precedence when two sources disagree: T1 outranks
71
+ T2; within T1, a devblog release post outranks the Handbook (the Handbook
72
+ lags a release); nodejs.org is co-normative for the runtime boundary — a
73
+ genuine Microsoft/Node disagreement must be surfaced, never silently
74
+ arbitrated.
75
+ 4. **Ask a clarifying question only if genuinely needed** — only when two
76
+ current, equally authoritative sources conflict in a way that changes the
77
+ invoking task.
78
+ 5. **Offer an optional snapshot.** Default is inline-only. On explicit
79
+ confirmation, write `docs/research/typescript/<topic-slug>.md`, assembled
80
+ from Step 2's findings + Step 3's synthesis (not re-fetched), with a `>
81
+ **Provenance** —` header naming today's date and the sources consulted.
82
+
83
+ ## Refresh mode
84
+
85
+ 1. **Read the tracker & establish anchors.** Read
86
+ `docs/research/typescript-refresh.md`, its header
87
+ `<!-- typescript-refresh: last-verified=<date> typescript-version=<version> -->`
88
+ — deliberately the newest **upstream** version last verified, distinct
89
+ from `package.json`'s own `typescript` pin, which this tracker exists to
90
+ check against, not restate. Missing tracker/facet → first run, `NEW`
91
+ only. Then read the allowlist file; state today's date; derive a run
92
+ directory `<scratchpad>/ts-refresh-<date>/`.
93
+ 2. **Build the delta.** `WebFetch` the devblog index and
94
+ `github.com/microsoft/TypeScript/releases`; extract entries newer than
95
+ the recorded version. An unreachable source is a coverage gap, not a
96
+ blocker. Pass this delta into all five briefs below — it is not a sixth
97
+ facet.
98
+ 3. **Fan out five fixed facets in one message** — fixed, not derived per
99
+ run, so sweeps stay comparable and the tracker stays diffable:
100
+
101
+ | Facet id | Emitted surface it validates |
102
+ | ---------------------------- | --------------------------------------------------------------------------------------- |
103
+ | `compiler-config-flags` | `tsconfig.base.json`, `tsconfig.json` |
104
+ | `modules-esm-node-interop` | `guard-js-extension.mjs`, `guard-no-commonjs.mjs`, the `import-x/extensions` rule |
105
+ | `packaging-declaration-emit` | `check-exports.mjs`, the `exports` map, `isolatedDeclarations` |
106
+ | `lint-typing-rules` | `eslint.config.js`'s preset composition |
107
+ | `testing-language-features` | `vitest.config.ts`, the coverage gate, the choice of runner and testing approach itself |
108
+
109
+ Each brief carries: the facet row, Step 2's delta, the tracker's prior
110
+ claims for that facet, the allowlist + GitHub caveat + date anchor, the
111
+ exact filename to write (`<run-dir>/<facet-id>.md`), and this verdict
112
+ format per claim:
113
+
114
+ ```
115
+ CLAIM: <the tracker's prior claim, or "NEW" if none existed>
116
+ VERDICT: UNCHANGED | CHANGED | GONE
117
+ NOW: <the current upstream position, with tier>
118
+ REPO-IMPACT: <which emitted file(s) this affects, or "none">
119
+ ```
120
+
121
+ Return value: **write the full file, return only a compact digest**
122
+ (counts per verdict + every non-"none" REPO-IMPACT line + the file path).
123
+
124
+ 4. **Aggregate.** Read every scratchpad file in full. Four buckets:
125
+ confirmed drift with repo impact (verify each against the cited file
126
+ itself before trusting it — an agent can misread a page), guidance
127
+ changes with no impact, dead/moved URLs, coverage gaps.
128
+ 5. **Update the tracker in place** (not a new dated file) — this skill's
129
+ only write outside plan mode. Bump the header date + version, update
130
+ every checked claim's text/URL/date, add `NEW` sources, update the
131
+ outstanding-drift table.
132
+ 6. **`EnterPlanMode`** with a remediation plan, one section per
133
+ confirmed-drift item. No drift → skip plan mode, report a clean sweep,
134
+ still update the tracker.
135
+
136
+ ## Why this exists, separately from "how is our config wired"
137
+
138
+ Research mode answers "what does upstream say about X." Nothing else in the
139
+ baseline asks the inverse — "is what's already configured still what
140
+ upstream recommends" — because every lint/typecheck/test gate is a closed
141
+ loop checking the repo against its own prior decisions. A stale pin one
142
+ major behind upstream passes every one of those gates cleanly; only a live
143
+ sweep against the actual upstream surfaces it.
@@ -0,0 +1,102 @@
1
+ # Upstream TypeScript sources — the allowlist
2
+
3
+ The single source list consulted by `typescript-guidance` in both modes.
4
+ Editing this file is the one edit site when the tiering changes.
5
+
6
+ ## Domain allowlist
7
+
8
+ Pass verbatim as `WebSearch`'s `allowed_domains`:
9
+
10
+ ```
11
+ typescriptlang.org, www.typescriptlang.org, devblogs.microsoft.com,
12
+ nodejs.org, typescript-eslint.io, arethetypeswrong.github.io, publint.dev
13
+ ```
14
+
15
+ Plus **the official docs of a tool the project's interview actually
16
+ selected** for testing/bundling (e.g. `vitest.dev`, a chosen bundler's
17
+ docs) — this is what gives the `testing-language-features` facet a source
18
+ family, since none of the domains above owns a test runner's own docs.
19
+
20
+ Two of the fixed domains are **path-scoped within an otherwise broader
21
+ domain**:
22
+
23
+ - `devblogs.microsoft.com` hosts every Microsoft product's blog. Only
24
+ `/typescript/` paths are in scope here.
25
+ - `nodejs.org` hosts the whole Node.js documentation site. Only `/api/`
26
+ paths — principally `/api/typescript.html` — are in scope here.
27
+
28
+ ## The two tiers
29
+
30
+ **T1 — owner-normative.** A claim from here can be cited as-is.
31
+
32
+ - `typescriptlang.org` — the Handbook, the tsconfig reference, the Modules
33
+ reference.
34
+ - `devblogs.microsoft.com/typescript` — release announcements, the
35
+ authoritative record of breaking changes.
36
+ - `github.com/microsoft/TypeScript` — releases, milestones, wiki Design
37
+ Notes.
38
+ - `nodejs.org/api/typescript.html` — co-normative T1 for the
39
+ Node↔TypeScript runtime boundary (type stripping, `erasableSyntaxOnly`).
40
+ A disagreement across that seam is a genuine two-owner conflict to
41
+ surface, not a T1-vs-T2 subordination to resolve silently.
42
+
43
+ **T2 — owner-adjacent / executable spec.** Citable, but state the scope
44
+ limit.
45
+
46
+ - `typescript-eslint.io` — rule semantics, and the exact composition of the
47
+ `recommendedTypeChecked`/`strictTypeChecked`/`stylisticTypeChecked`
48
+ presets.
49
+ - `arethetypeswrong.github.io` — packaging correctness rules (dual-format
50
+ resolution, `exports`-map type resolution failure modes).
51
+ - `publint.dev` — package-publishing correctness rules.
52
+ - The selected test/bundler tool's own docs — behavior and current
53
+ recommendation for that tool specifically.
54
+
55
+ **Explicitly out of scope.** Named here so an agent that finds one of these
56
+ drops it and says so, rather than quietly substituting it for missing T1/T2
57
+ coverage:
58
+
59
+ - `github.com/tsconfig/bases` — actively maintained ecosystem consensus,
60
+ but consensus, not the owner's word.
61
+ - Individual authors and their published material — no normative standing.
62
+
63
+ ## GitHub caveat
64
+
65
+ `allowed_domains` filters by domain, not path, so a bare `github.com`
66
+ allowance would let through any repo. Agents may include `github.com` and
67
+ `raw.githubusercontent.com` in their search domains, but must **only cite or
68
+ fetch URLs under `microsoft/TypeScript`, `microsoft/TypeScript-Website`, or
69
+ `arethetypeswrong/arethetypeswrong.github.io`** — and drop any other GitHub
70
+ result, however highly ranked.
71
+
72
+ ## First-class sources to enumerate directly
73
+
74
+ Search ranking is not exhaustive — a recent devblog post or an individual
75
+ tsconfig option page can rank poorly and simply not surface. Enumerate these
76
+ directly rather than relying on search alone:
77
+
78
+ - `https://devblogs.microsoft.com/typescript/` — the release-announcement
79
+ index; read as a **delta** from a known prior version in refresh mode.
80
+ - `https://github.com/microsoft/TypeScript/releases` — the machine-readable
81
+ version list; cross-check the devblog against it.
82
+ - `https://www.typescriptlang.org/tsconfig/` — the per-option compiler-flag
83
+ reference.
84
+ - `https://www.typescriptlang.org/docs/handbook/modules/reference.html` —
85
+ the Modules reference (`nodenext`/`bundler` resolution modes, ESM/CJS
86
+ interop).
87
+ - `https://nodejs.org/api/typescript.html` — Node's type-stripping page.
88
+ - `https://typescript-eslint.io/users/configs/` — preset composition.
89
+
90
+ ## Coverage discipline
91
+
92
+ Reject any non-allowlisted domain outright and say so in the report, rather
93
+ than substituting a community blog, an individual author's material, or a
94
+ Stack Overflow answer for missing T1/T2 coverage. If a facet turns up no
95
+ qualifying source, that is itself a reportable finding (a coverage gap), not
96
+ a reason to lower the bar.
97
+
98
+ ## Current-date anchor
99
+
100
+ Every agent brief must state today's date explicitly — a `retrieved <date>`
101
+ stamp otherwise depends on the spoke inferring the date itself, which is
102
+ unreliable.