@civaapple/qi-protocol
v0.7.3
Published
Durable Qi IDs and runtime-validated Session event schemas
Readme
@civaapple/qi-protocol
Durable IDs and Session event schemas shared by every Qi runtime component.
Purpose
This package defines the language of durable truth: branded identifiers, the SessionEvent union, and strict
runtime parsers. Producers and consumers must agree here before a new fact can enter the Session stream.
Non-goals
- It does not decide whether a transition is legal;
@civaapple/qi-agent/kernelowns that policy. - It does not persist, project, transport, or execute events.
- It does not expose provider-specific model payloads as Session truth.
Core model
SessionId, RunId, StepId, ActionId, TaskId, PlanId, PlanItemId, WorkPlanId, WorkItemId,
QuestionId, and related identifiers
carry distinct prefixes. Every durable event has a discriminated type, identity links, actor metadata, sequence,
and timestamp. Mode, Plan revision/review, and control Question events are first-class Session facts
(ADR 0011). Read-only Workspace mounts use
workspace.mount.added / workspace.mount.removed /
workspace.sensitive_path.granted / workspace.sensitive_path.revoked
(ADR 0015). parseSessionEvent() is the runtime boundary
for untrusted serialized input.
Behavioral invariants
- Event variants are explicit and compatibility-sensitive; failure meanings are never hidden in free-form text.
- Entity identity cannot be reassigned across Session, Run, Step, or Action boundaries.
- IDs of different domain kinds are not interchangeable.
- New events must remain replayable without requiring current process state.
context.compiled.blockStats, when present, carries only bounded per-kind included/omitted count and estimated token aggregates. Block payloads, sources, and retention reasons remain outside Session truth.context.compactedidentifies the archived source exchange and token reduction without deleting its events.safety.redaction.appliedrecords only boundary, scope, category, and count; secret values are forbidden from the audit fact itself.- ProcessTask start, stop request, exit, and lost ownership are explicit facts; transient stdout/stderr is not a Session event and cannot serve as settlement evidence.
plan.revision.recordedwithoutformatreplays aslegacy_items;formal_markdownrevisions carry the complete document and do not require items.run.triggeredmay freezemode, a Plan binding, and an optional Goal binding (goalBinding: { goalId, contractVersion }).triggermay beuser,goal,timer,event, orresume. Formal Plan bindings omitplanItemId; legacy bindings retain it.trigger: "goal"requires a Goal binding (ADR 0033).run.triggered.contentoptionally records orderedRunInputParttext/image metadata. Images contain only source, dimensions, byte counts, media types, and original/preparedartifact://references; binary bytes and provider data URLs are forbidden. Older events withoutcontentremain text-only throughinput.work.plan.updatedrecords implementation navigation independently from Formal Plan review and completion evidence.run.question.*settles a blocking Question inside one Run and remains distinct from between-Runcontrol.question.*.step.completed.finishReason = handoffexplicitly marks a budget continuation summary. Older Sessions without this additive value keep their prior history behavior.action.freshness.rebasedrecords the original and effective whole-file digests when the Loop safely chains a same-Stepeditafter a completed edit; it must precede authority and executor entry.- New Memory facts use the structured
MemoryScopeunion.memory.user.assertedrecords an explicit human source andmemory.activation.changedrecordsrelevantversus user-onlyalways; legacy string scopes remain replayable but isolated.
Failure semantics
Invalid IDs or event shapes fail before reaching storage or projection. Domain-invalid but schema-valid event sequences are rejected by the Kernel.
Install and minimal use
npm install @civaapple/qi-protocolimport { createId } from "@civaapple/qi-protocol";
const sessionId = createId("ses");Public API
See src/ids.ts for ID schemas and src/events.ts for SessionEventSchema, SessionEvent, and
parseSessionEvent().
Change guide
Changing an event requires synchronized updates to the protocol schema, Kernel projection, persistence and stream compatibility tests, and the owning package documentation. Prefer additive variants and optional fields; there is not yet a formal mixed-version event envelope, so incompatible changes require the generation, preflight, atomic migration, replay, and release gates in ADR 0014.
Verification
tests/slice0.test.mjs is the primary lifecycle and replay evidence. Provider protocol behavior is separately
covered by tests/openai-responses.test.mjs.
