@nurix/etna 0.17.1 → 0.18.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 (101) hide show
  1. package/README.md +19 -9
  2. package/bin/etna.js +56 -28
  3. package/data/harness-index.json +21 -6
  4. package/data/harnesses/code/CLAUDE.md +7 -18
  5. package/data/harnesses/code/agents/brainstorm.md +3 -3
  6. package/data/harnesses/code/agents/change-review.md +13 -10
  7. package/data/harnesses/code/agents/harness-manager.md +16 -16
  8. package/data/harnesses/code/agents/maintenance.md +10 -3
  9. package/data/harnesses/code/agents/performance-review.md +5 -0
  10. package/data/harnesses/code/harness.json +1 -1
  11. package/data/harnesses/code/rules/general.md +40 -36
  12. package/data/harnesses/code/skills/boundary/SKILL.md +15 -42
  13. package/data/harnesses/code/skills/boundary/references/boundary-taxonomy.md +366 -304
  14. package/data/harnesses/code/skills/brainstorm/README.md +9 -9
  15. package/data/harnesses/code/skills/brainstorm/SKILL.md +15 -15
  16. package/data/harnesses/code/skills/brainstorm/harvest.md +2 -2
  17. package/data/harnesses/code/skills/brainstorm/templates/backlog.md +2 -2
  18. package/data/harnesses/code/skills/brainstorm/templates/build.md +6 -6
  19. package/data/harnesses/code/skills/brainstorm/templates/decisions.md +3 -3
  20. package/data/harnesses/code/skills/brainstorm/templates/doctrine.md +2 -2
  21. package/data/harnesses/code/skills/brainstorm/templates/domain-model.md +2 -2
  22. package/data/harnesses/code/skills/brainstorm/templates/glossary.md +2 -1
  23. package/data/harnesses/code/skills/brainstorm/templates/non-goals.md +3 -7
  24. package/data/harnesses/code/skills/brainstorm/templates/questions.md +6 -5
  25. package/data/harnesses/code/skills/brainstorm/templates/state.md +1 -8
  26. package/data/harnesses/code/skills/brainstorm/templates/tech.md +6 -6
  27. package/data/harnesses/code/skills/brainstorm/templates/thesis.md +2 -2
  28. package/data/harnesses/code/skills/distiller/SKILL.md +48 -177
  29. package/data/harnesses/code/skills/distiller/references/docs-mode.md +116 -343
  30. package/data/harnesses/code/skills/distiller/references/method.md +37 -109
  31. package/data/harnesses/code/skills/documentation/SKILL.md +9 -6
  32. package/data/harnesses/code/skills/documentation/references/examples.md +30 -61
  33. package/data/harnesses/code/skills/documentation/references/style-guide.md +59 -62
  34. package/data/harnesses/code/skills/documentation/references/templates.md +25 -33
  35. package/data/harnesses/code/skills/workflow-mapper/SKILL.md +32 -11
  36. package/data/harnesses/code/skills/workflow-mapper/references/patterns.md +1 -1
  37. package/data/harnesses/code-fable/CLAUDE.md +12 -23
  38. package/data/harnesses/code-fable/agents/brainstorm.md +3 -3
  39. package/data/harnesses/code-fable/agents/change-review.md +13 -10
  40. package/data/harnesses/code-fable/agents/harness-manager.md +16 -16
  41. package/data/harnesses/code-fable/agents/maintenance.md +10 -3
  42. package/data/harnesses/code-fable/agents/performance-review.md +5 -0
  43. package/data/harnesses/code-fable/harness.json +1 -1
  44. package/data/harnesses/code-fable/rules/general.md +40 -36
  45. package/data/harnesses/code-fable/skills/boundary/SKILL.md +15 -42
  46. package/data/harnesses/code-fable/skills/boundary/references/boundary-taxonomy.md +366 -304
  47. package/data/harnesses/code-fable/skills/brainstorm/README.md +9 -9
  48. package/data/harnesses/code-fable/skills/brainstorm/SKILL.md +15 -15
  49. package/data/harnesses/code-fable/skills/brainstorm/harvest.md +2 -2
  50. package/data/harnesses/code-fable/skills/brainstorm/templates/backlog.md +2 -2
  51. package/data/harnesses/code-fable/skills/brainstorm/templates/build.md +6 -6
  52. package/data/harnesses/code-fable/skills/brainstorm/templates/decisions.md +3 -3
  53. package/data/harnesses/code-fable/skills/brainstorm/templates/doctrine.md +2 -2
  54. package/data/harnesses/code-fable/skills/brainstorm/templates/domain-model.md +2 -2
  55. package/data/harnesses/code-fable/skills/brainstorm/templates/glossary.md +2 -1
  56. package/data/harnesses/code-fable/skills/brainstorm/templates/non-goals.md +3 -7
  57. package/data/harnesses/code-fable/skills/brainstorm/templates/questions.md +6 -5
  58. package/data/harnesses/code-fable/skills/brainstorm/templates/state.md +1 -8
  59. package/data/harnesses/code-fable/skills/brainstorm/templates/tech.md +6 -6
  60. package/data/harnesses/code-fable/skills/brainstorm/templates/thesis.md +2 -2
  61. package/data/harnesses/code-fable/skills/distiller/SKILL.md +48 -177
  62. package/data/harnesses/code-fable/skills/distiller/references/docs-mode.md +116 -343
  63. package/data/harnesses/code-fable/skills/distiller/references/method.md +37 -109
  64. package/data/harnesses/code-fable/skills/documentation/SKILL.md +9 -6
  65. package/data/harnesses/code-fable/skills/documentation/references/examples.md +30 -61
  66. package/data/harnesses/code-fable/skills/documentation/references/style-guide.md +59 -62
  67. package/data/harnesses/code-fable/skills/documentation/references/templates.md +25 -33
  68. package/data/harnesses/code-fable/skills/workflow-mapper/SKILL.md +32 -11
  69. package/data/harnesses/code-fable/skills/workflow-mapper/references/patterns.md +1 -1
  70. package/data/harnesses/discover/CLAUDE.md +41 -109
  71. package/data/harnesses/discover/agents/api.md +11 -28
  72. package/data/harnesses/discover/agents/codebase.md +12 -30
  73. package/data/harnesses/discover/agents/community.md +9 -21
  74. package/data/harnesses/discover/agents/deployed-client-bundle.md +16 -67
  75. package/data/harnesses/discover/agents/distribution-artifacts.md +21 -59
  76. package/data/harnesses/discover/agents/docs.md +11 -20
  77. package/data/harnesses/discover/agents/infra-backend-fingerprint.md +28 -68
  78. package/data/harnesses/discover/agents/packages.md +12 -28
  79. package/data/harnesses/discover/agents/session.md +18 -50
  80. package/data/harnesses/discover/agents/website.md +9 -19
  81. package/data/harnesses/discover/agents/wire-capture.md +22 -72
  82. package/data/harnesses/discover/harness.json +1 -1
  83. package/data/harnesses/discover/rules/discovery.md +73 -182
  84. package/data/harnesses/discover/rules/evaluation.md +90 -98
  85. package/data/harnesses/discover/rules/ingestion.md +123 -322
  86. package/data/harnesses/discover/rules/self-correction.md +67 -92
  87. package/data/harnesses/discover/rules/tradecraft.md +201 -172
  88. package/data/harnesses/hr/CLAUDE.md +21 -51
  89. package/data/harnesses/hr/harness.json +1 -1
  90. package/data/harnesses/hr/skills/interview-eval/SKILL.md +23 -11
  91. package/data/harnesses/hr/skills/interview-eval/TEMPLATE.md +49 -29
  92. package/data/harnesses/hr/skills/interview-eval/rubric.md +30 -30
  93. package/data/harnesses/kb-agi/CLAUDE.md +8 -8
  94. package/data/harnesses/kb-agi/agents/kb-agi-init.md +31 -22
  95. package/data/harnesses/kb-agi/agents/kb-catch-stale.md +1 -1
  96. package/data/harnesses/kb-agi/agents/kb-find-gaps.md +1 -1
  97. package/data/harnesses/kb-agi/agents/kb-fix-links.md +1 -1
  98. package/data/harnesses/kb-agi/agents/kb-refresh-summaries.md +2 -2
  99. package/data/harnesses/kb-agi/agents/kb-sync-metadata.md +2 -2
  100. package/data/harnesses/kb-agi/harness.json +1 -1
  101. package/package.json +1 -1
@@ -1,14 +1,10 @@
1
1
  # Discovery Reference — Scope Gate · Access Vector · Dimension Catalog
2
2
 
3
- The reference knowledge for **Discovery** (`discover` harness, Mode 1). It carries all three of
4
- Discovery's steps in the order they run (preceded by corpus-root resolution, Step 00 below):
3
+ The reference knowledge for **Discovery** (`discover` harness, Mode 1). It carries all three of Discovery's steps in the order they run (preceded by corpus-root resolution, Step 00 below):
5
4
 
6
- - **Part A — Scope-feasibility gate** (Step 0): resolve the target's identity and emit a verdict
7
- so the run never wastes effort on an infeasible target.
8
- - **Part B — Access vector** (Step 1): grade the four-axis capability vector that decides which
9
- dimensions are reachable and which method each uses.
10
- - **Part C — Dimension catalog** (Step 2): the canonical list of dimensions, their detection
11
- signals, collection strategy, and owning agent.
5
+ - **Part A — Scope-feasibility gate** (Step 0): resolve the target's identity and emit a verdict so the run never wastes effort on an infeasible target.
6
+ - **Part B — Access vector** (Step 1): grade the four-axis capability vector that decides which dimensions are reachable and which method each uses.
7
+ - **Part C — Dimension catalog** (Step 2): the canonical list of dimensions, their detection signals, collection strategy, and owning agent.
12
8
 
13
9
  `ingestion` also reads **Part C** to dispatch the right agent with the right method.
14
10
 
@@ -23,70 +19,48 @@ Before Part A, decide **where this run writes** — the harness picks intelligen
23
19
  3. If none exists and the user hasn't named one, default to `research/` at the repo root.
24
20
  4. **Confirm the chosen root in one line** before writing `00-scope-verdict.md`.
25
21
 
26
- All `research/<target>/` paths in the harness are the *default form*, relative to the resolved `<corpus>/`.
22
+ All `research/<target>/` paths in the harness are the _default form_, relative to the resolved `<corpus>/`.
27
23
 
28
24
  ---
29
25
 
30
26
  # Part A — Scope-feasibility gate (Step 0)
31
27
 
32
- Run this **before** any dimension probing. It resolves the target's identity and emits one of four
33
- verdicts. The rules are mechanical — execute them with cheap probes (`WebSearch`, `curl`,
34
- `git ls-remote`, `npm view`) in well under a minute.
28
+ Run this **before** any dimension probing. It resolves the target's identity and emits one of four verdicts. The rules are mechanical — execute them with cheap probes (`WebSearch`, `curl`, `git ls-remote`, `npm view`) in well under a minute.
35
29
 
36
- Output: `research/<target>/00-scope-verdict.md` + a `scope:` block in `00-recon-plan.md`. If the
37
- verdict is not `accept`, Discovery **halts** (presents the narrowing prompt, or refuses) and does
38
- not proceed to dimension probing.
30
+ Output: `research/<target>/00-scope-verdict.md` + a `scope:` block in `00-recon-plan.md`. If the verdict is not `accept`, Discovery **halts** (presents the narrowing prompt, or refuses) and does not proceed to dimension probing.
39
31
 
40
32
  ## Verdicts
41
33
 
42
34
  | Verdict | Meaning | Downstream |
43
- |---------|---------|-----------|
35
+ | --- | --- | --- |
44
36
  | **accept** | bounded target with ≥1 real surface | continue to dimension probing |
45
37
  | **narrow** | too-broad-suite or ambiguous-name | present the narrowing prompt; halt for user reply |
46
38
  | **redirect** | a commodity primitive (behavior = its public spec) | offer a facet menu; halt for user reply |
47
39
  | **refuse** | ethically/legally out-of-bounds (hard stop only here) | stop; no run |
48
40
 
49
- A **no-reachable-surface** result is a **soft prompt** ("log in / give me a URL or repo"), not a
50
- hard refuse — only the ethics gate (Gate B) is a hard refuse.
41
+ A **no-reachable-surface** result is a **soft prompt** ("log in / give me a URL or repo"), not a hard refuse — only the ethics gate (Gate B) is a hard refuse.
51
42
 
52
43
  ## The decision algorithm (priority-ordered; first match wins)
53
44
 
54
- **0a — Resolve identity.** If the user gave a concrete URL/repo/package, identity is fixed → skip
55
- ambiguity. Else `WebSearch "<target>"` + `"<target> software"`; collect canonical homepage, vendor,
56
- one-line category.
45
+ **0a — Resolve identity.** If the user gave a concrete URL/repo/package, identity is fixed → skip ambiguity. Else `WebSearch "<target>"` + `"<target> software"`; collect canonical homepage, vendor, one-line category.
57
46
 
58
47
  **Gate A — ambiguity.** Top results map to ≥2 unrelated vendors/categories → `narrow` (disambiguate). STOP.
59
48
 
60
- **Gate B — ethics.** Resolved product is piracy/cracking/malware/CSAM/credential-harvesting/spyware,
61
- or the only way in is bypassing auth/paywall/TOS the user has no right to → `refuse` (ethics). STOP.
62
- *(Highest priority once identity is known — never proceed on an out-of-bounds target even if reachable.)*
63
-
64
- **Gate C — suite size.** Fetch homepage; count distinct independently-marketed products N (nav
65
- "Products" items each with their own `/pricing` or `/docs` tree; or a `WebSearch "<target> products"`
66
- grid). If N ≥ 4 **OR** the entity is on the umbrella seed list → `narrow` (pick-product). STOP.
67
- > Umbrella seed list: AWS, Azure, GCP, Salesforce, Microsoft 365, SAP, Oracle Cloud, Google
68
- > Workspace, Adobe Creative Cloud, Atlassian.
69
- > Guard against false positives: "one platform, many *modules* sharing one account/API/pricing page"
70
- > (Stripe: Payments/Billing/Connect) is **one product → accept**, not a suite. The N≥4 count alone
71
- > isn't enough — require separate pricing/docs trees, not just a broad nav.
72
-
73
- **Gate D — primitive.** Target is a single foundational building block whose behavior is a published
74
- spec with no hidden app surface (managed primitives like S3/EC2/Lambda; single-purpose util libs
75
- with <~5 exports; protocol/spec names; a raw DB engine) → `redirect` (pick-facet). STOP.
76
- > Bias: only `redirect` when behavior is fully a public spec. When a hosted SaaS wrapper exists
77
- > (Redis Cloud, MongoDB Atlas), prefer `accept` on the wrapper.
78
-
79
- **Gate E — reachability.** Run the cheapest probe per dimension as a boolean (does ANY surface
80
- exist?): `git ls-remote` OR npm/PyPI hit OR `llms.txt`/docs subdomain OR homepage-200-with-content
81
- OR user-has-session. If ZERO surfaces → **soft prompt** ("No reachable surface — log in, or give me
82
- a repo/docs/URL"). If exactly one thin non-session surface → `accept` (thin) with a shallow-coverage
83
- warning.
49
+ **Gate B — ethics.** Resolved product is piracy/cracking/malware/CSAM/credential-harvesting/spyware, or the only way in is bypassing auth/paywall/TOS the user has no right to → `refuse` (ethics). STOP. _(Highest priority once identity is known — never proceed on an out-of-bounds target even if reachable.)_
50
+
51
+ **Gate C — suite size.** Fetch homepage; count distinct independently-marketed products N (nav "Products" items each with their own `/pricing` or `/docs` tree; or a `WebSearch "<target> products"` grid). If N ≥ 4 **OR** the entity is on the umbrella seed list → `narrow` (pick-product). STOP.
52
+
53
+ > Umbrella seed list: AWS, Azure, GCP, Salesforce, Microsoft 365, SAP, Oracle Cloud, Google Workspace, Adobe Creative Cloud, Atlassian. Guard against false positives: "one platform, many _modules_ sharing one account/API/pricing page" (Stripe: Payments/Billing/Connect) is **one product → accept**, not a suite. The N≥4 count alone isn't enough — require separate pricing/docs trees, not just a broad nav.
54
+
55
+ **Gate D — primitive.** Target is a single foundational building block whose behavior is a published spec with no hidden app surface (managed primitives like S3/EC2/Lambda; single-purpose util libs with <~5 exports; protocol/spec names; a raw DB engine) → `redirect` (pick-facet). STOP.
56
+
57
+ > Bias: only `redirect` when behavior is fully a public spec. When a hosted SaaS wrapper exists (Redis Cloud, MongoDB Atlas), prefer `accept` on the wrapper.
58
+
59
+ **Gate E — reachability.** Run the cheapest probe per dimension as a boolean (does ANY surface exist?): `git ls-remote` OR npm/PyPI hit OR `llms.txt`/docs subdomain OR homepage-200-with-content OR user-has-session. If ZERO surfaces → **soft prompt** ("No reachable surface — log in, or give me a repo/docs/URL"). If exactly one thin non-session surface → `accept` (thin) with a shallow-coverage warning.
84
60
 
85
61
  **Fallthrough → `accept`.** Compute the access vector (Part B) and proceed to dimension probing.
86
62
 
87
- **Recursion:** a narrowed pick re-enters Step 0 (so "Salesforce → Marketing Cloud" is itself
88
- feasibility-checked and may narrow again). **Max narrow-depth = 2**, then accept-the-narrowest with
89
- a partial-coverage warning.
63
+ **Recursion:** a narrowed pick re-enters Step 0 (so "Salesforce → Marketing Cloud" is itself feasibility-checked and may narrow again). **Max narrow-depth = 2**, then accept-the-narrowest with a partial-coverage warning.
90
64
 
91
65
  ## `00-scope-verdict.md` shape
92
66
 
@@ -101,35 +75,34 @@ suite_product_count: <N>
101
75
  surfaces_present: [codebase?, docs?, api?, website?, session?]
102
76
  awaiting_user: <true|false>
103
77
  ---
78
+
104
79
  # <Target> — Scope Verdict: <VERDICT>
105
- ## Resolution (what the name resolved to + evidence)
106
- ## Gate trace (which gate fired A–E + the verbatim signal)
80
+
81
+ ## Resolution (what the name resolved to + evidence)
82
+
83
+ ## Gate trace (which gate fired A–E + the verbatim signal)
84
+
107
85
  ## Verdict & reason
108
- ## Narrowing prompt (if narrow/redirect — the exact question + options)
109
- ## If refused (one-line reason + what would make it acceptable)
86
+
87
+ ## Narrowing prompt (if narrow/redirect — the exact question + options)
88
+
89
+ ## If refused (one-line reason + what would make it acceptable)
110
90
  ```
91
+
111
92
  Mirror `verdict` into a `scope:` frontmatter block on `00-recon-plan.md` so ingestion reads one field.
112
93
 
113
94
  ## Narrowing prompt templates
114
95
 
115
- **NARROW-SUITE (Gate C):** "I can recon a focused product, but **<Target>** is a suite of ~<N>
116
- independently-built products — a single run would be shallow across all of them. Which one should I
117
- tear down?" + a numbered list auto-built from the homepage product nav, each tagged with its likely
118
- access-grade. Always append "0. A specific feature within one of these (tell me which)."
96
+ **NARROW-SUITE (Gate C):** "I can recon a focused product, but **<Target>** is a suite of ~<N> independently-built products — a single run would be shallow across all of them. Which one should I tear down?" + a numbered list auto-built from the homepage product nav, each tagged with its likely access-grade. Always append "0. A specific feature within one of these (tell me which)."
119
97
 
120
- **NARROW-DISAMBIGUATE (Gate A):** "**<Target>** resolves to more than one product. Which did you
121
- mean?" + numbered candidates (vendor · one-line · URL) + "none of these — give me a URL."
98
+ **NARROW-DISAMBIGUATE (Gate A):** "**<Target>** resolves to more than one product. Which did you mean?" + numbered candidates (vendor · one-line · URL) + "none of these — give me a URL."
122
99
 
123
- **REDIRECT-PRIMITIVE (Gate D):** "**<Target>** is a documented primitive, not a product with hidden
124
- internals — its behavior is the public spec. I can still recon a facet. Which angle?" + a facet menu
125
- (for a managed service: console/dashboard UX · public API surface · consistency/semantics model ·
126
- pricing & limits as a product · competitive positioning) + "Or point me at a real product that USES
127
- <Target> and I'll recon that instead."
100
+ **REDIRECT-PRIMITIVE (Gate D):** "**<Target>** is a documented primitive, not a product with hidden internals — its behavior is the public spec. I can still recon a facet. Which angle?" + a facet menu (for a managed service: console/dashboard UX · public API surface · consistency/semantics model · pricing & limits as a product · competitive positioning) + "Or point me at a real product that USES <Target> and I'll recon that instead."
128
101
 
129
102
  ## Worked verdicts (regression fixtures)
130
103
 
131
104
  | Target | Gate | Verdict | Note |
132
- |--------|------|---------|------|
105
+ | --- | --- | --- | --- |
133
106
  | AWS S3 | D | redirect (primitive) | "behavior is the public API; pick a facet or a product built on S3" |
134
107
  | Salesforce | C | narrow (suite) | "pick a cloud: Sales / Service / Marketing / Flow Builder / Apex / …" |
135
108
  | Microsoft 365 | C | narrow (suite) | umbrella seed list; options Word/Excel/Teams/… each tagged |
@@ -144,41 +117,32 @@ pricing & limits as a product · competitive positioning) + "Or point me at a re
144
117
 
145
118
  # Part B — Access is a capability VECTOR (Step 1)
146
119
 
147
- A target's "access" is **four orthogonal axes**, each carrying `{value, confidence, evidence}`.
148
- The vector — not a single grade — decides which dimensions are reachable and which extraction
149
- *method* each uses.
120
+ A target's "access" is **four orthogonal axes**, each carrying `{value, confidence, evidence}`. The vector — not a single grade — decides which dimensions are reachable and which extraction _method_ each uses.
150
121
 
151
122
  | Axis | Values | Unlocks dimensions | Anchors |
152
- |------|--------|--------------------|---------|
153
- | **source** | full · partial · none | codebase, packages | *Case 1* (full = OSS repo) |
154
- | **runtime** | reachable · gated · none | deployed-client-bundle, api, infra-backend-fingerprint, wire-capture | *Case 2* (reachable + source:none) |
155
- | **auth** | have-login · none | session | *Case 3* (have-login) |
123
+ | --- | --- | --- | --- |
124
+ | **source** | full · partial · none | codebase, packages | _Case 1_ (full = OSS repo) |
125
+ | **runtime** | reachable · gated · none | deployed-client-bundle, api, infra-backend-fingerprint, wire-capture | _Case 2_ (reachable + source:none) |
126
+ | **auth** | have-login · none | session | _Case 3_ (have-login) |
156
127
  | **presence** | rich · thin · none | docs, website, community | (almost always rich) |
157
128
 
158
- The three named **cases** are presets over this vector — a target can light several at once
159
- (Liveblocks = source:full + runtime:reachable + auth:obtainable + presence:rich → nearly all
160
- dimensions). Rules:
161
- - **`auth:obtainable` is a hint, not actionable** — the harness never self-signs-up; it only counts as `have-login` if the *user* hands over a session.
162
- - **A *claimed* login is `auth:claimed` (confidence medium), not `auth:have-login` (high), until a cheap live probe confirms it.** A user saying "I'm logged in" — or a session being merely *expected* — is not proof: profiles expire, a fresh tab may not restore an in-memory token, and a deep-link can bounce to a login wall while the root looks authed. Grade `auth:claimed` until Discovery (or the `session` agent's first step) navigates the app and confirms an **authenticated surface** (a dashboard, a populated `viewer`/`/me`, a token in the store) — only then promote to `have-login`. Grading a claimed login `high` lets a session collapse to `blocked` after dispatch, with the wasted dispatch hidden behind a confident grade.
129
+ The three named **cases** are presets over this vector — a target can light several at once (Liveblocks = source:full + runtime:reachable + auth:obtainable + presence:rich → nearly all dimensions). Rules:
130
+
131
+ - **`auth:obtainable` is a hint, not actionable** — the harness never self-signs-up; it only counts as `have-login` if the _user_ hands over a session.
132
+ - **A _claimed_ login is `auth:claimed` (confidence medium), not `auth:have-login` (high), until a cheap live probe confirms it.** A user saying "I'm logged in" — or a session being merely _expected_ — is not proof: profiles expire, a fresh tab may not restore an in-memory token, and a deep-link can bounce to a login wall while the root looks authed. Grade `auth:claimed` until Discovery (or the `session` agent's first step) navigates the app and confirms an **authenticated surface** (a dashboard, a populated `viewer`/`/me`, a token in the store) — only then promote to `have-login`. Grading a claimed login `high` lets a session collapse to `blocked` after dispatch, with the wasted dispatch hidden behind a confident grade.
163
133
  - **Dimension-level access overrides the target headline** for method selection (a Case-1 target can still have a Case-3 session dimension).
164
- - Method swaps on axis *value*: `source:full` ⇒ `clone-and-map`; `source:partial` ⇒ `source-map-reassembly`; `runtime:reachable + source:none` ⇒ `bundle-string-mine` + wire-capture.
134
+ - Method swaps on axis _value_: `source:full` ⇒ `clone-and-map`; `source:partial` ⇒ `source-map-reassembly`; `runtime:reachable + source:none` ⇒ `bundle-string-mine` + wire-capture.
165
135
 
166
136
  Discovery records the resolved vector in the `access_grade` frontmatter of `00-recon-plan.md`.
167
137
 
168
- > **Hypotheses are not facts (seed them tagged, never echo them).** Any *derived inference* Discovery
169
- > makes beyond the four graded axes — e.g. "this `localStorage` key implies a GraphQL backend", "this
170
- > host is the realtime endpoint" — is recorded in `00-recon-plan.md` **as a labelled hypothesis**, never
171
- > as a plan fact, and is tagged `verify:may-be-stale` when seeded to a collector (CLAUDE.md Mode 2) so
172
- > Ingestion **re-derives** rather than echoes it. A wrong inference seeded as framing propagates: a real
173
- > run's `apolloAnonId ⇒ GraphQL` guess was repeated (hedged) by two captures before the `session` dimension
174
- > refuted it (the backend was RSC + Server Actions; the key was an Apollo.io tracker).
138
+ > **Hypotheses are not facts (seed them tagged, never echo them).** Any _derived inference_ Discovery makes beyond the four graded axes — e.g. "this `localStorage` key implies a GraphQL backend", "this host is the realtime endpoint" — is recorded in `00-recon-plan.md` **as a labelled hypothesis**, never as a plan fact, and is tagged `verify:may-be-stale` when seeded to a collector (CLAUDE.md Mode 2) so Ingestion **re-derives** rather than echoes it. A wrong inference seeded as framing propagates: a real run's `apolloAnonId ⇒ GraphQL` guess was repeated (hedged) by two captures before the `session` dimension refuted it (the backend was RSC + Server Actions; the key was an Apollo.io tracker).
175
139
 
176
140
  ---
177
141
 
178
142
  # Part C — The dimension catalog (Step 2)
179
143
 
180
144
  | # | Dimension | Agent | Unlocking axis | One-line strategy |
181
- |---|-----------|-------|----------------|-------------------|
145
+ | --- | --- | --- | --- | --- |
182
146
  | 1 | **codebase** | `codebase` | source:full | clone → structural map → per-package fan-out |
183
147
  | 2 | **docs** | `docs` | presence | `llms.txt` → else crawl/clip → organize by section |
184
148
  | 3 | **packages** | `packages` | source/presence | registry metadata + exports + type defs |
@@ -191,80 +155,32 @@ Discovery records the resolved vector in the `access_grade` frontmatter of `00-r
191
155
  | 10 | **wire-capture** | `wire-capture` | runtime (source:none) | the 3-rung ladder for non-browser/no-source clients (gated) |
192
156
  | 11 | **distribution-artifacts** | `distribution-artifacts` | runtime (non-web client) | extension CRX / Electron `.asar` / mobile binary / CLI |
193
157
 
194
- > **Deferred (available on request, not built):** `external-reputation` (G2/Reddit/HN — the only
195
- > "what others say" surface) and `hiring-intel` (job posts leak the backend stack). Strong
196
- > candidates, declined for this iteration. Re-add via self-correction if a run needs them.
197
- > **Conditional trigger:** when `community` returns **no first-party feedback loop** (no public
198
- > issues/roadmap/changelog/forum — feedback funnelled to a gated channel), flag `external-reputation`
199
- > as **recommended-for-this-run** in `00-recon-plan.md`, so the user-sentiment blind spot is a surfaced
200
- > choice rather than a silent gap (the `community` user-pain claims are then capped at tentative —
201
- > evaluation closed-feedback cap).
158
+ > **Deferred (available on request, not built):** `external-reputation` (G2/Reddit/HN — the only "what others say" surface) and `hiring-intel` (job posts leak the backend stack). Strong candidates, declined for this iteration. Re-add via self-correction if a run needs them. **Conditional trigger:** when `community` returns **no first-party feedback loop** (no public issues/roadmap/changelog/forum — feedback funnelled to a gated channel), flag `external-reputation` as **recommended-for-this-run** in `00-recon-plan.md`, so the user-sentiment blind spot is a surfaced choice rather than a silent gap (the `community` user-pain claims are then capped at tentative — evaluation closed-feedback cap).
202
159
 
203
160
  An **absent** dimension is a finding — record it with its evidence; never silently drop it.
204
161
 
205
162
  ## 1–7 — the core dimensions (strategy in brief)
206
163
 
207
164
  See git history / the source playbook for the full strategy text; in brief:
208
- - **codebase** — shallow-clone into `source/<target>/`, read orientation files + manifests, map
209
- packages + internal dep hierarchy, return a per-package work-list for the main-session fan-out.
165
+
166
+ - **codebase** — shallow-clone into `source/<target>/`, read orientation files + manifests, map packages + internal dep hierarchy, return a per-package work-list for the main-session fan-out.
210
167
  - **docs** — prefer in-repo docs, then `llms.txt`/`llms-full.txt`, then crawl; organize by section.
211
- - **packages** — per public package: registry metadata, `exports` map + `.d.ts` type surface, health.
212
- **Registry-ownership cheap-test (grade ownership before calling an SDK "partial/unverified").** Read
213
- the registry `author`/`maintainers`/`summary`/`project_urls`/`Homepage` fields and check the
214
- dependency set for a generator fingerprint (Stainless: `httpx`/`pydantic`/`anyio`/`distro`/`sniffio`
215
- + in-file "generated by Stainless" headers; Speakeasy; OpenAPI-Generator). An `author`/`summary` that
216
- says "official … library for the X API" + a vendor-domain `project_urls` confirms **official**
217
- ownership at **high** confidence even when the *source* repo is private — the published tarball IS the
218
- public-API mirror (a high-confidence `registry-metadata` anchor), so it is **not** "partial." Tag a
219
- genuinely third-party/community package (different author/scope) as such, but don't down-grade an
220
- official-but-private-source SDK to "unverified."
221
- - **api** — fetch the spec verbatim, build an endpoint catalog (auth, envelope, pagination, webhooks).
222
- **Grade the method from a RETRIEVED artifact, never a label.** Before grading `openapi-verbatim`,
223
- actually fetch the candidate spec URL and confirm a **parseable JSON/YAML body** — a docs page merely
224
- *titled* "OpenAPI" with no served `spec.json` (or a `/swagger` that 403s) is `docs-reconstructed`
225
- (capped medium), and Discovery must pre-grade it that way so the plan matches reality. **A
226
- sibling-declared host/op/route count is a coverage checklist (a floor), never a ceiling** — every
227
- collector expands from sibling-mined hosts/routes and records the predicted-vs-found delta.
228
- **NEW fold-in:** also probe MCP/tool surfaces — `/.well-known/mcp`, an MCP server manifest, a
229
- function-calling tool schema, an LLM "actions" file — and write `raw/tool-catalog.md` (an MCP tool
230
- list *is* an API catalog; it lives here, not in its own dimension). **Unauth MCP-probe recipe (when
231
- the tool catalog itself is auth-gated):** a `GET /mcp` → `405` body often names the transport
232
- (e.g. "stateless; only POST is supported" = streamable-HTTP); `GET /sse` presence/absence tells
233
- legacy-SSE vs streamable; and `/.well-known/oauth-authorization-server` + `/.well-known/oauth-protected-resource/{name}`
234
- reveal the **OAuth/PKCE model + issuer** (e.g. a `jwks_uri` on the auth vendor names Clerk/Auth0/etc.)
235
- — all without a token. Capture transport + auth + issuer from these, reconstruct the tool list from
236
- docs/SDK, and mark the verbatim `tools/list` **partial** (OAuth-gated).
237
- - **website** — crawl home/features/pricing/customers/integrations; extract positioning, pricing
238
- matrix, target market.
239
- - **community** — *first-party only*: changelog cadence + direction, issue/discussion themes, blog.
240
- - **session** — the deepest, opt-in, user-gated dimension; delegates to the session playbook in
241
- `ingestion` §9 (3-pass, P0–P6, captures/raw/curls). For any `auth:have-login`/`auth:claimed`
242
- target, Discovery **seeds the Pass-2 decision** (`pass2: offered-pending | declined-by-user |
243
- deferred`) into `00-recon-plan.md`, so a Pass-1-only (read-only) session is a *recorded choice*, not a
244
- silent omission of the write surface (ingestion §9.2).
168
+ - **packages** — per public package: registry metadata, `exports` map + `.d.ts` type surface, health. **Registry-ownership cheap-test (grade ownership before calling an SDK "partial/unverified").** Read the registry `author`/`maintainers`/`summary`/`project_urls`/`Homepage` fields and check the dependency set for a generator fingerprint (Stainless: `httpx`/`pydantic`/`anyio`/`distro`/`sniffio`
169
+ - in-file "generated by Stainless" headers; Speakeasy; OpenAPI-Generator). An `author`/`summary` that says "official … library for the X API" + a vendor-domain `project_urls` confirms **official** ownership at **high** confidence even when the _source_ repo is private — the published tarball IS the public-API mirror (a high-confidence `registry-metadata` anchor), so it is **not** "partial." Tag a genuinely third-party/community package (different author/scope) as such, but don't down-grade an official-but-private-source SDK to "unverified."
170
+ - **api** — fetch the spec verbatim, build an endpoint catalog (auth, envelope, pagination, webhooks). **Grade the method from a RETRIEVED artifact, never a label.** Before grading `openapi-verbatim`, actually fetch the candidate spec URL and confirm a **parseable JSON/YAML body** — a docs page merely _titled_ "OpenAPI" with no served `spec.json` (or a `/swagger` that 403s) is `docs-reconstructed` (capped medium), and Discovery must pre-grade it that way so the plan matches reality. **A sibling-declared host/op/route count is a coverage checklist (a floor), never a ceiling** — every collector expands from sibling-mined hosts/routes and records the predicted-vs-found delta. **NEW fold-in:** also probe MCP/tool surfaces — `/.well-known/mcp`, an MCP server manifest, a function-calling tool schema, an LLM "actions" file — and write `raw/tool-catalog.md` (an MCP tool list _is_ an API catalog; it lives here, not in its own dimension). **Unauth MCP-probe recipe (when the tool catalog itself is auth-gated):** a `GET /mcp` → `405` body often names the transport (e.g. "stateless; only POST is supported" = streamable-HTTP); `GET /sse` presence/absence tells legacy-SSE vs streamable; and `/.well-known/oauth-authorization-server` + `/.well-known/oauth-protected-resource/{name}` reveal the **OAuth/PKCE model + issuer** (e.g. a `jwks_uri` on the auth vendor names Clerk/Auth0/etc.) — all without a token. Capture transport + auth + issuer from these, reconstruct the tool list from docs/SDK, and mark the verbatim `tools/list` **partial** (OAuth-gated).
171
+ - **website** — crawl home/features/pricing/customers/integrations; extract positioning, pricing matrix, target market.
172
+ - **community** — _first-party only_: changelog cadence + direction, issue/discussion themes, blog.
173
+ - **session** — the deepest, opt-in, user-gated dimension; delegates to the session playbook in `ingestion` §9 (3-pass, P0–P6, captures/raw/curls). For any `auth:have-login`/`auth:claimed` target, Discovery **seeds the Pass-2 decision** (`pass2: offered-pending | declined-by-user | deferred`) into `00-recon-plan.md`, so a Pass-1-only (read-only) session is a _recorded choice_, not a silent omission of the write surface (ingestion §9.2).
245
174
 
246
175
  ## 8 — deployed-client-bundle — `deployed-client-bundle`
247
176
 
248
- **Unlocked by:** `runtime:reachable`. The **unauthenticated app shell** — distinct from `website`
249
- (marketing) and `session` (authenticated). Works on closed SaaS with no repo and no login.
177
+ **Unlocked by:** `runtime:reachable`. The **unauthenticated app shell** — distinct from `website` (marketing) and `session` (authenticated). Works on closed SaaS with no repo and no login.
250
178
 
251
- **Detection:** an app subdomain (`app.<target>.*`) or SPA route serves a JS bundle;
252
- `sourceMappingURL` present; a `/assets/*.js` graph. **Two cheap Discovery probes pre-grade the method
253
- and surface a leak early:** (a) does an entry chunk's `sourceMappingURL` resolve to a `.map`-200? →
254
- pre-grade `source-map-reassembly` (confidence high — original `src/` recovers). (b) probe a few
255
- bootstrap-config paths (`/config`, `/backend/config/*`, `/env.json`, a runtime-config endpoint) — a
256
- 200 here is both a method pre-grade and a possible unauth config/secret leak (a finding).
179
+ **Detection:** an app subdomain (`app.<target>.*`) or SPA route serves a JS bundle; `sourceMappingURL` present; a `/assets/*.js` graph. **Two cheap Discovery probes pre-grade the method and surface a leak early:** (a) does an entry chunk's `sourceMappingURL` resolve to a `.map`-200? → pre-grade `source-map-reassembly` (confidence high — original `src/` recovers). (b) probe a few bootstrap-config paths (`/config`, `/backend/config/*`, `/env.json`, a runtime-config endpoint) — a 200 here is both a method pre-grade and a possible unauth config/secret leak (a finding).
257
180
 
258
- **Strategy:** fetch the main bundle(s); string-mine the **route table**, the **API-path catalog**
259
- (→ append to the shared `dimensions/_shared/api-path-catalog.md`, `source: bundle` — ingestion §6),
260
- **feature flags** (→ shared `dimensions/_shared/feature-flags.md`), embedded **env config** (`VITE_*`,
261
- `NEXT_PUBLIC_*`, public keys — field-names only, redact values), and reassemble **source maps** if
262
- shipped (`method: source-map-reassembly`, confidence high). Digest huge bundles, don't paste. This
263
- dimension **owns** the app-API bundle mine — other dimensions cite its catalog by path, never re-mine
264
- the same bundle (ingestion §6).
181
+ **Strategy:** fetch the main bundle(s); string-mine the **route table**, the **API-path catalog** (→ append to the shared `dimensions/_shared/api-path-catalog.md`, `source: bundle` — ingestion §6), **feature flags** (→ shared `dimensions/_shared/feature-flags.md`), embedded **env config** (`VITE_*`, `NEXT_PUBLIC_*`, public keys — field-names only, redact values), and reassemble **source maps** if shipped (`method: source-map-reassembly`, confidence high). Digest huge bundles, don't paste. This dimension **owns** the app-API bundle mine — other dimensions cite its catalog by path, never re-mine the same bundle (ingestion §6).
265
182
 
266
- **Artifacts:** `_summary.md` + `raw/{route-table.md, env-config.md, bundle-map.md}` + appends to the
267
- shared `dimensions/_shared/{api-path-catalog.md, feature-flags.md}`.
183
+ **Artifacts:** `_summary.md` + `raw/{route-table.md, env-config.md, bundle-map.md}` + appends to the shared `dimensions/_shared/{api-path-catalog.md, feature-flags.md}`.
268
184
 
269
185
  ## 9 — infra-backend-fingerprint — `infra-backend-fingerprint`
270
186
 
@@ -272,55 +188,34 @@ shared `dimensions/_shared/{api-path-catalog.md, feature-flags.md}`.
272
188
 
273
189
  **Detection:** always attemptable for any live domain.
274
190
 
275
- **Strategy:** DNS records; **cert-transparency subdomain enumeration** (crt.sh → staging/internal/
276
- api hosts); CDN/cloud fingerprint (CNAMEs, IP/ASN, response headers); security headers; tech
277
- fingerprint (framework/analytics tells). **Sub-processor fold-in:** fetch the `/legal`, `/trust`,
278
- `/security`, `/dpa` pages → `raw/sub-processors.md` — the sub-processor list **names the vendor
279
- stack** (cloud, payments, AI provider, email, telephony), which is exactly this dimension's job.
191
+ **Strategy:** DNS records; **cert-transparency subdomain enumeration** (crt.sh → staging/internal/ api hosts); CDN/cloud fingerprint (CNAMEs, IP/ASN, response headers); security headers; tech fingerprint (framework/analytics tells). **Sub-processor fold-in:** fetch the `/legal`, `/trust`, `/security`, `/dpa` pages → `raw/sub-processors.md` — the sub-processor list **names the vendor stack** (cloud, payments, AI provider, email, telephony), which is exactly this dimension's job.
280
192
 
281
193
  **Artifacts:** `_summary.md` + `raw/{dns-and-subdomains.md, cloud-cdn-fingerprint.md, security-headers.md, sub-processors.md}`.
282
194
 
283
195
  ## 10 — wire-capture — `wire-capture` (first-class, GATED)
284
196
 
285
- **Unlocked by:** `runtime` when the interesting client is **non-browser** or there's **no source**
286
- (your Case 2). The runtime-evidence complement to `distribution-artifacts` (static): the binary says
287
- what hosts it *might* call; the capture says what it *actually* calls.
197
+ **Unlocked by:** `runtime` when the interesting client is **non-browser** or there's **no source** (your Case 2). The runtime-evidence complement to `distribution-artifacts` (static): the binary says what hosts it _might_ call; the capture says what it _actually_ calls.
288
198
 
289
- **Detection:** a non-browser client exists (from distribution-artifacts) OR an unauth SPA makes
290
- structured XHRs worth a tap, AND the appropriate ethics rung is authorized.
199
+ **Detection:** a non-browser client exists (from distribution-artifacts) OR an unauth SPA makes structured XHRs worth a tap, AND the appropriate ethics rung is authorized.
291
200
 
292
201
  **Strategy:** the **3-rung ladder** (lowest privilege first) — see `ingestion` §7.1:
202
+
293
203
  1. browser network tap (unauth, default) → `wire-tap-browser`;
294
204
  2. HAR export → `wire-har`;
295
205
  3. mitmproxy (**gated, opt-in, user-run, first-party traffic only**) → `wire-mitmproxy`;
296
- 4. **first-party SDK-harness** (when the product publishes an official SDK + the *user* can provision keys) — scaffold + instrument a throw-away client you own (`document_start` taps, full wire) → `sdk-harness` (`ingestion` §7.1). The deepest lane for a `runtime:reachable + source:none` product whose SDK is the only public mirror of the runtime; gated like rung 3.
206
+ 4. **first-party SDK-harness** (when the product publishes an official SDK + the _user_ can provision keys) — scaffold + instrument a throw-away client you own (`document_start` taps, full wire) → `sdk-harness` (`ingestion` §7.1). The deepest lane for a `runtime:reachable + source:none` product whose SDK is the only public mirror of the runtime; gated like rung 3.
297
207
 
298
- **Fold note (common path):** when there is no separate non-browser client, wire-capture **folds into
299
- `session`** (which owns the browser singleton), **never into a curl/WebFetch collector** (a non-browser
300
- collector cannot run rung-1's in-page tap, and routing it there yields zero `source: wire` rows —
301
- ingestion §7.1). The folded rung-1 *is* the interceptor `session` installs; its observed paths
302
- append to the shared `dimensions/_shared/api-path-catalog.md` as `source: wire`. A folded wire-capture
303
- still leaves a one-paragraph `_summary.md` (`status: folded`, naming the fold target) — never a silent
304
- drop.
208
+ **Fold note (common path):** when there is no separate non-browser client, wire-capture **folds into `session`** (which owns the browser singleton), **never into a curl/WebFetch collector** (a non-browser collector cannot run rung-1's in-page tap, and routing it there yields zero `source: wire` rows — ingestion §7.1). The folded rung-1 _is_ the interceptor `session` installs; its observed paths append to the shared `dimensions/_shared/api-path-catalog.md` as `source: wire`. A folded wire-capture still leaves a one-paragraph `_summary.md` (`status: folded`, naming the fold target) — never a silent drop.
305
209
 
306
- **Artifacts:** `_summary.md` + `captures/wire-narrative.md` + `raw/flows.json (redacted/digested)` +
307
- appends to shared `dimensions/_shared/api-path-catalog.md (source: wire)` + `curls.md`. Record the
308
- chosen rung + authorization in `_meta`.
210
+ **Artifacts:** `_summary.md` + `captures/wire-narrative.md` + `raw/flows.json (redacted/digested)` + appends to shared `dimensions/_shared/api-path-catalog.md (source: wire)` + `curls.md`. Record the chosen rung + authorization in `_meta`.
309
211
 
310
212
  ## 11 — distribution-artifacts — `distribution-artifacts`
311
213
 
312
- **Unlocked by:** `runtime` (a downloadable non-web client). Often the closest thing to source for a
313
- closed product.
214
+ **Unlocked by:** `runtime` (a downloadable non-web client). Often the closest thing to source for a closed product.
314
215
 
315
- **Detection:** a Chrome/Firefox web-store listing; a "Download for Mac/Windows" (Electron/Tauri)
316
- button; an App Store / Play Store listing; a published CLI (`npm i -g`, brew, GitHub releases).
216
+ **Detection:** a Chrome/Firefox web-store listing; a "Download for Mac/Windows" (Electron/Tauri) button; an App Store / Play Store listing; a published CLI (`npm i -g`, brew, GitHub releases).
317
217
 
318
- **Strategy:** **extension** — decode `manifest.json` (permissions/hosts/content-scripts = a
319
- capability map). **Electron** — `npx asar extract app.asar` → map JS modules + the shared
320
- route/API/flag catalog from the desktop client (often richer than web). **mobile** — `Info.plist`/
321
- `AndroidManifest` hosts, ATS exceptions, embedded-SDK list from strings (**redact any embedded
322
- keys**). **CLI** — help text/subcommands = an API catalog. Read the artifact's EULA first (see
323
- `ingestion` §7.2); never silently decompile a restrictively-licensed binary.
218
+ **Strategy:** **extension** — decode `manifest.json` (permissions/hosts/content-scripts = a capability map). **Electron** — `npx asar extract app.asar` → map JS modules + the shared route/API/flag catalog from the desktop client (often richer than web). **mobile** — `Info.plist`/ `AndroidManifest` hosts, ATS exceptions, embedded-SDK list from strings (**redact any embedded keys**). **CLI** — help text/subcommands = an API catalog. Read the artifact's EULA first (see `ingestion` §7.2); never silently decompile a restrictively-licensed binary.
324
219
 
325
220
  **Artifacts:** `_summary.md` + `raw/{extension-manifest.md, electron-asar-map.md, mobile-strings.md, cli-catalog.md}` (whichever apply) + appends to shared `dimensions/_shared/api-path-catalog.md` (source: distribution).
326
221
 
@@ -328,8 +223,4 @@ keys**). **CLI** — help text/subcommands = an API catalog. Read the artifact's
328
223
 
329
224
  ## How Discovery uses this reference
330
225
 
331
- Step 0 — run **Part A** (the gate); halt unless `accept`. Step 1 — grade the **Part B** vector with
332
- evidence. Step 2 — for each dimension in **Part C**, check its unlocking axis against the resolved
333
- vector, run the cheap detection probe, and record **available / partial / absent** with evidence
334
- into `00-recon-plan.md`. Gated dimensions (session, wire-capture rung 3) are flagged for user
335
- confirmation before ingestion dispatches them.
226
+ Step 0 — run **Part A** (the gate); halt unless `accept`. Step 1 — grade the **Part B** vector with evidence. Step 2 — for each dimension in **Part C**, check its unlocking axis against the resolved vector, run the cheap detection probe, and record **available / partial / absent** with evidence into `00-recon-plan.md`. Gated dimensions (session, wire-capture rung 3) are flagged for user confirmation before ingestion dispatches them.