Blog
Post · 2026-04-29

SESSION as the prime mover

For 38 sessions before this one, "S" was a memory-file naming convention. On April 29, 2026, Canonic History recorded the first break from that pattern. Operators wrote handoff narratives. The compiler folded patterns into LEARNING.md on the next build. There were no LEDGER events, no schema enforcement, no commit attribution, no GitHub-issue lifecycle binding, no inter-session inheritance verifier — only narrative prose floating above the governance graph. The handoff prose is half right. The structural rule is everything that comes after.

S33 caught a "MAGIC went 8→9 in S21" precedent that was never true. S38 caught a parse_header_field silently capping at 15 lines. Both were drift that hid inside ungoverned prose.

This session — S39 — is the first natively-governed session in CANONIC history. It opened with bin/session-open S39 --intent "..." emitting a SESSION_OPENED LEDGER row at ~/.canonic/LEDGER/session/events.jsonl. The active session ID is itself a governed ANCHOR; the marker above this paragraph resolves at build time, refreshed on every compile. When S40 opens, this paragraph updates without a content edit.

What changed

Seven commits across three repos walked the 5-move metagov closure recursively over SESSION itself:

  1. DECLAREcanonic-canonic/MAGIC/SERVICES/SESSION/ scaffolded with six files, scoring 255 per the MAGIC kernel: D=CANON.md, E=VOCAB.md, T=ROADMAP.md, R=SESSION.md, O=COVERAGE.md, S=inherits + axiom + MUST inside CANON.md, L=LEARNING.md, LANG inherited up the tree. The active_session anchor declared at S39.
  2. COMPILER READS — five new LEDGER event types (SESSION_OPENED, SESSION_CLOSED, HANDOFF_WRITTEN, ISSUE_CARRIED_FORWARD, WORKFLOW_RUN_FAILED) registered in LEDGER.md § Event Types; bin/gen-ledger-types emitted three mirrors (.js, .ts, .py); lib.ledger.emit_session_event shipped as the canonical SESSION-domain emitter with idempotency-key dedup.
  3. CONSUMERS REFERENCE — three consumer surfaces cite active_session via <!-- GOVERNANCE_INSERT --> markers (this blog post is the third).
  4. GATES ENFORCE — six verifiers shipped LIVE: sequence, no-orphan-issues, attribution, handoff-schema, workflow-run-attribution, handoff-issue-reconciliation. Sequencing dense, exclusive, gateable.
  5. PROPAGATESbin/session-open S40 will flip the anchor, refresh every consumer marker on next build, attribute every governance event in the new window via gov_session payload field, and emit a compile error if an orphan reference survives the rollover.

What the Operator Saw

session_id was already a heavily-loaded primitive in build-run governance — bin/build-stream-publish, bin/verify-build-stream-shape, bin/gen-build-sessions, bin/verify-build-event-codes — identifying one ~/.canonic/LEDGER/build/<id> build run, not a governance work session. Reusing the field name silently miscompiles. The governance-session field is gov_session everywhere: payload, anchor name, GH label gov-session:S<N>, commit-message tag [gov:S<N>].

Context-binding

A SESSION knows context. Three layers bind context to the session lifecycle:

  • Declared intent at open via bin/session-open S<N> --intent "<framing>" (mandatory, 10–500 chars). The operator's framing lives forever in the SESSION_OPENED payload.
  • Conversation transcripts at close — auto-discovered by querying the LEDGER for SCAN_TRANSCRIPT events whose ts falls in [opened, closed]. Operator never types transcript hashes manually.
  • Memory snapshots at open and close — sha-256 of ~/.claude/projects/-Users-iDrDex-CANONIC/memory/MEMORY.md at both ends. The diff between them is the operator's mental-state delta over the session window.

Future-me reads the S39/HANDOFF.md and follows the transcript hashes to the conversations that produced it. The operator's intent is preserved verbatim. The metagov closure pattern itself has a prime mover.

Sources

Claim Source Ref
S33 caught a MAGIC precedent that was never true https://hadleylab.org/blogs/2026-04-07-the-fixed-point internal
5-move metagov closure pattern https://hadleylab.org/blogs/2026-04-23-closing-the-books internal
SESSION_OPENED LEDGER event emitted by bin/session-open https://github.com/canonic-canonic/.canonic/blob/main/bin/session-open external
GitHub-issue lifecycle binding for governance sessions https://github.com/canonic-canonic/.canonic/issues external
gov_session payload field naming convention https://github.com/canonic-canonic/canonic-canonic/blob/main/MAGIC/SERVICES/SESSION/CANON.md external

The metagov pattern closes over itself: a SESSION declares its own contract, opens and closes via governed tooling, and the active session ID resolves at build time without a content edit.

Session Primitive | GOVERNANCE | SESSION | BLOGS