Skip to content

insights.jsonl

The side-car explain writes: one explanation record per operation, type and module, in the vocabulary of the Specy domain metamodel. It lives beside the model — <model>.insights.jsonl by default — and never inside it, so it can be regenerated, pointed at another model, or deleted without touching model.jsonl or model.db.

This page is derived from the Zod schemas in packages/insights/src/schema.ts and the vocabularies in packages/insights/src/ddd.ts. Unlike the other artifact pages it carries no excerpt from a real run: producing one requires a model provider and an API key.

File layout

header → i* → f* → eof

f lines are the units a run asked for and could not explain; a side-car with none has no f line. A reader that only wants explanations keeps the t:"i" lines.

Records are sorted by (level, id), with operation before type before module, and are re-serialized through their Zod schema, so a record built in memory and one read back from disk are the same bytes. The body carries no timestamp; only the trailer does. Two runs with the same records are therefore diffable: what changed is what was re-explained.

During a run, finished records are appended one per line to <out>.journal and the sorted side-car is rewritten from base plus journal at each layer boundary, so an interrupted run resumes where it stopped. Reading a journal is lenient (its last line may be cut); reading the side-car proper is strict.

header

FieldTypeMeaning
t"header"
kind"codegraph.insights/1"
generatedBystring@codegraph/insights
promptVersionstringbumped whenever the prompt or a block shape changes; every fingerprint includes it
metamodelstringthe vocabulary the blocks speak — specy.domain/3
models{leaf, rollup}the model slug used for operations, and for types and modules
providerstringwhich client served the calls (openrouter, cloudflare); absent on files written before it was recorded
depthinteger ≥ 0how many levels of dependency explanations each prompt carried
source{paths, langs, view}the models explained, their languages, and the view

i — one insight record

FieldTypeMeaning
t"i"
idnon-empty stringthe rendered entity id — compared as an opaque token, never parsed
key{lang, module, symbol, disambiguator?}the natural key, carried so a re-extraction re-joins without parsing ids
level"operation" | "type" | "module"the discriminant; decides which block shape follows
kindstringthe entity kind
namestring
filestringthe anchor file, root-relative
sccstring[]present when the unit sits in a dependency cycle: every member, sorted, this id included
origin"llm" | "template"
blockOperationBlock | TypeBlock | ModuleBlockthe explanation itself
fingerprint64-char hexsha256 of everything the explanation was computed from
modelstringthe model slug that answered
usage{promptTokens, completionTokens, cost?}
metadataRecord<string, string>the metamodel convention’s free key/value map

f — one failure record

A unit left without an insight record, and why. It exists exactly as long as the gap: a run that explains the unit drops it, a run that fails again replaces it with attempts + 1, a run that did not attempt the unit (--scope, --max-calls) carries it over. explain --retry-failed takes its scope from these lines. Sorted like the records; no timestamp.

FieldTypeMeaning
t"f"
idstringthe unit id — its first member’s rendered entity id, opaque
key{lang, module, symbol, disambiguator?}that entity’s natural key, when known
leveloperation | type | module
membersstring[]every entity the unit would have explained, sorted; more than one means a dependency cycle
modelstringthe model that was asked
reason.kindprovider | invalid-answer | errorthe call was refused or never answered · two answers in a row failed validation · anything else
reason.messagestringthe provider’s or the validator’s own words, verbatim
reason.statusinteger, optionalthe HTTP status, when the provider gave one (400 the prompt does not fit, 429 rate-limited after every back-off…). 401/402/403 also abort the run: only the unit that received it gets a record
reason.retryableboolean, optionalthe client’s verdict on asking again at once; a later run may well succeed (credits added)
attemptsinteger ≥ 1consecutive runs that attempted this unit and failed
callsinteger ≥ 0model calls the last attempt made
usage{promptTokens, completionTokens, cost?}, optionalwhat those calls spent
{"t":"f","id":"java:org.broadleafcommerce.core.web.expression.checkout","key":{"lang":"java","module":"org.broadleafcommerce.core.web.expression.checkout","symbol":""},"level":"module","members":["java:org.broadleafcommerce.core.web.expression.checkout"],"model":"openai/gpt-5.6-luna","reason":{"kind":"provider","message":"This request requires more credits, or fewer max_tokens. …","status":402,"retryable":false},"attempts":1,"calls":0}

eof

FieldTypeMeaning
t"eof"
counts{records, llm, template, reused, failed}all integers ≥ 0; failed is the number of f lines
usage{promptTokens, completionTokens, cost?}the run’s total
generatedAtISO-8601 stringthe ONLY timestamp in the file

Blocks

Every block carries a name — the ubiquitous-language name the model proposes — a description, and a confidence number clamped to [0,1] on receipt.

OperationBlock

FieldType
name, descriptionstring
safeboolean — read-only (no state mutation) or not
idempotentboolean | null
ownerone of OPERATION_OWNERS
handlesCommandstring | null — the command this operation handles, when it is a command handler
emits{name, kind}[] where kind is an EVENT_KINDS member
preconditions{name, predicate, violationReason}[]
postconditions{name, predicate}[]
invariantsEnforcedstring[]
usesSpi{name, capability}[] — external capabilities the operation needs, as SPIs
domainTermsstring[]
confidencenumber

TypeBlock

FieldType
name, descriptionstring
conceptone of DOMAIN_CONCEPTS
eventKindEVENT_KINDS member | null
interfaceRoleINTERFACE_ROLES member | null
aggregateRootboolean | null
containedInstring | null
syncPatternSYNC_PATTERNS member | null
identitystring | null — the identity field, for entities
fields{name, type, kind}[] where kind is a FIELD_KINDS member
invariants{name, predicate, enforcement}[] where enforcement is an ENFORCEMENTS member
stateMachine{states, transitions: {from, to, operation}[]} | null
relatesTo{name, concept}[]
exposesstring[] — operations that form this type’s public surface
dependsOn{name, role}[] — ports this type needs from others
domainTermsstring[]
confidencenumber

ModuleBlock

FieldType
name, descriptionstring
apis{name, operations: string[]}[]
spis{name, capability}[]
dependsOnstring[]
concepts{name, concept}[]
boundedContextHint{name, rationale} | null
sharedKernelHintstring | null — for a module in a dependency cycle: why the group is inseparable, or how to split it
ubiquitousLanguage{term, definition}[]
confidencenumber

Vocabularies

Closed enums, restated as literals in ddd.ts with the source cited.

VocabularyMembers
DOMAIN_CONCEPTSboundedContext, module, interface, operation, command, query, reaction, entity, readOnlyEntity, aggregate, stateMachine, repository, event, valueType, enum, domainService, applicationService, infrastructureService, invariant, precondition, postcondition, agreement, reconciliation, notDomain, unknown
EVENT_KINDSinternal, external, error, temporal
INTERFACE_ROLESAPI, SPI
OPERATION_OWNERSentity, aggregate, domainService, applicationService, infrastructureService, repository, valueType, unknown
ENFORCEMENTSrejection, compensation, alert
SYNC_PATTERNSsynchronous-query, asynchronous-projection
FIELD_KINDSprimitive, valueType, entityReference, enum, collection, unknown

Strict structured output

Providers’ strict structured-output mode requires every property to be required and no additional properties, so “optional” is expressed as .nullable(), never .optional(), and no numeric or string constraints are emitted. confidence is clamped on receipt rather than constrained in the schema.

Fingerprints

Every record carries a sha256 over what it was computed from: the prompt version, the model slug, the level, the source slices, the comments, the signatures, a digest of the facts shown, the fingerprints of the units it depended on, and the ids of dependencies that had no record. Merkle-style: change one leaf’s source and exactly its transitive dependents and containers change.

The explanation text is deliberately not hashed — a non-deterministic answer must never cascade re-runs. A re-run plans reuse for every unit whose members’ records match; --force overrides. Because a missing dependency is part of the fingerprint, a dependent explained while its callee had failed or was out of scope is redone once the callee exists.

Templated records

A getter, setter, equals/hashCode/toString/compareTo, or a field-assigning constructor is described by a template with origin: "template", confidence 1 and no model call — decided from facts only: no throw site, no corpus call, cyclomatic ≤ 1, and at most one field touched. Anything with a throws fact or a corpus call is never trivial, however short.

Last updated on