Expand description
Prompt ingestion as a local provider (ADR 0006).
The one input CGP never disciplined is the largest: the text a user pastes into a prompt. A realistic turn mixes four different things under one blob — a log, a table, a directory reference, and the actual ask — and only the last is intent. Pasted whole, it is re-sent verbatim every turn (no cache, no dedup), its cost is never accounted, nothing is content-addressed, and the model is handed material it must itself decide is mostly irrelevant.
This module is the ingestion-side dual of compose_context:
host-side reference behavior, not wire protocol. It turns a paste into an
ordinary ContextProvider:
- intent passes through verbatim as
ContextQuery::goal— the one thing the mechanism must never rewrite; - directory references become
ContextQuery::anchors(zero tokens; the graph provider resolves them better than pasted text could); - evidence (logs, tables, code, notes) becomes content-addressed frames,
served
compactby default with the full bytes retrievable losslessly by re-querying forfull.
The guarantee is not “zero wasted tokens” — relevance is only knowable
downstream. It is bounded default cost with lossless retrieval: the model
sees a distilled, budgeted rendering; the full bytes stay content-addressed
and pullable. Every emitted frame is honest by construction — token_cost
and the inline content_digest are recomputed for the exact representation
served (§B3), and every frame satisfies its
representation_invariants.
§Classification precedence
classify walks a ladder from the least ambiguous shape to the most, and
the order is load-bearing rather than incidental — several of these shapes
can imitate each other:
- a fenced
```region →Code(the user drew the box themselves); - a lone path-shaped token →
PathRef; - an exception header plus stack frames →
StackTrace; - a timestamped log — half the lines open with a clock and some line
carries a level token — →
Log, deliberately ahead of table detection, because a pipe-delimited log (ts | LEVEL | msg) otherwise reads as a table purely for sharing a delimiter count; - an explicitly delimited table (
|, tab, comma) →Table; - a weaker log (level tokens or bracketed prefixes, no timestamps) →
Log; - a whitespace-aligned table →
Table, the weakest tabular signal and therefore the last one tried: the two spaces after a paddedINFOlook exactly like a column break; - unfenced but code-shaped lines →
Code; anything left isProse.
§Known limits
Heuristics this cheap misread things, and the misreads below are accepted
rather than unnoticed. None of them can produce a dishonest frame — cost,
digest, and provenance are computed from the bytes actually emitted whatever
the kind — and every one of them is visible in the SegmentReport pill, so
a host UI can offer the correction rather than the user discovering it later:
- A CSV of sentences reads as prose. Comma detection requires cells that
read like values (see
MAX_CELL_WORDS), because English is full of commas. The block still becomes a verbatimdocframe — losing the column summary, not the evidence. - A scheme-less
example.com/path.rsstill reads as an anchor. A hostname-shaped first segment is now rejected (looks_like_path), soexample.com/pathis prose; but a token ending in a source extension is taken as a path, because in a workspace paste that is overwhelmingly what it is. - Syslog and bare clocks identify a log but never bound it.
Jul 20 18:00:01names no year and18:00:01names no day; F4 has no spelling for “no date”, so the line counts as timestamped for classification whilevalid_from/valid_tostay empty rather than carry an invented instant. - A zone-less timestamp is read as UTC. See
zone_is_utcfor why that assumption is the honest one and a numeric offset is refused instead.
Structs§
- Ingest
Bundle - The result of
ingest_paste: a ready-to-fan-out query, the local provider that answers it, and the classification report. - Ingest
Config - Knobs for
ingest_paste. - Ingest
Provider - A local, egress-free
ContextProviderserving one paste’s evidence. - Paste
Ingest - A user’s paste, decomposed into the three things it actually is.
- Segment
Report - One line of the ingestion report: what a segment was classified as and what it became. Surfaced so a host never transforms input invisibly.
Enums§
- Segment
Kind - The classification a segment received. Deterministic and heuristic — the
same posture as
validate.rs, reproducible from the bytes alone. - Segment
Outcome - What one classified segment became — the payload of a
SegmentReport, and the “visible and correctable” surface a host UI renders as a pill.
Constants§
- DEFAULT_
PROVIDER_ ID - Default provider id / consent key for an ingested paste.
Functions§
- ingest_
paste - Turn a decomposed paste into a query + a local provider + a report.