Example

Keep derived, external and model content apart

Give every item beside a source a layer fixed by the door it came through, and see a forged item caught on the way back out.

Material that sits beside a source is not the source, and the chapter’s claim is that the difference has to be structural rather than a matter of careful wording. A producer cannot declare its own layer: the layer is fixed by the constructor that made the item, and the constructor is fixed by the mechanism that produced it. A value chosen by the party being inspected cannot gate the inspection.

Run it

git clone https://github.com/ernanhughes/project-language.git
cd project-language
git checkout 329660f679a5a87831f91fe1430c20ac9360dda8
npm ci
npm run example:ch08

No model is called. The model answer in the run is produced by a scripted stand-in, and the ledger’s events are supplied by hand.

Expected outcome

Three items, three layers, and the only status that asserts nothing is re-presented:

...
[DERIVED FROM THE SOURCE · re-presented, not new]  sc_05fa46e512ab2ad3
  It relies on the well-known impossibility result.
  source systems-paper 9cba8f2b2f96…: "It relies on the well-known impossibility result."

[FROM ELSEWHERE · candidate, not verified]  sc_f23fba7bb7419fac
  No deterministic consensus protocol tolerates a single crash in an asynchronous system.
  from flp-1985 c0df5ce0c3a4…

[MODEL ANSWER · candidate, may be wrong]  sc_ac983bc0d023373a
  The theorem assumes an asynchronous system; this paper assumes partial synchrony, so it may not apply.
  produced by scripted-model; drew on sc_05fa46e512ab2ad3, sc_f23fba7bb7419fac
  limits: A reading of two short passages. Not checked against the theorem's proof.

A quotation the source does not contain cannot be presented as derived from it, and an item that was edited or built by hand is caught when it comes back out of storage:

...
refused: the quoted passage is not in the source
problems: LAYER_KIND_MISMATCH, ID_MISMATCH, STATUS_OVERCLAIMS

The limits rule is lexical, and the run says so on its own output:

...
first attempt, limits "None." → Not placed: LIMITS_VACUOUS: "none" and its relatives are not a statement of limits; LIMITS_TOO_SHORT: be specific: at least a short sentence; LIMITS_NO_LIMITING_CONSTRUCTION: say what it is not, what it rests on, or what it assumes

The layer is fixed by the constructor

The map from the mechanism to the layer is the whole structural rule. It is a constant, not a field a producer fills in:

export type Layer = "SEMANTIC_DERIVATION" | "EXTERNAL_EVIDENCE" | "MODEL_GENERATION";
export type ItemKind = "derived" | "retrieved" | "interactive";
/** "re-presented" asserts nothing the source did not say. Everything else is a candidate. */
export type ItemStatus = "re-presented" | "candidate";

export const LAYER_OF: Readonly<Record<ItemKind, Layer>> = {
	derived: "SEMANTIC_DERIVATION",
	retrieved: "EXTERNAL_EVIDENCE",
	interactive: "MODEL_GENERATION",
};

And what a derived item carries is the quotation, verbatim. The system’s own reading of it travels separately, as a labelled gloss, so an unsupported claim cannot be given the derived label by being written into the content:

export function derivedItem(source: TextDoc, quote: string, producer = "derivation", gloss?: string): SidecarItem {
	if (quote.trim() === "") throw new SidecarError(["EMPTY_CONTENT"], "a derived item needs the passage it re-presents");
	if (!source.content.includes(quote)) throw new SidecarError(["ANCHOR_NOT_IN_SOURCE"], "the quoted passage is not in the source");
	return seal({
		kind: "derived",
		layer: LAYER_OF.derived,
		status: "re-presented",
		// What is re-presented is the quotation, verbatim. Nothing else can carry the derived label.
		content: quote,
		anchor: { source_id: source.id, source_sha256: sha256(source.content), quote },
		origin: { producer },
		drew_on: [],
		...(gloss !== undefined && gloss.trim() !== "" ? { gloss } : {}),
	});
}

The limits rule is worth reading as a whole, because it is honest about what it does not do:

export function checkLimits(limits: string, prior: readonly string[] = []): SidecarProblem[] {
	const n = normalise(limits);
	if (n === "") return ["LIMITS_MISSING"];
	const out: SidecarProblem[] = [];
	if (VACUOUS.test(n)) out.push("LIMITS_VACUOUS");
	if (n.split(" ").length < 5) out.push("LIMITS_TOO_SHORT");
	if (!LIMITING.test(n)) out.push("LIMITS_NO_LIMITING_CONSTRUCTION");
	if (prior.some((p) => normalise(p) === n)) out.push("LIMITS_BOILERPLATE");
	return out;
}

Mechanism and limitations

Documented: the three layers, the rule that a producer cannot declare its own layer, and the gloss/content split are stated in the module’s own header comment in core/sidecar/src/index.ts.

Observed: the run above — a derived item’s content equals its quotation, a retrieved item carries its origin pinned by hash, a model answer arrives as a candidate with limits, a quotation absent from the source is refused, and a forged item is reported with three problems on the way out.

Not shown. The limits rule checks specificity, not honesty: “This answer may be fully trusted without any checking at all.” passes it. The item id shows integrity, not authorship. The ledger counts the events it is given, and the adapter emits only shown, used and dismissed — the run’s distracting count is supplied by hand, so nothing here measures a reader. The margin is capped, so it cannot be flooded. Nothing notifies, and nothing is added to the system prompt.

Canonical source and the sidecar module .

Understand this example

Copy this prompt into your AI tool. No code runs here.

Apply this example

Copy this prompt into your AI tool. No code runs here.