source-discovery
The procedure behind the source-discovery
rule. Hand-off target from think-before-action
when a task touches external or expensive structure. Definitions
(Evidence Report buckets, provenance, trust tiers, the DB-not-in-codebase
boundary, the card-worthiness threshold) live in
evidence-discipline —
read it once; this file is the executable procedure.
When to use
Before you plan or code against a structure you have not confirmed this session: a DB schema, an API/GraphQL shape, a DTO/Model/Entity, a vendor package's surface, or any field/endpoint/column/value.
Do NOT use for: trivial edits (rename/typo/format), structure already verified
this session, or when the user supplied the verified structure (gate-skip per
rdp-gate).
The shape of a run
discover the real source → Evidence Report (Verified / Assumed / Gaps) → plan → act → verify with the real tool
Scaffold the report cheaply so it never gets skipped:
npx tsx node_modules/@event4u/agent-config/src/scripts/evidence_report.ts git-state # fail-fast: abort if a rebase/merge/cherry-pick is in progress
npx tsx node_modules/@event4u/agent-config/src/scripts/evidence_report.ts init --task "<task>" # writes the gitignored session report
npx tsx node_modules/@event4u/agent-config/src/scripts/evidence_report.ts add --bucket verified --claim "users.email is unique" --source "db/schema/users.sql:23"
Provenance on every item (observed_at / source / version). Within a
session a read is fresh until the file's mtime changes; invalidate all session
reads when git rev-parse HEAD changes; across sessions always re-read.
Step 0 — Resolve local structure fresh (NO persistent index)
Resolve name → path fresh each lookup with rg / glob, then read the file
fresh. There is no persistent bootstrap index (a measured rg-latency
problem on a large monorepo is the only thing that would justify one — deferred).
rg -n "class User\b|model User|CREATE TABLE .*users" --type-add 'src:*.{php,ts,js,py,go,rb,sql}' -t src
Procedure — discover and analyze each surface before planning
- Identify which surface(s) the task touches (DB / API / vendor / DTO).
- Discover the real source via the matching sub-procedure below — local before remote, analyzing the actual definition, never memory.
- Record each fact into the Evidence Report with provenance, then build the plan from the report.
A. DB schema — in-codebase = LOCAL, read fresh, no card
In-codebase (schema defined by repo migrations / models / ORM / app code,
including schemaless stores the app controls — Mongoose / Prisma / Firestore
rules) → always local & fresh. Dump tables, columns, types, primary/foreign/
unique keys, indexes, relations, and derived filter/sort/group-ability into the
session cache with provenance — framework-neutral (MySQL / Postgres / SQLite;
ORM-agnostic). The migration is intended truth, the live DB is actual;
divergence is a drift signal worth surfacing. Only negative facts graduate to
a committed card (see database for the dump procedure).
B. API / GraphQL — probe + confirm
Resolve an OpenAPI/Swagger spec or GraphQL introspection from config/task first.
Else run a read-only, idempotent GET probe, reduced with jq — never a full
dump, never a write/stateful call, never prod without permission, secrets-aware
per security-sensitive-stop. A probed
positive shape is trust: low ("Assumed (from card)" if card-sourced) and must
be confirmed against the live surface before use.
C. Vendor / external-DB docs — card-worthy
Card-worthy = (external package / remote API / DB-not-in-codebase) AND (≥3
distinct methods/fields intended to be used, OR the source exposes >50 methods
and ≥1 is used, OR a prior hallucination on it, OR local types/README are
insufficient) — judged on intended use at discovery (still built before
coding). For a card-worthy dependency named in the task: local-first
(node_modules / vendor/ README + type defs; the installed version is ground
truth), then the net (registry → repo host → homepage). Pin the remote ref to
the installed version — never blind main. Reuse
external-reference-deep-dive +
markitdown; honor source-confidentiality,
untrusted-input-defense, lethal-trifecta-guard. Persist via the
knowledge-card template under agents/knowledge/<source>.md.
D. DTO / Model / Entity — local, read fresh
Resolve and read the actual class fresh (Step 0). In-codebase → local, no card.
E. Global cards — leads only (v2, ADR-100)
When knowledge.global_sharing.enabled (user-global, default on), a matching
card may exist in the per-user file-first store
(~/.event4u/agent-config/knowledge/), promoted from another project. It is a
lead, never a build input:
- Load its negative facts + pointers as usable leads (
trust: durable). - Load any positive structure into the Evidence Report under "Assumed
(from card · GLOBAL, unverified)" — record it with
evidence_report.ts add --bucket assumed --origin global …and re-confirm it against the live source this session before use (version skew / schema drift across projects). Never "Verified" on the global card alone. - A
public/vendorcard seen in ≥auto_promote_thresholddistinct repos triggers a one-tap promotion suggestion (never silent).proprietarycards are manual-only and never auto-shared. Record sightings via_lib/knowledge_global_promote.ts record-seen.
Missing structure → fixed extension workflow
When the field/endpoint/table you need is not there:
- Search the relevant sources.
- Not found — record the absence-search log with
searchedandnot_searched(viaevidence_report.ts add --bucket gaps --searched … --not-searched …). - Negative-fact card — only after the search is exhausted across all
relevant sources for that claim: write
type: anti-hallucination,polarity: negative, withactionable+next_step+ arevalidate_iftrigger ("an OpenAPI spec / contracts dir is added"). A negative fact is a current-state fact ("searched X, didn't find X") — not a card-worthiness decision (that belongs in notes/ADR). - Extension plan — a codebase-fitting plan (migration + model/cast/factory/
seeder, or the stack equivalent). Plan only, never silent execution
(
scope-control).
Verify after acting (Phase-3 wiring)
After acting on discovered structure, verify with the real tool per the
think-before-action matrix — curl /
Playwright / debugger / test runner / DB query. Any Assumed (from card) or
trust: low line used without this-session confirmation is a violation surfaced
post-task. A stale card (installed-version mismatch OR last_verified older than
N days) is lead-only: negative facts + pointers stay usable, positive
structure must be re-confirmed. Green is not a correctness proof — high-risk /
irreversible steps verify regardless.
Output
The Evidence Report (gitignored session cache), three buckets, soft-capped to ~10–20 decision-relevant facts, produced before the plan; plus, where the threshold is met, a thin committed card.
Evidence v2 — self-building context (heuristics only, never a bypass)
Curated project-intelligence (Class A config digests, Class B observed
conventions, Class C learned lessons) may be loaded to inform where to look and
what convention to expect — but it is read for heuristics only and never
bypasses a fresh structural read. A field/endpoint/column/value is still confirmed
against a live source this session. v2 capture is write-only into gitignored
intake (the agent may suggest a signal, never silently commit); trust and
commit are always human-gated. Full model + the three classes + memory tiers:
project-intelligence.
Knowledge capture (api_shape_learned / convention_detected events)
A confirmed API/GraphQL shape (§B) or an observed coding convention with ≥ 2 supporting locations is worth persisting for the team, distinct from the per-session Evidence Report above. Append to the knowledge intake — never write a tracked page mid-task:
npx tsx node_modules/@event4u/agent-config/src/scripts/emit_knowledge_event.ts --type api_shape_learned \
--endpoint "<path>" --method "<verb>" --request-schema '<json>' --response-schema '<json>'
npx tsx node_modules/@event4u/agent-config/src/scripts/emit_knowledge_event.ts --type convention_detected \
--pattern "<pattern>" --evidence "file:line" --sample-size <N> --scope project
/team-knowledge consolidate turns accumulated events into
agents/knowledge/concepts/ pages as a reviewed batch — see
knowledge-pages.
Gotchas
- A card's positive structure is never "Verified" on the card alone — it is "Assumed (from card)" until confirmed this session (R4 P1).
- L0–L4 depth labels are documentation only — the same evidence rules apply at every tier; no per-tier relaxation.
- The self-log is instrumentation; the deterministic teeth are pointer-CI + the eval. Do not treat a written "verified" as proof.
Do NOT
- Do NOT plan or code against an unconfirmed field/endpoint/column.
- Do NOT treat a card as a source of truth or a build input.
- Do NOT execute a schema/API extension silently — plan, then hand back.
- Do NOT read an intermediate tree mid git-op — fail-fast.