@nurix/etna 0.15.2 → 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 +0 -14
  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 +1 -1
  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 +0 -1
  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,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."
@@ -0,0 +1,266 @@
1
+ # Ingestion Contract — Dump Shape · Provenance · Ethics · Session Playbook
2
+
3
+ The reference knowledge for **Ingestion** (`re` harness, Mode 2). Every dimension dump obeys the
4
+ contract in §1–8 so (a) the **evaluation** mode can rely on a stable shape and weight each claim by
5
+ *how it was obtained*, and (b) a future agent can reproduce or extend any dump. §9 carries the
6
+ deepest, gated dimension's method — the logged-in browser-session playbook — which the `session`
7
+ agent follows.
8
+
9
+ This contract generalizes the source playbook's three-format contract (`captures/*.md` narrative +
10
+ `raw/*.json` verbatim + `curls.md`) to *any* dimension.
11
+
12
+ > **Contract style = "lighter".** Provenance ("how it was dumped") lives in the
13
+ > **`_summary.md` frontmatter**, not a separate `manifest.yaml`. There is no parallel YAML
14
+ > machine-spine — everything stays markdown-with-frontmatter. Evaluation reads the frontmatter
15
+ > to weight claims; self-correction reads it to detect under-delivery.
16
+
17
+ ---
18
+
19
+ ## 1. Folder layout
20
+
21
+ ```
22
+ research/<target>/dimensions/<dimension>/
23
+ ├── _summary.md ← decoded narrative + provenance frontmatter (human + machine read this)
24
+ └── raw/ ← verbatim artifacts (the reproducer reads these)
25
+ ```
26
+
27
+ Richer dimensions inherit the playbook contract (extra files, same `_summary.md` provenance):
28
+ - **session**: `dimensions/session/{_summary.md, captures/p*.md, raw/*.json, curls.md}`
29
+ - **wire-capture**: `dimensions/wire-capture/{_summary.md, captures/wire-narrative.md, raw/flows.json, curls.md}`
30
+
31
+ ---
32
+
33
+ ## 2. `_summary.md` — required shape (with provenance frontmatter)
34
+
35
+ ```markdown
36
+ ---
37
+ dimension: <codebase|docs|packages|api|website|community|session|deployed-client-bundle|infra-backend-fingerprint|wire-capture|distribution-artifacts>
38
+ target: <slug>
39
+ status: complete | partial | blocked
40
+ # --- provenance (the "how it was dumped" layer evaluation weights on) ---
41
+ access_grade_used: <source:full | runtime:reachable | auth:have-login | presence:rich | ...>
42
+ method: <the ACTUAL extraction method — see §3 vocabulary>
43
+ completeness_pct: <0-100, honest self-estimate of reachable surface captured>
44
+ confidence: high | medium | low # how much to TRUST what was captured (see §3)
45
+ captured_at: <YYYY-MM-DD>
46
+ sources: [<urls / paths actually consulted>]
47
+ gaps: [<structured — each is a thing evaluation must NOT treat as covered>]
48
+ ---
49
+
50
+ # <Target> — <Dimension> dump
51
+
52
+ ## Method
53
+ Exactly what was done, which tools, what was skipped and why. (The prose behind the frontmatter `method`.)
54
+
55
+ ## Findings
56
+ Ordered, concrete observations — real values (package names, versions, endpoint paths, file
57
+ paths, page URLs, prices). Tables liberally. The load-bearing section.
58
+
59
+ ## Inferences
60
+ What the findings imply. Mark inference vs. fact.
61
+
62
+ ## Open questions
63
+ What couldn't be captured and why. Never fabricate to fill a gap.
64
+
65
+ ## Artifacts
66
+ Index of `raw/` files, one line each.
67
+ ```
68
+
69
+ Keep `status` and `confidence` honest — they drive the entire evaluation weighting.
70
+
71
+ ---
72
+
73
+ ## 3. Method & confidence vocabulary (drives evaluation weighting)
74
+
75
+ `method` is one of: `clone-and-map`, `source-map-reassembly`, `registry-metadata`,
76
+ `openapi-verbatim`, `graphql-introspection`, `crawl-clip`, `docs-reconstructed`,
77
+ `bundle-string-mine`, `dns-ct-fingerprint`, `wire-tap-browser`, `wire-har`, `wire-mitmproxy`,
78
+ `binary-extract` (asar/apk/crx), `session-playbook`, `inferred`.
79
+
80
+ **Confidence is a function of method** (evaluation relies on this mapping):
81
+ - **high** — verbatim machine artifacts: `openapi-verbatim`, `graphql-introspection`, `registry-metadata`, `clone-and-map`, `binary-extract`.
82
+ - **medium** — `crawl-clip`, `docs-reconstructed`, `bundle-string-mine`, `dns-ct-fingerprint`, `wire-har`.
83
+ - **low** — `inferred`, `session-playbook` Pass-1-only, `wire-tap-browser` shapes-only, any wire-drift observation without a spec.
84
+
85
+ ---
86
+
87
+ ## 4. `raw/*` — required shape
88
+
89
+ Structured captures (API responses, registry metadata, schemas) → JSON with a `_meta` header:
90
+ ```json
91
+ {
92
+ "_meta": { "source": "...", "captured_at": "YYYY-MM-DD", "kind": "...", "byte_length": 0, "redactions": ["field → <REDACTED:...>"] },
93
+ "body": { /* verbatim, PII + secrets redacted */ },
94
+ "_decoded": { "field": "meaning + observed values" },
95
+ "_observation": "optional — what's load-bearing"
96
+ }
97
+ ```
98
+ Prose captures (doc/marketing pages, structure maps, catalogs) → markdown with a metadata line:
99
+ `<!-- source: <url-or-path> · captured_at: YYYY-MM-DD · method: <method> -->`
100
+
101
+ **One file per logical artifact**, named by what it is (`endpoint-catalog.md`, `react-exports.md`,
102
+ `pricing.md`, `structure-map.md`).
103
+
104
+ ---
105
+
106
+ ## 5. Size discipline — reduce, don't dump
107
+
108
+ Large artifacts (a 3 MB bundle, a 5 MB response, a 700-page sitemap) are **digested**, not pasted:
109
+ the schema/shape, enum distributions, one redacted representative sample, counts. A `raw/` file is
110
+ readable, not a memory dump. Set `digested: true` context in the artifact's `_meta`.
111
+
112
+ ---
113
+
114
+ ## 6. The shared-surface seam rule (bundle ↔ session ↔ wire-capture)
115
+
116
+ `deployed-client-bundle` (static unauth SPA), `session` (authenticated browser runtime), and
117
+ `wire-capture` (non-browser client) can all surface the same **API path catalog** and **feature
118
+ flags**. To keep them consumable instead of triplicated:
119
+
120
+ - Use **one canonical artifact name** across all three: `raw/api-path-catalog.md` and
121
+ `raw/feature-flags.md`, each row carrying a `source: bundle | session | wire` column.
122
+ - Evaluation owns the **three-way diff** (static-declared vs browser-observed vs nonbrowser-observed)
123
+ in `data-model-api-surface.md`. A path that appears in `bundle` but never in `session`/`wire` is a
124
+ dormant/unshipped route — a finding, not noise.
125
+
126
+ ---
127
+
128
+ ## 7. Ethics & redaction (non-negotiable — binds EVERY dimension)
129
+
130
+ Carried from the source playbook (`setup.md` §6). Violating them voids the work.
131
+
132
+ 1. **Never enter credentials.** The user signs into any logged-in surface beforehand.
133
+ 2. **Storage: shape, not values.** No raw cookies/tokens/JWT-signatures. Decode JWT *structure* with identity claims (`sub`,`email`,`phone`,`user_id`,`uid`,`sid`) redacted.
134
+ 3. **Never save secrets.** Before any `raw/` write, redact every credential-shaped field → `<REDACTED:...>` + log in `_meta.redactions`. Field patterns: `api_key`,`*_secret`,`client_secret`,`webhook_secret`,`signing_*`,`password`,`private_key`,`access_token`/`refresh_token` in bodies, vendor-named secrets. Value patterns: `sk_live_…`/`pk_live_…` (Stripe), `sk-…` (OpenAI), `xox[bp]-…` (Slack), `AKIA…` (AWS), `gh[ps]_…` (GitHub), `AIza…` (Google), `eyJ…` (JWT), opaque base64 ≥32 chars in a credential field. Over-redact when unsure.
135
+ 4. **Confirm before state changes** — anything that creates state, costs money, or is visible to others (even a draft toggle). State the exact action + estimated cost.
136
+ 5. **No destructive actions.** Document the absence; move on.
137
+ 6. **No bypassing safety harnesses** — redact, never evade.
138
+ 7. **No exfiltration.** Captures stay local under `research/<target>/`.
139
+ 8. **Respect TOS & robots.** For spec-writing / integration / competitive analysis — not credential theft, rate-limit bypass, or scraping.
140
+
141
+ ### 7.1 wire-capture & active-interception ethics (the strictest tier)
142
+
143
+ The `wire-capture` dimension climbs a **3-rung ladder, lowest privilege first**, and records the
144
+ chosen rung in `_meta`:
145
+
146
+ 1. **Browser network tap (default, unauth).** Chrome `read_network_requests` + the in-page
147
+ fetch/XHR interceptor on the **public** surface only. Capture request/response *shapes*; redact
148
+ in the wrapper before disk. No login. → `method: wire-tap-browser`.
149
+ 2. **HAR export.** Export DevTools HAR of the unauth SPA's XHRs, digest to an endpoint catalog,
150
+ scrub `Authorization`/`Cookie`/secret-shaped values. → `method: wire-har`.
151
+ 3. **mitmproxy / intercepting proxy — GATED, opt-in, user-run.** ONLY first-party traffic the
152
+ **user owns** (their own desktop/mobile/CLI client), ONLY with explicit chat authorization, ONLY
153
+ TOS-checked. The harness NEVER stands up a proxy against a third party's infra unattended; the
154
+ *user* installs the CA and routes their client — the agent only ingests exported flows. →
155
+ `method: wire-mitmproxy`. Same explicit-authorization loop as session Pass-2.
156
+
157
+ > Wireshark / packet capture is explicitly **not** used: for HTTPS it yields only TLS ciphertext,
158
+ > and a packet sweep of a third party is the bright line this harness will not cross.
159
+
160
+ ### 7.2 distribution-artifacts ethics
161
+ Downloading a public binary (CRX/`.asar`/`.ipa`/`.apk`) and reading its manifest/strings is fine.
162
+ But binary **decompilation** can cross from "inspect" to "reverse-engineer in violation of EULA":
163
+ the agent reads the artifact's own license/EULA first and records a restrictive one as an Open
164
+ question rather than silently decompiling.
165
+
166
+ ---
167
+
168
+ ## 8. Completeness check
169
+ A dump is complete when: `_summary.md` exists with full provenance frontmatter + honest `status`;
170
+ every Finding is backed by a `raw/` artifact or inline value; `raw/` artifacts have `_meta` +
171
+ decoding (large ones digested); redaction pass run; `gaps` recorded (never fabricated).
172
+
173
+ ---
174
+
175
+ ## 9. The session dimension — logged-in browser-session playbook
176
+
177
+ The method for the **session** dimension: reverse-engineering the *authenticated runtime* of a
178
+ product by driving it through a browser (Chrome MCP) and instrumenting it. It produces a
179
+ section-by-section understanding of a product's wire protocol, auth, and state model **without
180
+ source-code access**. The `session` agent follows this section.
181
+
182
+ This is the deepest and most sensitive dimension. The ethics in §7 above bind hardest here.
183
+
184
+ ### 9.1 Prerequisites (verify before anything else — all three non-negotiable)
185
+
186
+ | # | Precondition | How to verify |
187
+ |---|--------------|---------------|
188
+ | 1 | Target is **pre-logged-in** in Chrome | open the target URL in the connected tab → an authenticated surface (a dashboard, not a sign-in page). The agent never enters credentials. |
189
+ | 2 | **Claude Chrome extension** installed | `mcp__claude-in-chrome__tabs_context_mcp` returns live tabs |
190
+ | 3 | **Chrome CDP** connected | the same call returns stable tab IDs |
191
+
192
+ If any fails, return `blocked` naming the missing precondition.
193
+
194
+ ### 9.2 The three-pass strategy
195
+
196
+ A single linear sweep wastes context on things you can read for free and wastes credits on
197
+ actions whose response shape you could infer. Use three passes.
198
+
199
+ **Pass 1 — read-only mining (no money, no state change).** If the user already has data (a
200
+ project, conversation, account, order), mine it first. Hit every list/state/history endpoint with
201
+ the existing token; capture verbatim bodies. This yields ~70% of the spec for free. Mine, by role:
202
+ identity (`/me`, `/account`, `/workspaces`), list (the canonical taxonomy), single-resource state
203
+ (server-injected vs client-sent fields), history/event-log (a whole trajectory in one call),
204
+ runtime/preview state, per-resource billing, account billing, feature flags/cohort, integration
205
+ catalog (`/mcp/`, `/integrations/`), and schema/capabilities (`/openapi.json`, `/.well-known/*`,
206
+ `/page-metadata`).
207
+
208
+ **Pass 2 — fresh-run validation (with explicit cost/state-change confirmation).** Only after
209
+ Pass 1, and only with explicit user OK stating the exact action + cheapest mode + estimated cost.
210
+ Catches what Pass 1 can't: the submit/write request body, live state-machine transitions, the
211
+ completion event, server-side resolution of shorthand, ID/slug-generation, the real iteration
212
+ endpoint, and the full realtime event catalog. **Legitimate to skip** if the user opts out — leave
213
+ write-side shapes as open questions; never fabricate them.
214
+
215
+ **Pass 3 — synthesis.** Walk the captures, pull each finding into the dimension's `_summary.md`,
216
+ note the cleverest design choices, defaults imposed, performance characteristics, and open
217
+ questions.
218
+
219
+ ### 9.3 The P0 → P6 phases
220
+
221
+ The same phases apply whether the target is an AI builder, analytics dashboard, CRM, or collab tool:
222
+
223
+ | Phase | Focus |
224
+ |-------|-------|
225
+ | **P0 Surface** | routes, bundles, storage shape, the API host(s), the auth tell |
226
+ | **P1 Auth** | token type + issuer + storage location + refresh path; tenancy model |
227
+ | **P2 Core action** | the primary write — the submit/create body and its server resolution |
228
+ | **P3 Streaming** | the realtime transport (WS / SSE / WebChannel / Pusher / none) + event catalog |
229
+ | **P4 Runtime/state** | sandbox/preview/build/deploy state; the live result surface |
230
+ | **P5 Iteration** | the follow-up/edit endpoint (often surprisingly named) + any auto-iteration loop |
231
+ | **P6 Synthesis** | reconcile into the dimension's `_summary.md` + `captures/` + `curls.md` |
232
+
233
+ ### 9.4 Runtime taps (Pass-1 instrumentation, run in-page)
234
+
235
+ - **WebSocket / EventSource / fetch+XHR interceptors** — wrap the constructors/methods to log
236
+ URLs, frames, and bodies (shapes, not secrets — redact in the wrapper before anything reaches
237
+ disk). Add a `SCRUB(value)` step inside the fetch wrapper so credentials never reach the harness.
238
+ - **Storage shape inspector** — enumerate localStorage / sessionStorage / cookies / IndexedDB
239
+ **key names + lengths**, never raw values.
240
+ - **JWT decoder** — decode the token *structure* (alg, claim names, exp) with identity claims
241
+ (`sub`, `email`, `phone`, `user_id`, `uid`, `sid`) redacted.
242
+ - If a Pusher/realtime SDK is loaded, bind a global listener to capture the event catalog.
243
+
244
+ ### 9.5 The capture contract (richer than a standard dimension dump)
245
+
246
+ Under `research/<target>/dimensions/session/`:
247
+
248
+ - **`captures/p*.md`** — per-phase narrative for the human: frontmatter (title, summary, scope,
249
+ status), **Method** (taps run, actions taken), **Findings** (concrete values — URLs, fields,
250
+ status codes), **Inferences**, **Diff vs reference**, **Open questions**. Decoded, opinionated;
251
+ don't paste raw bodies here.
252
+ - **`raw/*.json`** — verbatim endpoint captures for the reproducer: a `_meta` header
253
+ (endpoint, auth-shape, captured_at, status, byte_length, redactions) + `body` (PII + secrets
254
+ redacted) + `_decoded_fields`. Digest bodies > 50 KB into a structured summary.
255
+ - **`curls.md`** — reproducible curl per endpoint, the auth model documented, a variables block,
256
+ and an endpoint-catalog table.
257
+ - **`_summary.md`** — the standard dimension bridge file (provenance frontmatter per §2) pointing
258
+ into the above, so Evaluation treats session like any other dimension. `method: session-playbook`,
259
+ `confidence: low` for Pass-1-only/inferred.
260
+
261
+ ### 9.6 Session ethics (binds hardest here — see §7 above)
262
+
263
+ Never enter credentials; storage shape not values; redact every secret **inside the tap wrapper**
264
+ before it reaches disk; **confirm before any Pass-2 state change or cost** (exact action + exact
265
+ cost); no destructive actions; no bypassing the harness (redact, never evade); captures stay local;
266
+ respect TOS. The provenance/redaction rules in §1–8 apply to everything written here.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nurix/etna",
3
- "version": "0.15.2",
4
- "description": "Bootstrap a project with a Nurix harness — installs a Claude Code plugin from the nurixlabs/skills marketplace and drops the harness's CLAUDE.md at the project root.",
3
+ "version": "0.15.3",
4
+ "description": "Bootstrap a project with a Nurix harness — copies the harness's CLAUDE.md, skills, agents, rules, and hooks directly into the project from a bundled payload (no marketplace fetch, no network).",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "etna": "bin/etna.js"