Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 36 additions & 5 deletions docs/ledger-bridge-contract.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# The ledger bridge contract — one doctrine, three record kinds
# The ledger bridge contract — one doctrine, four record kinds

> SEAM 4 of the outside-lab codesign (amicode's half; issue #704, part of #679;
> design-of-record: `spec-20260831-120000-amicode-outside-lab-codesign.md`, SEAM 4).
Expand Down Expand Up @@ -99,6 +99,28 @@ completes as this note + the fixtures, and amicode's reports stay readable
through its own surfaces (the Run Inspector, the problem-workspace spine, the
`amico-run` launch/verify path) exactly as they do today.

### (d) the SOTA staging sidecar (living-sota D3 — slice 2 of spec-20260905-103000)

The per-campaign SIDECAR staging stream a session ledger carries BESIDE
itself — the nine-section ledger grammar holds unamended; the sidecar is a
SEPARATE file (`<ledger-stem>.sota-staging.jsonl` under the personal vault's
`sessions/`, one per campaign, plus the reserved `hopper` stream as the
no-match/below-threshold fallback). The doctrine's five clauses apply
verbatim: append-only transition lines (`stage` / `accept` / `drop` /
`compact`) at or under PIPE_BUF with O_APPEND line-atomicity; staging state
DERIVED by replay, never stored; entries never mutated (the windowed
compaction rewrite is the one sanctioned exception, and it RECORDS itself as
an appended `compact` line); unknown `ev` values carried by readers; and
single writer — the digest, the SOTA watcher, and the weekly synthesis are
the ONLY stage/drop writers, with ONE sanctioned non-job append: the
**acceptance stamp**, an agent appending an `accept` line on the PI's explicit
instruction, carrying `instructed_by: "PI"` plus the recorded instruction
(channel, note, received_at). Every `stage` line carries provenance
(job/via/source/fetched_at) and the review-by/expiry stamps; every transition
is keyed by its external `event_id` (idempotent — double delivery is
impossible); accept and drop are both terminal and exactly one lands. The
acceptance-stamp schema rides the bridge fixture below (obligation O3).

## The replay fixtures + validator (amicode's half, shipped here)

- `packages/amico-run/fixtures/bridge/amicode-run/` — one canonical amicode run
Expand All @@ -110,11 +132,20 @@ through its own surfaces (the Run Inspector, the problem-workspace spine, the
`task.toml` (`kind = "experiment"`), `progress.jsonl` with the known event
kinds **plus one unknown `ev` on purpose** (the opacity rule, exercised, not
asserted), `result.toml`, and the artifact the `artifact` event names.
- `packages/amico-run/fixtures/bridge/2026-09-05-sota-staging/` — one
canonical SOTA staging sidecar record (living-sota slice 2): `staging.toml`
(the manifest), the campaign sidecar with a staged paper, a staged watcher
release, the PI-instructed accept stamp, an expired-without-review drop,
and a pending stage, plus the `hopper` stream carrying a below-threshold
stage and one unknown `ev` on purpose (the opacity probe, same as the
strumento fixture's).
- `packages/amico-run/scripts/validate_bridge_replay.mjs` — the replay
validator: exit 0 on both fixtures, non-zero on doctrine violations (a torn
terminal marker, a mutated content hash, a missing terminal marker, a torn
append-only stream, a non-contiguous `seq`, an escaping/void artifact path, a
broken stdout-contract line). No Julia, no Python — the fixtures are
validator: exit 0 on all three fixtures, non-zero on doctrine violations (a
torn terminal marker, a mutated content hash, a missing terminal marker, a
torn append-only stream, a non-contiguous `seq`, an escaping/void artifact
path, a broken stdout-contract line, a laundered staging acceptance — an
accept without its stage behind it or without its PI-instruction record, a
double stage for one event id). No Julia, no Python — the fixtures are
committed data. `node packages/amico-run/scripts/validate_bridge_replay.mjs`
with no arguments validates both; pass a record dir to validate one.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# The SOTA staging sidecar record — the canonical stream shape (living-sota D3)

One canonical SIDECAR staging record dir (the `sota-staging` record kind the
ledger-bridge validator replays): the per-campaign append-only transition
stream a campaign ledger carries BESIDE itself, plus the hopper fallback
stream. Synthetic values, real shapes — every line is a whole, flushed JSON
object ≤ PIPE_BUF appended with O_APPEND, `seq` is the line count at write
time, and state is derived by replay, never stored.

- `staging.toml` — the record's manifest: the record kind, the campaign the
sidecar belongs to, and the stamped constants (review-by / expiry /
compaction windows).
- `session-20260831-bridge-fixture.sota-staging.jsonl` — the campaign sidecar:
a staged paper (provenance-stamped, review-by/expiry stamps), a staged
watcher release event (the watcher rides the IDENTICAL shape), the
PI-instructed accept stamp (instruction provenance recorded), a match that
expired without review (the recorded drop line), and one still-pending
stage.
- `hopper.sota-staging.jsonl` — the fallback stream: a below-threshold stage
line **plus one unknown `ev` on purpose** — the reader-opacity rule,
exercised by the fixture the same way the strumento fixture carries its
unknown `ev` probe.

The writer discipline (ONE APPENDER — the digest, the watcher, and the
weekly synthesis are the only stage/drop writers; the accept stamp is the
sole sanctioned non-job append, an agent recording the PI's explicit
instruction) lives in `packages/amico-run/src/sota_staging.ts`; the replay
grammar is enforced by `packages/amico-run/scripts/validate_bridge_replay.mjs`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{"ev":"stage","seq":1,"ts":"2026-09-05T09:00:00.000Z","event_id":"arxiv:2606.99999","campaign":"hopper","kind":"paper","title":"Protein folding via deep learning","url":"https://arxiv.org/abs/2606.99999","provenance":{"job":"papers-digest","via":"fetched","source":"arXiv export API over HTTPS","fetched_at":"2026-09-05T08:55:00.000Z","feed":"quant-ph"},"matched":[],"reason":"below-threshold","review_by":"2026-09-12T09:00:00.000Z","expires_at":"2026-09-19T09:00:00.000Z"}
{"ev":"triage-tag","seq":2,"ts":"2026-09-05T12:00:00.000Z","event_id":"arxiv:2606.99999","tag":"flywheel-drain"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{"ev":"stage","seq":1,"ts":"2026-09-05T09:00:00.000Z","event_id":"arxiv:2606.05060","campaign":"session-20260831-bridge-fixture","kind":"paper","title":"Fast Rydberg CZ gates via shaped pulses","url":"https://arxiv.org/abs/2606.05060","provenance":{"job":"papers-digest","via":"fetched","source":"arXiv export API over HTTPS","fetched_at":"2026-09-05T08:55:00.000Z","feed":"quant-ph"},"matched":["rydberg","cz"],"review_by":"2026-09-12T09:00:00.000Z","expires_at":"2026-09-19T09:00:00.000Z"}
{"ev":"stage","seq":2,"ts":"2026-09-05T09:05:00.000Z","event_id":"github:example/piccolo-adjacent@v0.9.0","campaign":"session-20260831-bridge-fixture","kind":"release","title":"v0.9.0 — trajectory rework","url":"https://github.com/example/piccolo-adjacent/releases/tag/v0.9.0","provenance":{"job":"sota-watcher","via":"cache","source":"GitHub API against canonical repos","fetched_at":"2026-09-05T09:04:00.000Z","repo":"example/piccolo-adjacent","surface":"releases"},"matched":["trajectory","rydberg"],"review_by":"2026-09-12T09:05:00.000Z","expires_at":"2026-09-19T09:05:00.000Z"}
{"ev":"accept","seq":3,"ts":"2026-09-06T10:00:00.000Z","event_id":"arxiv:2606.05060","campaign":"session-20260831-bridge-fixture","kind":"paper","title":"Fast Rydberg CZ gates via shaped pulses","url":"https://arxiv.org/abs/2606.05060","instructed_by":"PI","instruction":{"channel":"chat","note":"the blockade number is load-bearing — accept","received_at":"2026-09-06T09:58:00.000Z"}}
{"ev":"stage","seq":4,"ts":"2026-09-05T09:10:00.000Z","event_id":"arxiv:2606.11111","campaign":"session-20260831-bridge-fixture","kind":"paper","title":"Marginal drift note","url":"https://arxiv.org/abs/2606.11111","provenance":{"job":"papers-digest","via":"fetched","source":"arXiv export API over HTTPS","fetched_at":"2026-09-05T08:55:00.000Z","feed":"quant-ph"},"matched":["blockade"],"review_by":"2026-09-12T09:10:00.000Z","expires_at":"2026-09-19T09:10:00.000Z"}
{"ev":"drop","seq":5,"ts":"2026-09-19T09:00:01.000Z","event_id":"arxiv:2606.11111","campaign":"session-20260831-bridge-fixture","reason":"expired-without-review","recorded":"2026-09-19T09:00:01.000Z"}
{"ev":"stage","seq":6,"ts":"2026-09-20T08:02:00.000Z","event_id":"arxiv:2606.07777","campaign":"session-20260831-bridge-fixture","kind":"paper","title":"Rydberg register scaling revisited","url":"https://arxiv.org/abs/2606.07777","provenance":{"job":"papers-digest","via":"cache","source":"arXiv export API over HTTPS","fetched_at":"2026-09-20T08:01:00.000Z","feed":"quant-ph"},"matched":["rydberg","register"],"review_by":"2026-09-27T08:02:00.000Z","expires_at":"2026-10-04T08:02:00.000Z"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind = "sota-staging"
schema_version = "1"
campaign = "session-20260831-bridge-fixture"
review_by_days = 7
expires_after_days = 14
compaction_window_days = 28
21 changes: 18 additions & 3 deletions packages/amico-run/fixtures/bridge/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# SEAM 4 bridge fixtures — the canonical replay records

Two committed, synthetic, stable record dirs the Telaio fold must replay —
issued #704, amicode's half of the ledger bridge. The doctrine they carry is
Three committed, synthetic, stable record dirs the Telaio fold must replay —
issued #704, amicode's half of the ledger bridge (the sota-staging record is
the living-sota campaign's slice-2 extension, spec-20260905-103000 D3).
The doctrine they carry is
[`docs/ledger-bridge-contract.md`](../../../../docs/ledger-bridge-contract.md);
the validator is
`packages/amico-run/scripts/validate_bridge_replay.mjs` (exit 0 on both by
`packages/amico-run/scripts/validate_bridge_replay.mjs` (exit 0 on all by
default; pass a dir to check one; the corruption directions are pinned by
`packages/amico-run/test/bridge_replay.test.ts`).

Expand Down Expand Up @@ -54,3 +56,16 @@ Named by its id — the TaskRecord contract binds `id == directory basename`.
- `artifacts/fit_002.json` — the file the `artifact` event names; the contract
requires a recorded artifact path to resolve to a real file inside the task
dir, so it does.

## `2026-09-05-sota-staging/` — one canonical SOTA staging sidecar record

The per-campaign SIDECAR staging stream (living-sota slice 2, D3): the
append-only transition stream a campaign ledger carries BESIDE itself (the
nine-section ledger grammar unamended), plus the hopper fallback stream.
`staging.toml` is the manifest (record kind + campaign + the stamped
windows); `session-20260831-bridge-fixture.sota-staging.jsonl` carries a
staged paper, a staged watcher release, the PI-instructed accept stamp (the
acceptance-stamp schema — obligation O3 — lives HERE), an
expired-without-review drop, and a pending stage; `hopper.sota-staging.jsonl`
carries a below-threshold stage plus one unknown `ev` on purpose (the
reader-opacity probe, same as the strumento fixture's unknown `ev`).
2 changes: 1 addition & 1 deletion packages/amico-run/scripts/validate_bridge_replay.d.mts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// amico-run tsconfig includes test/, unlike the extension package's — hence
// this declaration rather than an untyped import).

export type BridgeRecordKind = "amicode-run" | "strumento-task";
export type BridgeRecordKind = "amicode-run" | "strumento-task" | "sota-staging";

export interface BridgeValidation {
ok: boolean;
Expand Down
114 changes: 110 additions & 4 deletions packages/amico-run/scripts/validate_bridge_replay.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
// belongs to the .d.mts surface next to it, the assert_built_bundles.mjs
// pattern).
import { createHash } from "node:crypto";
import { existsSync, readFileSync } from "node:fs";
import { existsSync, readdirSync, readFileSync } from "node:fs";
import { basename, dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { parse as parseToml } from "smol-toml";
Expand Down Expand Up @@ -63,14 +63,16 @@ export function defaultFixtureDirs() {
return [
{ kind: "amicode-run", dir: join(PKG_ROOT, "fixtures", "bridge", "amicode-run") },
{ kind: "strumento-task", dir: join(PKG_ROOT, "fixtures", "bridge", "2026-08-31-strumento-task-b3a7") },
{ kind: "sota-staging", dir: join(PKG_ROOT, "fixtures", "bridge", "2026-09-05-sota-staging") },
];
}

/** Infer the record kind from the directory's own manifest (the record is the
* truth; neither kind ever contains the other's manifest). */
* truth; no kind ever contains another's manifest). */
export function inferRecordKind(dir) {
if (existsSync(join(dir, "run.toml"))) return "amicode-run";
if (existsSync(join(dir, "task.toml"))) return "strumento-task";
if (existsSync(join(dir, "staging.toml"))) return "sota-staging";
return undefined;
}

Expand Down Expand Up @@ -326,6 +328,109 @@ function validateStrumentoTask(dir, errors) {
}
}

// ─── the SOTA staging sidecar record (living-sota D3, slice 2) ───────────────
//
// The per-campaign SIDECAR staging stream: append-only transition lines
// (stage/accept/drop/compact) beside the session ledger; state derived by
// replay. The grammar this validator enforces IS the acceptance-stamp schema
// (obligation O3): an accept line carries instructed_by: "PI" + the recorded
// instruction; transitions reference their stage; a stage is unique by event
// id; accept and drop are mutually terminal; unknown `ev` values are carried
// (reader opacity — the fixture ships one on purpose).

const STAGING_KINDS = new Set(["paper", "release", "changelog", "issue"]);

function validateSotaStaging(dir, errors) {
const manifest = readTomlFile("staging.toml", dir, errors);
let campaign;
if (manifest !== undefined) {
if (manifest.kind !== "sota-staging") {
errors.push("staging.toml: kind is not sota-staging — the manifest names the record kind");
}
if (typeof manifest.campaign !== "string" || manifest.campaign === "") {
errors.push("staging.toml: campaign missing — the manifest names the sidecar's campaign");
} else {
campaign = manifest.campaign;
}
}
// the campaign's own sidecar must be present
if (campaign !== undefined && !existsSync(join(dir, `${campaign}.sota-staging.jsonl`))) {
errors.push(`${campaign}.sota-staging.jsonl: missing — the manifest's campaign must have its sidecar`);
}

let streams = [];
try {
streams = readdirSync(dir).filter((n) => n.endsWith(".sota-staging.jsonl"));
} catch {
/* none */
}
if (streams.length === 0) {
errors.push("no *.sota-staging.jsonl stream in the record — a staging record is its streams");
}
for (const name of streams) {
validateStagingStream(dir, name, errors);
}
}

function validateStagingStream(dir, name, errors) {
const stem = name.replace(/\.sota-staging\.jsonl$/, "");
const events = readJsonlFile(name, dir, errors);
if (events === undefined) return;
const seenStage = new Set();
const terminal = new Map(); // event_id → ev ("accept" | "drop")
events.forEach((e, i) => {
const at = `${name}: line ${i + 1}`;
if (e.seq !== i + 1) errors.push(`${at}: seq is ${e.seq} — seq is the line count at write time (monotonic from 1)`);
if (typeof e.ts !== "string" || !ISO_RE.test(e.ts)) errors.push(`${at}: ts missing or not ISO-8601`);
const ev = typeof e.ev === "string" ? e.ev : "";
if (ev === "" || typeof e.event_id !== "string" || e.event_id === "") {
if (ev !== "") errors.push(`${at}: event_id missing — every transition is keyed by its external identity`);
else if (typeof e.ev !== "string") errors.push(`${at}: ev missing — unknown ev VALUES skip, but ev itself is required`);
return;
}
if (ev === "stage") {
if (typeof e.campaign !== "string" || e.campaign !== stem) {
errors.push(`${at}: campaign "${e.campaign}" ≠ the stream's stem "${stem}" — a sidecar carries its own campaign only`);
}
if (!STAGING_KINDS.has(e.kind)) errors.push(`${at}: kind "${e.kind}" outside paper|release|changelog|issue`);
if (typeof e.title !== "string" || e.title === "") errors.push(`${at}: title missing — the listing renders it`);
if (typeof e.url !== "string" || e.url === "") errors.push(`${at}: url missing — every staged match is cited`);
if (e.provenance === null || typeof e.provenance !== "object" || Array.isArray(e.provenance)) {
errors.push(`${at}: provenance missing — a match never lands unprovenance-stamped`);
} else {
for (const k of ["job", "via", "source", "fetched_at"]) {
if (typeof e.provenance[k] !== "string" || e.provenance[k] === "") {
errors.push(`${at}: provenance.${k} missing — the stamp carries {job, via, source, fetched_at}`);
}
}
}
if (typeof e.review_by !== "string" || !ISO_RE.test(e.review_by)) errors.push(`${at}: review_by missing or not ISO-8601 — the review-by stamp is the shape`);
if (typeof e.expires_at !== "string" || !ISO_RE.test(e.expires_at)) errors.push(`${at}: expires_at missing or not ISO-8601 — the expiry stamp is the shape`);
if (seenStage.has(e.event_id)) errors.push(`${at}: a second stage for ${e.event_id} — double-delivery is impossible (idempotent by event id)`);
seenStage.add(e.event_id);
return;
}
if (ev === "accept") {
// O3: the acceptance-stamp schema — the PI-instructed record
if (e.instructed_by !== "PI") errors.push(`${at}: instructed_by is not "PI" — the stamp records the human decision, not a job append`);
if (e.instruction === null || typeof e.instruction !== "object" || Array.isArray(e.instruction)) {
errors.push(`${at}: instruction missing — an unstamped acceptance is a laundered one`);
} else {
if (typeof e.instruction.channel !== "string" || e.instruction.channel === "") errors.push(`${at}: instruction.channel missing`);
if (typeof e.instruction.note !== "string" || e.instruction.note.trim() === "") errors.push(`${at}: instruction.note missing — the PI's explicit instruction is required`);
if (typeof e.instruction.received_at !== "string" || !ISO_RE.test(e.instruction.received_at)) errors.push(`${at}: instruction.received_at missing or not ISO-8601`);
}
} else if (ev === "drop") {
if (typeof e.reason !== "string" || e.reason === "") errors.push(`${at}: reason missing — a drop is a recorded line, never a silent skip`);
if (typeof e.recorded !== "string" || !ISO_RE.test(e.recorded)) errors.push(`${at}: recorded missing or not ISO-8601`);
}
// transition grammar: references its stage; accept XOR drop per event id
if (!seenStage.has(e.event_id)) errors.push(`${at}: ${ev} for ${e.event_id} with no stage behind it — a transition records the fate of a STAGED match`);
else if (terminal.has(e.event_id)) errors.push(`${at}: ${ev} after ${terminal.get(e.event_id)} for ${e.event_id} — accept and drop are both terminal, exactly one lands`);
else terminal.set(e.event_id, ev);
});
}

/** Validate one record directory against the bridge doctrine. Pure: reads the
* dir, returns every violation it finds (never throws). */
export function validateBridgeRecord(dir, kind) {
Expand All @@ -336,12 +441,13 @@ export function validateBridgeRecord(dir, kind) {
ok: false,
kind: "amicode-run",
errors: [
`${dir}: no record manifest found (run.toml for an amicode run dir, task.toml for a strumento task dir)`,
`${dir}: no record manifest found (run.toml for an amicode run dir, task.toml for a strumento task dir, staging.toml for a SOTA staging record)`,
],
};
}
if (k === "amicode-run") validateAmicodeRun(dir, errors);
else validateStrumentoTask(dir, errors);
else if (k === "strumento-task") validateStrumentoTask(dir, errors);
else if (k === "sota-staging") validateSotaStaging(dir, errors);
return { ok: errors.length === 0, kind: k, errors };
}

Expand Down
Loading
Loading