@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.
- package/README.md +16 -13
- package/bin/etna.js +8 -20
- package/data/harness-index.json +2 -1
- package/data/harnesses/code/CLAUDE.md +1 -15
- package/data/harnesses/code/agents/brainstorm.md +0 -1
- package/data/harnesses/code/agents/change-review.md +0 -1
- package/data/harnesses/code/agents/harness-manager.md +0 -1
- package/data/harnesses/code/agents/maintenance.md +0 -1
- package/data/harnesses/code/agents/performance-review.md +0 -1
- package/data/harnesses/code/agents/spec-mode.md +0 -1
- package/data/harnesses/code/harness.json +2 -2
- package/data/harnesses/code/rules/general.md +0 -1
- package/data/harnesses/code/rules/nomenclature.md +0 -1
- package/data/harnesses/code/skills/boundary/SKILL.md +0 -1
- package/data/harnesses/code/skills/brainstorm/SKILL.md +0 -1
- package/data/harnesses/code/skills/distiller/SKILL.md +9 -6
- package/data/harnesses/code/skills/documentation/SKILL.md +0 -1
- package/data/harnesses/code/skills/workflow-mapper/SKILL.md +0 -1
- package/data/harnesses/kb-agi/CLAUDE.md +0 -15
- package/data/harnesses/kb-agi/agents/kb-agi-init.md +0 -1
- package/data/harnesses/kb-agi/agents/kb-catch-stale.md +0 -1
- package/data/harnesses/kb-agi/agents/kb-find-gaps.md +0 -1
- package/data/harnesses/kb-agi/agents/kb-fix-links.md +0 -1
- package/data/harnesses/kb-agi/agents/kb-refresh-frontdoor.md +0 -1
- package/data/harnesses/kb-agi/agents/kb-refresh-summaries.md +0 -1
- package/data/harnesses/kb-agi/agents/kb-sync-metadata.md +0 -1
- package/data/harnesses/kb-agi/harness.json +1 -1
- package/data/harnesses/kb-agi/rules/kb.md +0 -4
- package/data/harnesses/re/CLAUDE.md +139 -0
- package/data/harnesses/re/agents/api.md +52 -0
- package/data/harnesses/re/agents/codebase.md +63 -0
- package/data/harnesses/re/agents/community.md +47 -0
- package/data/harnesses/re/agents/deployed-client-bundle.md +94 -0
- package/data/harnesses/re/agents/distribution-artifacts.md +97 -0
- package/data/harnesses/re/agents/docs.md +49 -0
- package/data/harnesses/re/agents/infra-backend-fingerprint.md +97 -0
- package/data/harnesses/re/agents/packages.md +48 -0
- package/data/harnesses/re/agents/session.md +55 -0
- package/data/harnesses/re/agents/website.md +50 -0
- package/data/harnesses/re/agents/wire-capture.md +91 -0
- package/data/harnesses/re/harness.json +6 -0
- package/data/harnesses/re/rules/re-discovery.md +266 -0
- package/data/harnesses/re/rules/re-evaluation.md +100 -0
- package/data/harnesses/re/rules/re-ingestion.md +266 -0
- 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,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."
|