kestrel.markets
Version:
A typed, token-efficient language + runtime for agentic trading: agents author bounded plans, the runtime fires them at the tick. CLI + typed library + MCP server.
54 lines (53 loc) • 3.63 kB
JavaScript
/**
* # frame/brief — the BRIEF content-hash + constructor (ADR-0026)
*
* The OSS side of the {@link ./types.ts Brief} (the soft, directional English channel): it RENDERS a
* brief supplied by the cell/config and binds its CONTENT HASH into provenance (`brief_hash`, sibling
* to `promptHash`), so "this performance came from this thesis" is attributable. It does NOT build
* the platform Brief/Journal/Thesis lifecycle (that is a kestrel.markets artifact).
*
* **HARD GUARD (ADR-0026):** a Brief is unvalidated free text that can NEVER enter admission /
* narrowing / bounded-risk — only the {@link ./types.ts Mandate}/envelope do. This module only
* HASHES + CONSTRUCTS a Brief; nothing here touches the narrowing algebra.
*
* **HONESTY, BY CONSTRUCTION + AT THE HASH-COMMIT SEAM (kestrel-voy9).** {@link makeBrief} is the
* honest constructor — it computes the hash from the text, so a Brief it builds can NEVER carry an
* attribution that lies about which thesis ran. The complementary half — a Brief that a cell/config
* supplied as a raw `{ text, hash }` literal (bypassing this constructor) — is verified by
* {@link assertBriefHashHonest} at the seams where a Brief's hash actually COMMITS to provenance:
* - the plan-fixture FREEZE ({@link ../session/harness/plan-fixture.ts capturePlanFixture} /
* {@link ../session/harness/plan-fixture.ts readPlanFixture}), where a lying `brief.hash` would
* otherwise mint a stable `plan_fixture_sha` that binds the wrong thesis into grade provenance
* (ADR-0032 §7) — the grade driver never renders, so this is the load-bearing check; and
* - the render seam ({@link ./render.ts buildKernelCellLines}), as defense-in-depth before it
* emits the `brief=<hash>` line.
* The guard is EXPORTED and WIRED at those real drivers (not an inert export nothing calls).
*/
import { sha256 } from "../crypto/sha256.js";
import { KernelHonestyError } from "./types.js";
/** The canonical content hash of a brief's text: `sha256:<64-hex>`. Deterministic + pure — the same
* text hashes identically, so a rebrief is detectable and a grade can bind exactly which thesis ran. */
export function briefHashOf(text) {
return `sha256:${sha256(text)}`;
}
/** Construct a {@link Brief} from its directional text (+ optional version), computing its content
* hash — the HONEST constructor: a Brief built here can never carry a hash that disagrees with its
* text (dishonest-by-construction is impossible). The cell/config supplies the text; provenance binds
* {@link Brief.hash}. Pure. */
export function makeBrief(text, version) {
return { text, hash: briefHashOf(text), ...(version !== undefined ? { version } : {}) };
}
/**
* Fail-closed verification that a supplied Brief's `hash` matches its `text` (kestrel-voy9). A cell or
* an on-disk fixture may carry a raw `{ text, hash }` that bypassed {@link makeBrief}; a mismatch means
* the attribution would LIE about which thesis ran, so it must never enter a content-address or a
* rendered provenance line. Throws {@link KernelHonestyError} on mismatch. Pure. WIRED at the
* plan-fixture freeze/read and the render seam — never a standalone export nothing calls.
*/
export function assertBriefHashHonest(brief) {
const expected = briefHashOf(brief.text);
if (brief.hash !== expected) {
throw new KernelHonestyError(`brief hash mismatch — supplied ${JSON.stringify(brief.hash)} but text hashes to ${JSON.stringify(expected)} ` +
"(fail-closed: a Brief's content hash must match its text so provenance attributes the real thesis).");
}
}