id-377 research — declarative surface inventory (agent sweep)
Declarative / declared-as-data surface inventory
Section titled “Declarative / declared-as-data surface inventory”Read-only agent sweep of scripts/ (tests excluded), commissioned for
{377.4}. Verbatim findings; the companion design note
(declarative-write-surfaces.md) records which of these v1 handles.
Verdict on the flow.py _insert_*_row raw-SQL mirrors — already visible
Section titled “Verdict on the flow.py _insert_*_row raw-SQL mirrors — already visible”All six are plain inline string literals (implicit concatenation folds to a
single ast.Constant) passed as the first positional arg to
conn.execute(...):
| Function | def | conn.execute | Table | INSERT cols |
|---|---|---|---|---|
_insert_content_chunk_row | flow.py:2953 | flow.py:2975 | content_chunks | 8 ($7::vector) |
_insert_record_embedding_row | flow.py:2997 | flow.py:3012 | record_embeddings | 4, ON CONFLICT (owner_kind, owner_id, model) |
_insert_entity_mention_row | flow.py:3025 | flow.py:3046 | entity_mentions | 9 ($8::jsonb) |
_insert_entity_relationship_row | flow.py:3069 | flow.py:3085 | entity_relationships | 6 |
_insert_qa_extraction_row | flow.py:3101 | flow.py:3127 | q_a_extractions | 12 ($11::jsonb) |
_upsert_source_document | flow.py:2671 | flow.py:2809 | source_documents | 26, ON CONFLICT DO UPDATE SET 21 |
Caveat: the five _insert_* helpers take conn: Any as a PARAMETER
(acquired once at flow.py:3260 in ingest_once, passed down). Attribute-name
matching on {execute, fetch, …} still fires; a detector that first proves
the receiver is an asyncpg connection will not.
Other cocoindex declarative write APIs in use
Section titled “Other cocoindex declarative write APIs in use”localfs.declare_file(...)— a SECOND declarative write surface: 6 sites in producer/bundle_writer.py (:367, :690, :1051, :1090, :1141, :1366). Same declare-and-reconcile model as declare_row, but for markdown bundle FILES, not Postgres columns (orphan-delete semantics at bundle_writer.py:39-53). Relevant only if lineage ever covers file artefacts.TableTarget.declare_vector_index(...)deliberately NOT used (rationale flow.py:4150-4158 — out-of-band DDL). No KTable/collector.export(), nodeclare_dir_target._coco_api.pyis a PEP 562 lazy re-export façade: runtime imports are invisible (__getattr__+_SYMBOL_SOURCESdict :55-78); the realfrom cocoindex... importlines exist only insideif TYPE_CHECKING:(:121-137). Name-based collection (not import-graph resolution) is the only shape that sees through it.
Declared-as-data DB access beyond TableSchema/mount/declare_row + _SQL_* consts
Section titled “Declared-as-data DB access beyond TableSchema/mount/declare_row + _SQL_* consts”- Column lists as comma-joined string constants interpolated into SQL
(l_records.py):
_QA_COLUMNS:390 (13 q_a_pairs cols),_SOURCE_DOCUMENT_COLUMNS:425 (16 source_documents cols),_QA_WON_COLUMNS:539 (a constant interpolating another constant). Interpolation sites :397, :414, :433, :438, :545. [v1: resolved by the order-respecting module-const f-string resolution.] - Genuinely dynamic SQL (l_records.py): :1110-1121 conditional
tuple-unpack + computed placeholder index; :1315-1316/:1322-1323
f"{CONST} LIMIT $2"[v1: the latter resolve; the former stay caveated]. Query selection additionally gated by client-authored concept-feeder.json (:781-790 → :1100, :1168, :1318). - supabase-py with
ClientOptions(schema="api")— bid_worker.py:104: everyfrom_("t")resolves toapi.t(view mirror), notpublic.t. Payloads built as list comprehensions (:490-501 → :503 upsert 8 cols; :526-545 → :546 insert 15 cols);on_conflict=carries column names as a comma string (:505);.order("created_at"):199 is a read-side column mention in a modifier only. - Row-mapping subscript reads with no SQL in-file: url_source.py (11 sites), server.py (5), canonicalisation.py:376-377 (rows arrive as a parameter; originating SELECT at flow.py:4504); canonicalisation.py:299, 319-327 reads the entity_aliases shape from a JSON snapshot fixture.
- Stored procs — visible SQL, zero column tokens: flow.py:2655
(
resolve_or_mint_source_identity, mints/updates source_documents), writer_fence.py:137/:161, bid_worker.py:783 (claim_next_job→ processing_queue). [The pg_proc-scan follow-up’s surface.] - Named SQL const outside l_records: url_source.py:64-69
_PASSED_URLS_SQL, consumed by name at :196. [v1: resolved.] - Non-SQL routes into the write path: verify_driver.py:206-212 POSTs to
/stage; server.py:1449-1452 route registry; server.py:834-836/:1191 engine kick via thread dispatch. - Confirmed absent tree-wide: executemany, copy_records_to_table, CSV/COPY, pandas.to_sql, psycopg, sqlalchemy, raw PostgREST, psql/supabase subprocesses.
- Structural finding:
sd_targetis mounted (flow.py:3907) but NOsd_target.declare_rowexists — every source_documents write goes through raw SQL in_upsert_source_document(rationale flow.py:2720-2784), which writes 26 columns vs the schema’s declared 22 (adds logical_path, admission_status, retention_class, origin_type). “Mounted” ≠ “written declaratively”; declared-column sets can be deliberate SUBSETS with omission semantics (GENERATED ALWAYS / PG defaults, flow.py:1420-1437).
Hard cases for a static resolver (25)
Section titled “Hard cases for a static resolver (25)”**kwargsabsorption erasing the param name across 4 hops — producer/trigger.py:137- Dispatch through a function-valued parameter — producer/trigger.py:158
- Lazy in-body imports breaking the module import graph — producer/embed.py:133-135 (also flow_def.py:374-376, trigger.py:117-119)
*targetssplat with arg↔param binding set by argument ORDER at a mount_each the engine replays — flow.py:4030 (order bound :4059-4069)- Mount inside a closure stored in a module global, executed elsewhere — server.py:1152 (stored :1171, run :1191)
- Cross-module schema-constant reference — server.py:1152 (
flow.RECORD_EMBEDDINGS_SCHEMA) [v1: handled via attribute-name candidates] declare_row(row=row)payload built in a loop into a dict — flow.py:2480 (dict literal :2466-2478) [v1: handled via scope-dict fallback]**spread inside a jsonb column’s value — flow.py:2408- Column list as comma-joined string constant in SQL — l_records.py:397 [v1: handled]
- Constant interpolating another constant — l_records.py:539-542 [v1: handled]
- Conditional tuple-unpack SQL + computed placeholder index — l_records.py:1110-1121 [caveated]
- Module-level named SQL const passed by name — url_source.py:196 [v1: handled]
- Mounted target never declared onto; raw SQL writes a LARGER column set — sd_target flow.py:3907 (22) vs :2809 (26)
- Declared columns deliberately a SUBSET; omission carries semantics — flow.py:1420-1437
- List-comprehension payload to supabase .insert/.upsert — bid_worker.py:546
- Column names only in an
on_conflict=string — bid_worker.py:505 - Column names only in a chain modifier — bid_worker.py:199
- Stored-proc call: visible SQL, zero column tokens — flow.py:2655 [caveated: sqlFunctionSourceSites]
- Column reads with rows arriving as a parameter — canonicalisation.py:376-377
- Schema shape read from a JSON fixture — canonicalisation.py:299, 319-327
- Connection as a function parameter, not a module pool — flow.py:2953
- PEP 562
__getattr__façade; real imports only underif TYPE_CHECKING:— _coco_api.py:55-78 vs :121-137 - ColumnDef encoder callable changing the wire type — flow.py:1469-1473 (
_encode_pgvector) - Star-splatted parameter tuple built earlier — qa_dedup_proposer.py:446
- One physical declare_row serving three owner_kinds from three modules — flow.py:1505, fed by flow.py:2250, flow.py:3724, producer/embed.py:137