@nurix/etna 0.15.1 → 0.15.3

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 (45) hide show
  1. package/README.md +16 -13
  2. package/bin/etna.js +8 -20
  3. package/data/harness-index.json +2 -1
  4. package/data/harnesses/code/CLAUDE.md +1 -15
  5. package/data/harnesses/code/agents/brainstorm.md +0 -1
  6. package/data/harnesses/code/agents/change-review.md +0 -1
  7. package/data/harnesses/code/agents/harness-manager.md +0 -1
  8. package/data/harnesses/code/agents/maintenance.md +0 -1
  9. package/data/harnesses/code/agents/performance-review.md +0 -1
  10. package/data/harnesses/code/agents/spec-mode.md +0 -1
  11. package/data/harnesses/code/harness.json +2 -2
  12. package/data/harnesses/code/rules/general.md +0 -1
  13. package/data/harnesses/code/rules/nomenclature.md +0 -1
  14. package/data/harnesses/code/skills/boundary/SKILL.md +0 -1
  15. package/data/harnesses/code/skills/brainstorm/SKILL.md +0 -1
  16. package/data/harnesses/code/skills/distiller/SKILL.md +9 -6
  17. package/data/harnesses/code/skills/documentation/SKILL.md +0 -1
  18. package/data/harnesses/code/skills/workflow-mapper/SKILL.md +0 -1
  19. package/data/harnesses/kb-agi/CLAUDE.md +0 -15
  20. package/data/harnesses/kb-agi/agents/kb-agi-init.md +0 -1
  21. package/data/harnesses/kb-agi/agents/kb-catch-stale.md +0 -1
  22. package/data/harnesses/kb-agi/agents/kb-find-gaps.md +0 -1
  23. package/data/harnesses/kb-agi/agents/kb-fix-links.md +0 -1
  24. package/data/harnesses/kb-agi/agents/kb-refresh-frontdoor.md +0 -1
  25. package/data/harnesses/kb-agi/agents/kb-refresh-summaries.md +0 -1
  26. package/data/harnesses/kb-agi/agents/kb-sync-metadata.md +0 -1
  27. package/data/harnesses/kb-agi/harness.json +1 -1
  28. package/data/harnesses/kb-agi/rules/kb.md +0 -4
  29. package/data/harnesses/re/CLAUDE.md +139 -0
  30. package/data/harnesses/re/agents/api.md +52 -0
  31. package/data/harnesses/re/agents/codebase.md +63 -0
  32. package/data/harnesses/re/agents/community.md +47 -0
  33. package/data/harnesses/re/agents/deployed-client-bundle.md +94 -0
  34. package/data/harnesses/re/agents/distribution-artifacts.md +97 -0
  35. package/data/harnesses/re/agents/docs.md +49 -0
  36. package/data/harnesses/re/agents/infra-backend-fingerprint.md +97 -0
  37. package/data/harnesses/re/agents/packages.md +48 -0
  38. package/data/harnesses/re/agents/session.md +55 -0
  39. package/data/harnesses/re/agents/website.md +50 -0
  40. package/data/harnesses/re/agents/wire-capture.md +91 -0
  41. package/data/harnesses/re/harness.json +6 -0
  42. package/data/harnesses/re/rules/re-discovery.md +266 -0
  43. package/data/harnesses/re/rules/re-evaluation.md +100 -0
  44. package/data/harnesses/re/rules/re-ingestion.md +266 -0
  45. package/package.json +2 -2
@@ -0,0 +1,91 @@
1
+ ---
2
+ name: wire-capture
3
+ description: Dimension dumper for the GATED WIRE-CAPTURE dimension of the Product Recon Harness. Climbs the 3-rung lowest-privilege-first ladder (browser tap → HAR → user-run mitmproxy) to record what a non-browser/no-source client *actually* calls, redacting every body before disk. Dispatched during Ingestion (Mode 2) — not invoked directly by users.
4
+ tools: Read, Write, Bash
5
+ model: inherit
6
+ ---
7
+
8
+ # wire-capture — the gated runtime wire dimension
9
+
10
+ You dump what a target's client **actually puts on the wire** into
11
+ `research/<target>/dimensions/wire-capture/`. Read `.claude/rules/re-ingestion.md` (repo root)
12
+ first — especially **§7.1** (the 3-rung ladder), §6 (the shared api-path-catalog seam), and the
13
+ redaction rules. You obey it absolutely. This is the **runtime complement** to
14
+ `distribution-artifacts`: the binary says what hosts it *might* call; you record what it *does*.
15
+
16
+ This dimension is **GATED**. Like `session`, the *live* capture is interactive and
17
+ main-session-driven — the user routes their own client and you ingest exported flows. You apply
18
+ the playbook, author the captures from what's already been collected, and **flag higher rungs for
19
+ user authorization** rather than escalating on your own.
20
+
21
+ ## Inputs (from the dispatch prompt)
22
+ - target slug + the output dir `research/<target>/dimensions/wire-capture/`,
23
+ - the **authorized rung** (1 / 2 / 3) and, for rung 3, the explicit chat authorization + the
24
+ first-party client the user owns and has agreed to route,
25
+ - any already-collected inputs: a Chrome tap log, an exported `*.har`, or a user-exported
26
+ mitmproxy flow dump (`.mitm`/JSON) — paths under `research/<target>/`.
27
+
28
+ ## Strategy — the 3-rung ladder, lowest privilege first
29
+
30
+ Pick the **lowest rung that answers the question** and record it + the authorization in `_meta`.
31
+ Never climb without explicit per-rung authorization in chat.
32
+
33
+ 1. **Rung 1 — browser network tap (default, unauth).** `method: wire-tap-browser`, confidence
34
+ **low** (shapes only). Chrome `read_network_requests` + an in-page fetch/XHR interceptor over
35
+ the **public** surface only — no login. Capture request/response *shapes* (method, path, status,
36
+ content-type, body skeleton), not values. This is the default when an unauth SPA makes
37
+ structured XHRs worth a tap.
38
+ 2. **Rung 2 — HAR export.** `method: wire-har`, confidence **medium**. Ingest a DevTools HAR the
39
+ user exported. Parse with `jq`: `jq '.log.entries[] | {method:.request.method, url:.request.url,
40
+ status:.response.status}' app.har`. Digest to an endpoint catalog; scrub `Authorization`,
41
+ `Cookie`, `Set-Cookie`, and every secret-shaped header/field before anything touches disk.
42
+ 3. **Rung 3 — mitmproxy (GATED · opt-in · USER-RUN · TOS-checked).** `method: wire-mitmproxy`,
43
+ confidence **medium**. **ONLY** first-party traffic the **user owns** (their own desktop/mobile/
44
+ CLI client), **ONLY** with explicit chat authorization, **ONLY** after the target's TOS is
45
+ checked. You **NEVER install a CA and NEVER intercept third-party traffic** — the *user* installs
46
+ the CA, routes *their* client, and exports flows; you only ingest the export
47
+ (`mitmdump -nr flows -w -` then digest, or read the user's JSON dump). Same explicit-authorization
48
+ loop as session Pass-2. If unauthorized, stop and flag it — do not proceed.
49
+
50
+ **Wireshark / packet capture is explicitly NOT used** — for HTTPS it yields only TLS ciphertext,
51
+ and a packet sweep of a third party is the bright line this harness will not cross.
52
+
53
+ **Redact every body before disk.** Run the §7 + §7.1 redaction pass on each flow *before* writing:
54
+ strip `Authorization`/`Cookie`/`Set-Cookie`, collapse credential-shaped fields to
55
+ `<REDACTED:...>`, decode JWT *structure* only with identity claims removed, and log every redaction
56
+ in the artifact `_meta.redactions`. Over-redact when unsure.
57
+
58
+ ## Output
59
+
60
+ Write `research/<target>/dimensions/wire-capture/_summary.md` with the **provenance
61
+ frontmatter** (`dimension: wire-capture`, `target`, `status`, `access_grade_used: runtime:reachable`,
62
+ `method` = the rung actually used, `completeness_pct`, `confidence` per the rung mapping above,
63
+ `captured_at`, `sources`, `gaps`). Body: **Method** (which rung, why that rung, what was skipped),
64
+ **Findings** (the live endpoints, envelope shape, auth scheme, hosts contacted — as tables),
65
+ **Inferences** (mark inference vs. fact — e.g. a host implies a vendor), **Open questions**,
66
+ **Artifacts**.
67
+
68
+ Then the captures + raw artifacts (per `re-discovery` Part C (wire-capture)):
69
+ - `captures/wire-narrative.md` — the decoded story: what the client does on the wire, in order.
70
+ - `raw/flows.json` — verbatim-but-**redacted and digested** flows, each with the `_meta` header
71
+ (incl. `kind`, `byte_length`, `redactions[]`, and the **chosen rung + authorization**), `body`,
72
+ `_decoded`. Digest large captures (schema + one redacted sample + counts), never paste megabytes.
73
+ - `raw/api-path-catalog.md` — the **shared-surface artifact** (§6): every row carries
74
+ `source: wire`. Use this exact filename so evaluation can three-way diff it against `bundle` and
75
+ `session` rows.
76
+ - `curls.md` — reproducer `curl` skeletons with all credentials replaced by placeholders.
77
+
78
+ ## Return value
79
+
80
+ Return a **one-paragraph headline** of what the wire reveals — the real hosts contacted, the
81
+ envelope/auth scheme, and the rung used (so the reader knows how much to trust it). Then a compact
82
+ table of observed endpoints. **Flag the seam rule (§6):** every `api-path-catalog.md` row is
83
+ `source: wire`, so evaluation can diff *actually-called* (wire) against *statically-declared*
84
+ (`bundle` / `distribution-artifacts`) and *browser-observed* (`session`) — a host or path the
85
+ binary declares but the wire never hits is a finding, not noise; the inverse (called but
86
+ undeclared) is a stronger one. If only rung 1 was authorized, say so and name what rungs 2/3 would
87
+ unlock so the main session can request authorization.
88
+
89
+ **Discipline:** lowest privilege first; never self-escalate the ladder; never install a CA or tap
90
+ third-party traffic; never run Wireshark; redact every body before disk and log it in `_meta`. An
91
+ unauthorized higher rung is an Open question, not an excuse to guess what the wire would show.
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "re",
3
+ "version": "0.1.0",
4
+ "epoch": null,
5
+ "digest": "04de463436b5"
6
+ }
@@ -0,0 +1,266 @@
1
+ # Discovery Reference — Scope Gate · Access Vector · Dimension Catalog
2
+
3
+ The reference knowledge for **Discovery** (`re` harness, Mode 1). It carries all three of
4
+ Discovery's steps in the order they run:
5
+
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, dump strategy, and owning agent.
12
+
13
+ `ingestion` also reads **Part C** to dispatch the right agent with the right method.
14
+
15
+ ---
16
+
17
+ # Part A — Scope-feasibility gate (Step 0)
18
+
19
+ Run this **before** any dimension probing. It resolves the target's identity and emits one of four
20
+ verdicts. The rules are mechanical — execute them with cheap probes (`WebSearch`, `curl`,
21
+ `git ls-remote`, `npm view`) in well under a minute.
22
+
23
+ Output: `research/<target>/00-scope-verdict.md` + a `scope:` block in `00-recon-plan.md`. If the
24
+ verdict is not `accept`, Discovery **halts** (presents the narrowing prompt, or refuses) and does
25
+ not proceed to dimension probing.
26
+
27
+ ## Verdicts
28
+
29
+ | Verdict | Meaning | Downstream |
30
+ |---------|---------|-----------|
31
+ | **accept** | bounded target with ≥1 real surface | continue to dimension probing |
32
+ | **narrow** | too-broad-suite or ambiguous-name | present the narrowing prompt; halt for user reply |
33
+ | **redirect** | a commodity primitive (behavior = its public spec) | offer a facet menu; halt for user reply |
34
+ | **refuse** | ethically/legally out-of-bounds (hard stop only here) | stop; no run |
35
+
36
+ A **no-reachable-surface** result is a **soft prompt** ("log in / give me a URL or repo"), not a
37
+ hard refuse — only the ethics gate (Gate B) is a hard refuse.
38
+
39
+ ## The decision algorithm (priority-ordered; first match wins)
40
+
41
+ **0a — Resolve identity.** If the user gave a concrete URL/repo/package, identity is fixed → skip
42
+ ambiguity. Else `WebSearch "<target>"` + `"<target> software"`; collect canonical homepage, vendor,
43
+ one-line category.
44
+
45
+ **Gate A — ambiguity.** Top results map to ≥2 unrelated vendors/categories → `narrow` (disambiguate). STOP.
46
+
47
+ **Gate B — ethics.** Resolved product is piracy/cracking/malware/CSAM/credential-harvesting/spyware,
48
+ or the only way in is bypassing auth/paywall/TOS the user has no right to → `refuse` (ethics). STOP.
49
+ *(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
52
+ "Products" items each with their own `/pricing` or `/docs` tree; or a `WebSearch "<target> products"`
53
+ grid). If N ≥ 4 **OR** the entity is on the umbrella seed list → `narrow` (pick-product). STOP.
54
+ > Umbrella seed list: AWS, Azure, GCP, Salesforce, Microsoft 365, SAP, Oracle Cloud, Google
55
+ > Workspace, Adobe Creative Cloud, Atlassian.
56
+ > Guard against false positives: "one platform, many *modules* sharing one account/API/pricing page"
57
+ > (Stripe: Payments/Billing/Connect) is **one product → accept**, not a suite. The N≥4 count alone
58
+ > isn't enough — require separate pricing/docs trees, not just a broad nav.
59
+
60
+ **Gate D — primitive.** Target is a single foundational building block whose behavior is a published
61
+ spec with no hidden app surface (managed primitives like S3/EC2/Lambda; single-purpose util libs
62
+ with <~5 exports; protocol/spec names; a raw DB engine) → `redirect` (pick-facet). STOP.
63
+ > Bias: only `redirect` when behavior is fully a public spec. When a hosted SaaS wrapper exists
64
+ > (Redis Cloud, MongoDB Atlas), prefer `accept` on the wrapper.
65
+
66
+ **Gate E — reachability.** Run the cheapest probe per dimension as a boolean (does ANY surface
67
+ exist?): `git ls-remote` OR npm/PyPI hit OR `llms.txt`/docs subdomain OR homepage-200-with-content
68
+ OR user-has-session. If ZERO surfaces → **soft prompt** ("No reachable surface — log in, or give me
69
+ a repo/docs/URL"). If exactly one thin non-session surface → `accept` (thin) with a shallow-coverage
70
+ warning.
71
+
72
+ **Fallthrough → `accept`.** Compute the access vector (Part B) and proceed to dimension probing.
73
+
74
+ **Recursion:** a narrowed pick re-enters Step 0 (so "Salesforce → Marketing Cloud" is itself
75
+ feasibility-checked and may narrow again). **Max narrow-depth = 2**, then accept-the-narrowest with
76
+ a partial-coverage warning.
77
+
78
+ ## `00-scope-verdict.md` shape
79
+
80
+ ```markdown
81
+ ---
82
+ target: <slug>
83
+ scope_checked_at: <YYYY-MM-DD>
84
+ verdict: accept | narrow | redirect | refuse
85
+ verdict_reason: clean | too-broad-suite | primitive | ambiguous-name | no-surface | ethics | over-scoped
86
+ resolved_identity: <canonical homepage / repo / package>
87
+ suite_product_count: <N>
88
+ surfaces_present: [codebase?, docs?, api?, website?, session?]
89
+ awaiting_user: <true|false>
90
+ ---
91
+ # <Target> — Scope Verdict: <VERDICT>
92
+ ## Resolution (what the name resolved to + evidence)
93
+ ## Gate trace (which gate fired A–E + the verbatim signal)
94
+ ## Verdict & reason
95
+ ## Narrowing prompt (if narrow/redirect — the exact question + options)
96
+ ## If refused (one-line reason + what would make it acceptable)
97
+ ```
98
+ Mirror `verdict` into a `scope:` frontmatter block on `00-recon-plan.md` so ingestion reads one field.
99
+
100
+ ## Narrowing prompt templates
101
+
102
+ **NARROW-SUITE (Gate C):** "I can recon a focused product, but **<Target>** is a suite of ~<N>
103
+ independently-built products — a single run would be shallow across all of them. Which one should I
104
+ tear down?" + a numbered list auto-built from the homepage product nav, each tagged with its likely
105
+ access-grade. Always append "0. A specific feature within one of these (tell me which)."
106
+
107
+ **NARROW-DISAMBIGUATE (Gate A):** "**<Target>** resolves to more than one product. Which did you
108
+ mean?" + numbered candidates (vendor · one-line · URL) + "none of these — give me a URL."
109
+
110
+ **REDIRECT-PRIMITIVE (Gate D):** "**<Target>** is a documented primitive, not a product with hidden
111
+ internals — its behavior is the public spec. I can still recon a facet. Which angle?" + a facet menu
112
+ (for a managed service: console/dashboard UX · public API surface · consistency/semantics model ·
113
+ pricing & limits as a product · competitive positioning) + "Or point me at a real product that USES
114
+ <Target> and I'll recon that instead."
115
+
116
+ ## Worked verdicts (regression fixtures)
117
+
118
+ | Target | Gate | Verdict | Note |
119
+ |--------|------|---------|------|
120
+ | AWS S3 | D | redirect (primitive) | "behavior is the public API; pick a facet or a product built on S3" |
121
+ | Salesforce | C | narrow (suite) | "pick a cloud: Sales / Service / Marketing / Flow Builder / Apex / …" |
122
+ | Microsoft 365 | C | narrow (suite) | umbrella seed list; options Word/Excel/Teams/… each tagged |
123
+ | Notion | fallthrough | accept | single product; docs+api+website+session, no public monorepo |
124
+ | Liveblocks | fallthrough | accept (Case 1) | open monorepo + SDKs + docs + OpenAPI + site + session |
125
+ | bare "Atlas" | A | narrow (ambiguous) | MongoDB Atlas vs Ory Atlas vs Palantir |
126
+ | leftpad-class util | D | redirect (primitive) | "<5 exports; source IS the spec" |
127
+ | coming-soon splash, no session | E | soft prompt | "no reachable surface — log in or give me a repo/URL" |
128
+ | torrent/credential-stuffing service | B | refuse (ethics) | no prompt, no run |
129
+
130
+ ---
131
+
132
+ # Part B — Access is a capability VECTOR (Step 1)
133
+
134
+ A target's "access" is **four orthogonal axes**, each carrying `{value, confidence, evidence}`.
135
+ The vector — not a single grade — decides which dimensions are reachable and which extraction
136
+ *method* each uses.
137
+
138
+ | Axis | Values | Unlocks dimensions | Anchors |
139
+ |------|--------|--------------------|---------|
140
+ | **source** | full · partial · none | codebase, packages | *Case 1* (full = OSS repo) |
141
+ | **runtime** | reachable · gated · none | deployed-client-bundle, api, infra-backend-fingerprint, wire-capture | *Case 2* (reachable + source:none) |
142
+ | **auth** | have-login · none | session | *Case 3* (have-login) |
143
+ | **presence** | rich · thin · none | docs, website, community | (almost always rich) |
144
+
145
+ The three named **cases** are presets over this vector — a target can light several at once
146
+ (Liveblocks = source:full + runtime:reachable + auth:obtainable + presence:rich → nearly all
147
+ dimensions). Rules:
148
+ - **`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.
149
+ - **Dimension-level access overrides the target headline** for method selection (a Case-1 target can still have a Case-3 session dimension).
150
+ - Method swaps on axis *value*: `source:full` ⇒ `clone-and-map`; `source:partial` ⇒ `source-map-reassembly`; `runtime:reachable + source:none` ⇒ `bundle-string-mine` + wire-capture.
151
+
152
+ Discovery records the resolved vector in the `access_grade` frontmatter of `00-recon-plan.md`.
153
+
154
+ ---
155
+
156
+ # Part C — The dimension catalog (Step 2)
157
+
158
+ | # | Dimension | Agent | Unlocking axis | One-line strategy |
159
+ |---|-----------|-------|----------------|-------------------|
160
+ | 1 | **codebase** | `codebase` | source:full | clone → structural map → per-package fan-out |
161
+ | 2 | **docs** | `docs` | presence | `llms.txt` → else crawl/clip → organize by section |
162
+ | 3 | **packages** | `packages` | source/presence | registry metadata + exports + type defs |
163
+ | 4 | **api** | `api` | runtime/presence | OpenAPI/GraphQL → endpoint catalog (+ **MCP/tool-catalog fold-in**) |
164
+ | 5 | **website** | `website` | presence | crawl public pages → features, pricing, positioning |
165
+ | 6 | **community** | `community` | presence | first-party changelog/issues/discord themes |
166
+ | 7 | **session** | `session` | auth:have-login | delegate to the session playbook (§9 of `re-ingestion`: 3-pass, P0–P6) |
167
+ | 8 | **deployed-client-bundle** | `deployed-client-bundle` | runtime:reachable | unauth SPA: route table, API-path catalog, flags, env, source maps |
168
+ | 9 | **infra-backend-fingerprint** | `infra-backend-fingerprint` | runtime/presence | DNS, cert-transparency, CDN/cloud, headers (+ **sub-processor/trust fold-in**) |
169
+ | 10 | **wire-capture** | `wire-capture` | runtime (source:none) | the 3-rung ladder for non-browser/no-source clients (gated) |
170
+ | 11 | **distribution-artifacts** | `distribution-artifacts` | runtime (non-web client) | extension CRX / Electron `.asar` / mobile binary / CLI |
171
+
172
+ > **Deferred (available on request, not built):** `external-reputation` (G2/Reddit/HN — the only
173
+ > "what others say" surface) and `hiring-intel` (job posts leak the backend stack). Strong
174
+ > candidates, declined for this iteration. Re-add via self-correction if a run needs them.
175
+
176
+ An **absent** dimension is a finding — record it with its evidence; never silently drop it.
177
+
178
+ ## 1–7 — the core dimensions (strategy in brief)
179
+
180
+ See git history / the source playbook for the full strategy text; in brief:
181
+ - **codebase** — shallow-clone into `source/<target>/`, read orientation files + manifests, map
182
+ packages + internal dep hierarchy, return a per-package work-list for the main-session fan-out.
183
+ - **docs** — prefer in-repo docs, then `llms.txt`/`llms-full.txt`, then crawl; organize by section.
184
+ - **packages** — per public package: registry metadata, `exports` map + `.d.ts` type surface, health.
185
+ - **api** — fetch the spec verbatim, build an endpoint catalog (auth, envelope, pagination, webhooks).
186
+ **NEW fold-in:** also probe MCP/tool surfaces — `/.well-known/mcp`, an MCP server manifest, a
187
+ function-calling tool schema, an LLM "actions" file — and write `raw/tool-catalog.md` (an MCP tool
188
+ list *is* an API catalog; it lives here, not in its own dimension).
189
+ - **website** — crawl home/features/pricing/customers/integrations; extract positioning, pricing
190
+ matrix, target market.
191
+ - **community** — *first-party only*: changelog cadence + direction, issue/discussion themes, blog.
192
+ - **session** — the deepest, opt-in, user-gated dimension; delegates to the session playbook in
193
+ `re-ingestion` §9 (3-pass, P0–P6, captures/raw/curls).
194
+
195
+ ## 8 — deployed-client-bundle — `deployed-client-bundle`
196
+
197
+ **Unlocked by:** `runtime:reachable`. The **unauthenticated app shell** — distinct from `website`
198
+ (marketing) and `session` (authenticated). Works on closed SaaS with no repo and no login.
199
+
200
+ **Detection:** an app subdomain (`app.<target>.*`) or SPA route serves a JS bundle;
201
+ `sourceMappingURL` present; a `/assets/*.js` graph.
202
+
203
+ **Strategy:** fetch the main bundle(s); string-mine the **route table**, the **API-path catalog**
204
+ (→ shared `raw/api-path-catalog.md`, `source: bundle`), **feature flags** (→ shared
205
+ `raw/feature-flags.md`), embedded **env config** (`VITE_*`, `NEXT_PUBLIC_*`, public keys —
206
+ field-names only, redact values), and reassemble **source maps** if shipped (`method:
207
+ source-map-reassembly`, confidence high). Digest huge bundles, don't paste.
208
+
209
+ **Artifacts:** `_summary.md` + `raw/{route-table.md, api-path-catalog.md, feature-flags.md, env-config.md, bundle-map.md}`.
210
+
211
+ ## 9 — infra-backend-fingerprint — `infra-backend-fingerprint`
212
+
213
+ **Unlocked by:** `runtime`/`presence`. Reconstructs the backend you can't see in the repo.
214
+
215
+ **Detection:** always attemptable for any live domain.
216
+
217
+ **Strategy:** DNS records; **cert-transparency subdomain enumeration** (crt.sh → staging/internal/
218
+ api hosts); CDN/cloud fingerprint (CNAMEs, IP/ASN, response headers); security headers; tech
219
+ fingerprint (framework/analytics tells). **Sub-processor fold-in:** fetch the `/legal`, `/trust`,
220
+ `/security`, `/dpa` pages → `raw/sub-processors.md` — the sub-processor list **names the vendor
221
+ stack** (cloud, payments, AI provider, email, telephony), which is exactly this dimension's job.
222
+
223
+ **Artifacts:** `_summary.md` + `raw/{dns-and-subdomains.md, cloud-cdn-fingerprint.md, security-headers.md, sub-processors.md}`.
224
+
225
+ ## 10 — wire-capture — `wire-capture` (first-class, GATED)
226
+
227
+ **Unlocked by:** `runtime` when the interesting client is **non-browser** or there's **no source**
228
+ (your Case 2). The runtime-evidence complement to `distribution-artifacts` (static): the binary says
229
+ what hosts it *might* call; the capture says what it *actually* calls.
230
+
231
+ **Detection:** a non-browser client exists (from distribution-artifacts) OR an unauth SPA makes
232
+ structured XHRs worth a tap, AND the appropriate ethics rung is authorized.
233
+
234
+ **Strategy:** the **3-rung ladder** (lowest privilege first) — see `re-ingestion` §7.1:
235
+ 1. browser network tap (unauth, default) → `wire-tap-browser`;
236
+ 2. HAR export → `wire-har`;
237
+ 3. mitmproxy (**gated, opt-in, user-run, first-party traffic only**) → `wire-mitmproxy`.
238
+
239
+ **Artifacts:** `_summary.md` + `captures/wire-narrative.md` + `raw/{flows.json (redacted/digested), api-path-catalog.md (source: wire)}` + `curls.md`. Record the chosen rung + authorization in `_meta`.
240
+
241
+ ## 11 — distribution-artifacts — `distribution-artifacts`
242
+
243
+ **Unlocked by:** `runtime` (a downloadable non-web client). Often the closest thing to source for a
244
+ closed product.
245
+
246
+ **Detection:** a Chrome/Firefox web-store listing; a "Download for Mac/Windows" (Electron/Tauri)
247
+ button; an App Store / Play Store listing; a published CLI (`npm i -g`, brew, GitHub releases).
248
+
249
+ **Strategy:** **extension** — decode `manifest.json` (permissions/hosts/content-scripts = a
250
+ capability map). **Electron** — `npx asar extract app.asar` → map JS modules + the shared
251
+ route/API/flag catalog from the desktop client (often richer than web). **mobile** — `Info.plist`/
252
+ `AndroidManifest` hosts, ATS exceptions, embedded-SDK list from strings (**redact any embedded
253
+ keys**). **CLI** — help text/subcommands = an API catalog. Read the artifact's EULA first (see
254
+ `re-ingestion` §7.2); never silently decompile a restrictively-licensed binary.
255
+
256
+ **Artifacts:** `_summary.md` + `raw/{extension-manifest.md, electron-asar-map.md, mobile-strings.md, cli-catalog.md}` (whichever apply) + `raw/api-path-catalog.md` (source: distribution).
257
+
258
+ ---
259
+
260
+ ## How Discovery uses this reference
261
+
262
+ Step 0 — run **Part A** (the gate); halt unless `accept`. Step 1 — grade the **Part B** vector with
263
+ evidence. Step 2 — for each dimension in **Part C**, check its unlocking axis against the resolved
264
+ vector, run the cheap detection probe, and record **available / partial / absent** with evidence
265
+ into `00-recon-plan.md`. Gated dimensions (session, wire-capture rung 3) are flagged for user
266
+ confirmation before ingestion dispatches them.
@@ -0,0 +1,100 @@
1
+ # Evaluation Templates
2
+
3
+ `evaluation` reads every `dimensions/<dim>/_summary.md` (its **provenance frontmatter** +
4
+ Findings) and reconciles them into **cross-dimension** documents under
5
+ `research/<target>/evaluation/`. The value is the reconciliation — cross-checking views into one
6
+ coherent picture, **weighted by how each claim was obtained**, with disagreements flagged.
7
+
8
+ **Three rules for every evaluation doc:**
9
+ 1. **Anchor + tag every claim** with its dimension *and provenance*: `(api: raw/endpoint-catalog.md
10
+ · openapi-verbatim · high)`. The method + confidence come verbatim from the source dimension's
11
+ `_summary.md` frontmatter.
12
+ 2. **Weight, don't average.** A claim's confidence = the **max** of its sources' confidence,
13
+ **promoted one band only if corroborated by ≥2 *independent* dimensions**, capped at source
14
+ confidence when single-source. Conflicts are **flagged, never averaged**.
15
+ 3. **Cross-check, don't concatenate.** Agree → state as fact. Disagree / single-source / low-conf →
16
+ render hedged ("observed but unverified…") and flag in the doc's reconciliation section.
17
+
18
+ **Independence (for the promotion rule):** `codebase`, `api`, `session`, `wire-capture`,
19
+ `distribution-artifacts` are mutually independent and independent of marketing. **`website` and
20
+ `docs` are NOT independent** for *feature claims* (docs often restate marketing) — two of them
21
+ agreeing is still one source. A bundle-declared route + a session-observed route ARE independent.
22
+
23
+ **Presentation mapping:** high → stated as fact; low/single-source → hedged as tentative;
24
+ conflicted → flagged. (This is the "lighter" form of the provenance-weighting — done inline in the
25
+ prose, not via a separate `claims.yaml`.)
26
+
27
+ ---
28
+
29
+ ## 1. `evaluation/technology-architecture.md`
30
+ ```markdown
31
+ # <Target> — Technology & Architecture
32
+ ## TL;DR (3–5 sentences; the single most distinctive choice)
33
+ ## Stack (languages/frameworks/build/runtime — table, each anchored+tagged)
34
+ ## Architecture (client/server split, packages+deps, runtime/sync/data model, transport)
35
+ ## How it's built (monorepo layout, public/private, codegen, CI, release cadence)
36
+ ## Notable design choices (the 3–5 worth stealing + why)
37
+ ## Cross-dimension reconciliation (agreements/disagreements + confidence per claim)
38
+ ## Open questions
39
+ ```
40
+
41
+ ## 2. `evaluation/product-features.md`
42
+ ```markdown
43
+ # <Target> — Product Features & Capabilities
44
+ ## What it does (one paragraph)
45
+ ## Feature map (every capability · user · maturity GA/beta/docs-only — anchored+tagged)
46
+ ## User-facing surfaces (dashboard/editor/components/CLI/widgets)
47
+ ## User journeys (the 2–3 primary flows end-to-end)
48
+ ## Gaps & rough edges (from community signal)
49
+ ## Cross-dimension reconciliation (marketing claims vs. what code/docs actually support — flag over-claims)
50
+ ```
51
+
52
+ ## 3. `evaluation/data-model-api-surface.md`
53
+ ```markdown
54
+ # <Target> — Data Model & API / SDK Surface
55
+ ## Core entities (domain objects + relations; ER-style)
56
+ ## Integration surface (SDK/packages public API · REST/HTTP catalog · realtime/wire protocol)
57
+ ## Auth & tenancy model (token type, where it lives, scope expression)
58
+ ## Three-way API-path diff (the seam rule: bundle-declared vs session-observed vs wire-observed —
59
+ dormant/unshipped routes are findings)
60
+ ## Cross-dimension reconciliation (published surface [api/packages/docs] vs observed wire [session/
61
+ wire-capture]; document drift — published=fact, observed-drift=tentative)
62
+ ## Open questions
63
+ ```
64
+
65
+ ## 4. `evaluation/competitive-positioning.md`
66
+ ```markdown
67
+ # <Target> — Competitive Positioning
68
+ ## Positioning (their pitch + market — website/blog)
69
+ ## Pricing & packaging (plans, what gates what, unit economics — website pricing + platform/limits)
70
+ ## Differentiation (claimed moat vs the teardown's read of the real moat — often infra/data)
71
+ ## Alternatives & comparison (named competitors + how it differs)
72
+ ## Strategic read (direction from changelog/blog)
73
+ ```
74
+
75
+ ---
76
+
77
+ ## 5. `research/<target>/README.md` — the run story
78
+ ```markdown
79
+ # <Target> — Recon Run
80
+ > One paragraph: what it is + why we ran recon.
81
+ ## Access grade (the resolved vector — source/runtime/auth/presence — + matched case[s])
82
+ ## Dimensions covered (table: dimension | status | method | confidence | headline finding)
83
+ ## Headline findings (5–10, each anchored+tagged)
84
+ ## How to navigate (00-scope-verdict.md, 00-recon-plan.md, dimensions/, evaluation/, 04-self-correction-proposal.md)
85
+ ## Lessons (candidate methodology learnings → feed self-correction)
86
+ ## Reproduction
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Evaluation method
92
+ 1. Read every `dimensions/*/_summary.md` frontmatter first (the provenance index) — note method +
93
+ confidence + status + gaps per dimension.
94
+ 2. Read Findings; drop into specific `raw/` artifacts only when a claim needs a precise value.
95
+ 3. Draft the four rollups + the README — each rollup may be drafted by its own sub-agent dispatched
96
+ from the **main session** (overlapping reads, independent writes), then a single reconciliation
97
+ pass keeps them consistent.
98
+ 4. Tag every claim with provenance; weight per the rules above; flag every disagreement; record
99
+ every gap. A confident doc built on one low-confidence dimension is worse than an honest
100
+ "single-source, unverified."