Changelog
All notable changes to Prism are documented here. Format follows Keep a Changelog. Dates are UTC. Prism started without semver-tagged releases — the project is a single-tenant per-user install with ongoing migration. As ofv0.2.0
(2026-04-26) the line is tagged. Entries are still grouped by date and
reference the commits + specs that landed; release tags surface above the
relevant date header. Operators upgrade by git pull + rebuilding the
backend image (and the optional standalone session-manager container, as
of v0.2.0).
This file is updated per commit arc, not per individual commit. Entries
are curated for what changed for operators, agents, or developers —
not a replay of every
git log line. The git log is the source of
truth for per-commit detail; this changelog is the human-readable arc.2026-05-13
Architectural
- SPEC-113 v0.3 — Bootstrap path resolution + immutable
$PRISM_ROOTmodel (Texi architecture, Donna PO, Frank ratified). Ring 2 methodology lives immutably at$PRISM_ROOT/templates/(prism-base.md+ ptype overlay) and is read at runtime by agents — not copied into customer projects../PRISM.mdis no longer a customer project file; it exists only in the Prism repo itself, where$PRISM_ROOT == $PROJECT_ROOT. Customer dirs ($PROJECT_ROOT/<name>) get only the thin edge:CLAUDE.md/AGENTS.mdRing 1 replicas,.prism/, and.agent/in contributor mode. Upgrades touch$PRISM_ROOTonly; never customer dirs. See SPEC-113 for the full contract, failure-mode names, and acceptance criteria. Motivated by postmortem13b4a879(DPA-Crawl bootstrap cascade). - SPEC-112 v0.3 — Client vs Contributor scaffold boundary (Texi architecture, Donna engineering / Plan #18 integration, Frank ratified). Two install/scaffold modes. Client (default): customer install —
$PROJECT_ROOTgets onlyCLAUDE.md/AGENTS.mdRing 1 replicas +.prism/dotfile metadata + editor MCP config. No.agent/tree, no roster files, nostart-alllaunchers, noPRISM.md. Contributor (explicit opt-in viascaffold_profile='contributor'): adds the full.agent/tree, role/persona config, launch.local, roster compatibility files,start-alllaunchers, and contributor ptype/profile metadata.prism_adoptandprism_createdefault to client unlessscaffold_profile='contributor'is passed (or an existing contributor tree is explicitly accepted, or$PROJECT_ROOT == $PRISM_ROOTfor the Prism repo self-reference). See SPEC-112. - SPEC-114 v0.1 — Sage and Clara customer-care incident personas (Texi architecture, Donna PO + engineering, Frank greenlight 16:00Z). Plan #19 v0.1 customer-care persona pair. Sage is the intake classifier — receives reporter signals and classifies as
info/incident/enhancement/recommendation/unclear, routing incident-like cases to Clara. Clara (named for Clara Barton) is the incident manager — executes a five-tier init checklist (mandatory init reads → conditional reads by symptom → privacy gates → severity/scope/kind classification → output discipline). Clara is the gate that decides whetherprism_phone_homefires under SPEC-115. v0.1 launches terminal-launched on server1 for observability; headless daemon mode deferred to a later phase. See SPEC-114. - SPEC-115 v0.1 —
prism_phone_homeverb + ET GitHub-issue transport (Texi architecture, Donna PO + backend, Frank greenlight 16:00Z). Adds the controlled Prism-product phone-home channel before Prism Cloud exists. Newprism_phone_homeverb (rejectsscope='customer-internal'; requires passedredaction_report+operator_review.approved=true); ET gitapp_helper service validates the packet, applies idempotency dedupe, and transports throughghCLI to the private invite-onlyFrankTewksbury/Prismrepository. Operator must be invited as a collaborator before phone-home can succeed (phone_home_repo_access_deniedfailure mode otherwise). Customer-internal incidents never leave the local environment;mixedscope phones home only the redacted Prism-product subset after operator review. v0.2 will swapghCLI transport for a Prism-Bot GitHub App; v0.1 redaction + operator-review-before-send invariants must be preserved. See SPEC-115.
Added
- PR #344 — BIOS template wording +
resolvePidenv fallback + offline-fallback gate (Donna, ships SPEC-113 v0.3).templates/CLAUDE.md+templates/AGENTS.mdbumped to bios_version 2.6.0. Boot step 1 changes fromRead ./PRISM.mdto “Read Ring 2 methodology from$PRISM_ROOT/templates/prism-base.md+ ptype overlay”. Boot step 4 (offline fallback to_ACTIVE_CONTEXT.md/_TODO.md) is gated on step 1 success — prevents DPA-Crawl-class bootstrap cascade where Codex fell back to DFW global constitution and read offline context beforeprism_start.mcp-noderesolvePidfallback order locked: explicitpid> explicitname>PRISM_PROJECT_NAMEenv >PRISM_PROJECT_DIRenv > structured failure. Conflict detection: throwsenv_project_mismatch/name_arg_mismatch_env_projectwhen explicit args disagree with launcher-injected env — defense in depth against theidentity_as_project_nameclass.templates/prism-application.mdA6 paragraph rewritten from “PRISM.md composition writes to project root” to “Ring 2 methodology resolution reads at runtime from$PRISM_ROOT/templates/”.
Fixed
- PR #343 —
coder.shlauncher: removePRISM.mdfrom project-root sentinels (Lafonda). Mac/POSIX launcher no longer treatsPRISM.mdas a project-root sentinel. Sentinel set is now.prism/directory +AGENTS.md/CLAUDE.mdRing 1 replicas + backend project metadata. Customer projects withoutPRISM.md(the new normal) now resolve correctly. - PR #342 —
coder.ps1launcher: removePRISM.mdfrom project-root sentinels (Cherry). Windows-side counterpart to PR #343. Cherry’s Windows smoke (signal913833f9) confirmscoder.ps1+ BIOS 2.6.0 templates load correctly on a project root withoutPRISM.md.
2026-05-11
Architectural
- Marconi — in-memory signal-mesh switch shipped (SPEC-101 v0.4, Donna engineering driver, Texi ratified, Frank operator GO). The signal-delivery hot path is now sender shim → Marconi → receiver shim, with Redis Stream + PG audit as an asynchronous fan-out off the hot path. The legacy synchronous-PG / Redis-pubsub forwarder is removed from
send_signal. Live-verified onserver1PROD 2026-05-11 01:03Z via signalc8f4d0cblanding in bothsignal_queueandsignal_queue_shadowwithstage=model_acted_ack. v0.4 target: p99< 5mson the same-instance hot path.- Stage 0 — design gate (PR #279). Loss budget, recovery invariants (R1/R2/R3/R5/R6/R8), and rollback procedures locked. Frank loss-budget signoff captured: “if Redis is down, messages are delivered but never recorded at this stage of the build.”
- Stage 1 — process-local routing + registration cache (PR #280).
backend/app/marconi/{_cache,routing,registration}.py+ flag-gated wiring. FlagsMARCONI_ROUTING_TABLE_READS/MARCONI_REGISTRATION_TABLE_READS. - Stage 2 — cache lifecycle: direct write-through hooks + startup warmup (PR #282). Wires direct invalidation at every site that mutates session state (
controller_service.register/deregister/handoff_master/claim_master,KeyspaceReaper, WS connect/disconnect). No pubsub subscriber anywhere. - Stage 3 — in-memory audit queue + Redis Stream writer (PR #293). Audit fan-out pipeline lands before the hot-path cutover so accepted signals continue producing parallel records during cutover. Flags
MARCONI_AUDIT_QUEUE_WRITE/MARCONI_REDIS_STREAM_WRITER. - Stage 3.5 — envelope enrichment for byte-perfect shadow comparison (PR #295). Marconi-archived envelopes match legacy-PG envelopes byte-for-byte; shadow harness (PR #292) compares.
- Stage 4 — PG archiver (PR #294 shadow, PR #299 PRIMARY flip). Consumer group on Marconi Cache Redis Stream with
XREADGROUP COUNT 1 BLOCK 0; idempotent UPSERT intosignal_queue/signal_trace_events/signal_obligations. No batching — the archiver optimizes for near-immediate audit persistence, not throughput batching. FlagsMARCONI_PG_ARCHIVER_SHADOW/MARCONI_PG_ARCHIVER_PRIMARY. - Stage 5 — hot-path inversion (PR #283, flipped ON in PR #284).
send_signallooks up the recipient’s WS handle in Marconi’s routing table and pushes directly. Synchronous PG INSERT removed from the hot path. FlagsMARCONI_HOT_PATH_SEND/MARCONI_OBLIGATIONS_MEMORY_PRIMARY. - Sign-coded result envelope (PR #285, PR #286).
[stage=…]banner the shim renders alongside the doorbell to make the delivery stage observable without a separate trace call. Possible stages:model_acted_ack,surface_observed,pushed,queued_offline. - PR #299 — flip
MARCONI_PG_ARCHIVER_PRIMARYON. Frank GO, no soak. PG archiver is the canonical writer tosignal_queue/signal_trace_events/signal_obligations.
Added
- SPEC-100 — operator-invoked signal-mesh loopback diagnostic (PR #276, Donna).
prism_channel_probeandprism_channel_probe_ackverbs send a synthetic envelope from a sender shim through Marconi to a receiver shim and back, surfacing whether the sender’s WS handle is healthy, whether the receiver’s daemon is attached and forwarding, whether the surface strategy rendered the doorbell, and whether the receiver model calledprism_channel_probe_ack. The loopback probe is what surfaced the legacy-path drift that motivated SPEC-101. - Channel-probe client-cap discovery + end-to-end probe verbs (PR #287). Sender-side capability discovery before issuing a probe; full end-to-end verb wiring through MCP shim.
- SPEC-104 — Marconi cache-first trace/read path. Recent signal trace lookup now has a cache-first contract:
prism_signal_tracedefaults to Marconi Cache for real-time state, whilesource="pg_audit"is the explicit historical/reporting/reconciliation path. Responses expose source metadata such assource,cache_hit,pg_audit_used,cache_stream_id, andtrace_state.
Changed
- Signal trace compatibility semantics. A recent Marconi Cache miss no longer silently implies historical absence. Callers that need the old PG audit behavior must request
source="pg_audit"or opt into history withinclude_history=true.
Fixed
- Rejected Marconi sends are auditable. Sends to an unregistered recipient now enqueue a rejected audit envelope when Marconi Cache write-through is enabled, so misspelled-recipient attempts can be traced instead of returning IDs without a cache/audit path.
marconi-archiver— translatepublish_pathpushed_to_marconi→pushed_to_ws(PR #300). Marconi emitted the internal labelpushed_to_marconiin the API response while older shims and the dashboard expectedpushed_to_ws. The archiver now normalizes the value at the boundary so external surfaces see a stable vocabulary.- SPEC-101 — remove
AUDIT_PENDING_MARCONI+ACK_DEFERRED_MARCONIdead branches (PR #301). Stage 5 cutover obsoleted these intermediate ack stages; cleanup landed post-deploy. channel-probe— bump default ACK timeout 5s → 10s (PR #290). Accommodates per-persona daemon turn-boundary holds; was tripping false-negative probe failures on busy receivers.launcher— restore--channels server:prism(PR #288). The flag name had drifted; channels-push delivery required the explicit flag.
Docs
- SPEC-101 v0.4 marconi audit flow lock (PR #291). Operator architecture lock: Marconi switch (in-mem) → Marconi Cache (Redis Stream
marconi:signals:{tenant}, MAXLEN ~7d) → PG audit. Pre-stamps Stage 5 status path so the code PR could mark it shipped without another architecture revision. - SPEC-101 v0.3.1 — operator architecture lock + Texi precision (PR #281). Restored §3.6 in-memory audit queue as a named Marconi internal (replacing floating ring references); reordered stage ladder so audit fan-out lands BEFORE hot-path cutover.
- SPEC-101 Stage 0 sub-doc + v0.2 scope reduction (PR #279, updated v0.3+). Loss budget, recovery invariants, rollback. Local durable spool removed (Frank operator scope reduction).
- SPEC-101 v0.1 — Marconi: in-memory signal mesh, zero backend on hot path (PR #277). Initial draft, Texi concept ratification.
- Signal Mesh + Marconi docs rewrite (Desiree).
/signal-meshrewritten around the three-tier topology with 5 new mermaid diagrams (two flows, hot-path sequence, audit fan-out, surface delivery, recovery). New/marconiexplainer page covering in-memory tables, cache invalidation hooks, stage ladder, full §9 counter catalog, and failure-mode summary. Cross-doc consistency sweep acrossindex,vision,agent-surfaces, andmetrics. Amendment banners on the superseded signaling spec series (SPEC-034 / 037 / 044 / 045 / 052 / 058 / 070 / 071 / 091).
Operability
- OTel → Prometheus bridge RESTORED (PR #298, Donna postmortem
3c1f986c)./metricsendpoint now exposes the fullmarconi_*namespace plus the existingsignals_sent_total,system_signals_emitted_total,controller_*counters. Trust Prometheus again. Memoryproject_otel_prometheus_bridge_deadupdated to reflect restoration; PID label drift defect onPeerLeftpath noted for follow-up.
2026-05-08
Added
-
Memorules — SPEC-094 Phase 2 a-d (Donna, four-PR arc). Memorules
ship as the first concrete artifact of the persona-behavioral-memory
layer. Persona-scoped behavioral records — what a persona has learned
to do or not do across sessions — are now written, recalled, and
audited through TriGraph-backed primitives instead of host-editor
local files. Working names pending legal clearance.
- Phase 2a — Memorule schema + write service (PR #235, 28 unit
tests). New Cypher schema for
:Memorulenodes carrying scope (persona / specialization / project / global), applicability rules, payload, source-of-record reference, and lifecycle status. Write service validates shape, deduplicates against existing recordings, and emits journal entries on first-write. - Phase 2b — Memorule recall + applies_to ranking (PR #236,
12 unit tests).
prism_rememberrecall path scores Memorules by applicability — persona match > specialization match > project match > global — with deterministic tie-break. - Phase 2c —
prism_remember kind='memorule'contract expansion (PR #237). The verb’s payload contract grows to accept memorule- specific fields (rule body, applicability scope, supersedes pointer, invariants list). - Phase 2d — Watson
:MemoruleAuditemission (PR #238, 10 unit tests). Every recall, write, supersede, and invalidate event emits a:MemoruleAuditentity into TriGraph for governance visibility. Closes the audit-trail gap raised in Texi’s review.
- Phase 2a — Memorule schema + write service (PR #235, 28 unit
tests). New Cypher schema for
-
Dewey (Recallgate) — SPEC-099 Phase 3 advisory wiring (Donna, four-PR
arc). Dewey is the memory-enforcement-gate archetype that ensures
recall actually fires under stuckness. Phase 3 wires the advisory
layer into existing verbs so prior memorules / postmortems /
decisions surface at the moment of action. Working names pending
legal clearance.
- Phase 3 — classifier + window + audit primitives (PR #239). Backend service that classifies whether a given interaction should trigger recall, computes the lookback window, and emits audit primitives.
- Phase 3 — single-call advisory orchestrator (PR #240). Wraps classifier + recall fetch + scoring into one MCP-callable entry point.
- Phase 3 — advisory live in
prism_todo create(PR #241). When an agent creates a TODO, the orchestrator fires and surfaces relevant prior memorules / postmortems / decisions in the response. - Phase 3 — advisory wired into signal/ack (PR #242). Signal acknowledgement path now consults the advisory to surface contextual memory at the point of action.
-
SPEC-096 v0.2 — wrap-time pre-flight (Donna, slices 1-4). Catches
ratified-but-uncommitted artifacts at
prism_wrapandprism_checkpointtime so they don’t get lost in the wrap delta — the recurrence pattern that surfaced in the 2026-05-08 dirty-tree incident (RCAc3fb59b3).- v0.2 spec doc (PR #225) — wrap-time pre-flight check for uncommitted ratified artifacts.
- Slice 1 — backend
wrap_preflightservice skeleton (PR #228, 53 unit tests). Pure backend; not yet wired into lifecycle. - Slice 2 — mcp-node
wrap_preflight_shimhelper (PR #231, 17 tests). Surface-side helper for the MCP shim. - Slice 3 — wire into delta endpoint + lifecycle (PR #232).
The check now actually fires inside
prism_wrapandprism_checkpoint. - Slice 4 — telemetry surface in
runtime_diagnostics(PR #234). Operators can watchwrap_preflightpass/fail rates over time.
-
Miranda (Wallbreak Protocol) —
method.wall-break.persistencev0.2 published (PR #222, Donna engineering author with Texi architectureapproved_with_required_revisions, Candi governance acceptance). Canonical method fragment defining Prism’s stuckness- and-persistence protocol — five trigger conditions, solution-table forcing, self-critique loop, wrap-time handoff gate, recall-on-task- start, and postmortem-on-structural-walls. Phase enforcement by social contract (Phase 1); SPEC-094 advisory integration (Phase 2) andprism_stuckverb (Phase 3) deferred until adoption gaps are observed. Working names pending legal clearance. - Plan #003 — memory-activation implementation plan (Miranda-style) (PR #227, Donna). Sequences SPEC-094 Memorules + SPEC-099 Dewey (Recallgate) + SPEC-096 wrap-pre-flight into a coherent multi-phase execution arc.
-
Dashboard topology — host name on agent + service nodes (Porsche,
PRs #217 + #218). Topology surface displays the host machine for
each agent and service node. PR #218 follows up by passing the
host’s
HOSTNAMEthrough to the dashboard container asPRISM_MACHINE_IDso the surface uses the same identifier as the rest of the stack. -
Seed-input PDF archive at
docs/inputs/(PR #245). Project seed-input PDFs preserved under version control for ownership and timestamp record. Pairs with the legal/copyright initiative that shipped the visible Ntecdev / NtecLabs footer + per-page last-updated badge +/legalpage (PR #223).
Fixed
-
Signal — canonical PID label on
system_signals_emitted_total(PR #243). The metric was carrying drifting PID labels across cardinality boundaries; now stable. Part of the 2026-05-08 signal-quality fix arc (RCAc3fb59b3). - Signal — zero subscribers treated as queued, agent → session fall-back (PR #244). Zero-subscriber emits are no longer silently dropped; recipient resolution now falls back from agent identity to session id when the agent is offline. Same RCA arc as PR #243.
Documentation
-
BIOS v2.5.0 — local auto-memory deprecated (SPEC-094 Phase 1)
(PR #216, Donna).
templates/CLAUDE.md+templates/AGENTS.mdcarry the rule that Anthropic editor host auto-memory (~/.claude/projects/*/memory/,MEMORY.md, equivalent Codex / Cursor stores) is deprecated; all persistent memory operations route through Prism verbs (prism_remember,prism_journal,semantic_recall, etc.). Operator-locked rule — only the operator can re-enable, and only after SPEC-094 acceptance criteria pass. - SPEC-094 v0.4 + SPEC-099 v0.1 drafts (PR #229, Donna). Memorules delta + Dewey (Recallgate) first drafts.
- SPEC-094 v0.5 + SPEC-099 v0.2 — Texi revisions applied (PR #230).
- SPEC-099 — Texi second-pass text fix on ACK-only test case (PR #233).
2026-05-07
Added
-
SPEC-093 — Tenant → Org → Department → Project hierarchy (Donna,
PR-A). Four-level identity chain replaces the prior flat
tenant/project model. Every Project now carries
tenant_id+org_id+department_id+pid, with FK constraints enforcing the chain at insertion. Personal-install (LAN) backwards compatibility is preserved by flat-LAN seeding: when no Department is specified, a default Department is created under the default Org under the default Tenant — existing single-user installs continue to work without operator action. PR #211 — schema + service + bootstrap + migration; PR #210 — A5/A6/A7/A8 LAN dept-hierarchy smokes + upgrade rehearsal scaffold. -
SPEC-090 —
prism_adoptverb +/projects/adopt409-idempotent surface (PR #212, Donna). New MCP verb that registers an existing git repo into Prism without recreating PIDs. The 409-idempotent surface means re-running adopt against an already-registered project returns the existing PID rather than erroring or duplicating. Solves the bootstrap-second-machine and bootstrap-from-existing-clone cases.
Fixed
- CLI Windows statusline platform-split (PR #215, Lafonda). Claude
Code statusline now uses
bin/coder.ps1via PowerShell on Windows; the existing.shpath stays for Unix. Closes the cross-platform parity gap that surfaced during the Windows install rehearsals.
2026-05-06
Added
-
SPEC-087 cloud bring-up (Render Blueprint) — Phase 1 lands
(Donna). Phase 1
OAUTH_REDIRECT_URI+ containerized Neo4j (Frank §7 amendment) lands in PR #188, completing the Render bring-up cascade that started 2026-05-04 with the v0.1 spec doc and Phase 0 Blueprint. Neo4j is now containerized inside theprism-neo4jpserv (no external Neo4j dependency); the OAuth redirect URI is threaded through env vars; the Blueprint applies cleanly against a fresh Render workspace. The cascade across PRs #182–#188 — port-contract / dashboard-probe-URLs (#185), pserv dockerCommand + port bindings (#187), DATABASE_URL dialect normalization (#186), neo4j plan upgradestandard → pro_plusper the full-capability sizing rule (#191) — is documented in the research postmortem (#189). -
SPEC-089 — Cloud Customer Onboarding + Auth (Donna). First
customer-onboarding spec for the cloud surface.
- v0.1 spec doc (PR #209). Covers the provider-agnostic
identity model, the WorkOS auth provider integration, /whoami
- /logout surfaces, and the parametric auth router design.
- Phase 1 — provider-agnostic user identity + auth-provider
setting (PR #194). Identity layer abstracted from any specific
provider;
auth_providersettings field selects which provider implementation to load. - Phase 2 (slices 2.1 + 2.3) —
WorkOSProvider+ parametric auth router +/whoami+/logout(PR #195). First concrete provider implementation; routes shape themselves around the configured provider. - Phase 2 — WorkOS auth smoke + rollback-rehearsal scaffolds (PR #196). End-to-end smoke for the WorkOS path; rollback rehearsal scaffolds for ops practice.
- v0.1 spec doc (PR #209). Covers the provider-agnostic
identity model, the WorkOS auth provider integration, /whoami
Fixed
-
Auth — default Org seeded per Tenant in OAuth
provision_from_identity(PR #192). New Tenants no longer landed without an Org row, which later broke project creation that assumedorg_idwas always resolvable. The default-Org-per-Tenant invariant matches what SPEC-093 then formalized in the four-level hierarchy the next day. -
Backend —
uvicorn --proxy-headers(PR #203).request.base_urlnow returnshttpsbehind the Render edge proxy, fixing OAuth redirect-URI generation that was emittinghttp://and breaking the WorkOS round-trip. -
Signal — stale session resurrection loop stopped (commit
fa73c35). Fixed a path where dropped sessions could be resurrected by out-of-order signal frames, creating ghost rows that confusedprism_status. -
Signal — Redis pattern subscribers no longer count for push
gating (commit
37971ec). Pattern-subscriber count was inflating the push-gating decision and causing zero-real-subscriber emits to be treated as live. Fixed to only count direct (non-pattern) subscribers. - Smoke — recall-tier3 payload shapes (PR #199). Tier-3 recall payloads were drifting from the live shape after Phase 2 ran; smoke updated to track current contract.
-
Smoke — rollback per-key PUT, count-preservation guard,
SERVICE_IDself-resolve (PR #207). Render env-var sync now patches per-key, avoiding the wipe-on-PUT class postmortem6b351dc6; a count-preservation guard catches accidental list truncation;SERVICE_IDself-resolves from local context if not supplied. -
Smoke — rollback poll
deploy.status=='live'(PR #208). Rollback smoke now polls for actuallivestatus instead of returning on firstdeploy_idreply, surfacing honest SLO. Also adds?limit=100to the deploy-list query so older deploys aren’t truncated. -
Smoke — auth
httpsassertion onredirect_uri(PR #204). Smoke now assertshttpson the redirect URI, catching the reverse-proxy regression that PR #203 fixed downstream.
Documentation
- Render bring-up cascade postmortem (PR #189, Donna research note). Documents the PR #184–#188 cascade — what the Blueprint got right, what fell over, what surfaced via Render’s native error reporting, and how the cascade was recovered. Useful reference for any future Cloud bring-up work.
2026-05-05
Added
-
SPEC-082 v0.3 — Operator-Driven Master Handoff Verbs (Donna PO,
Texi reviewed v0.1 → v0.2 → v0.3). Two new MCP verbs that turn
master election from “implicit first-registered wins, hope nobody
preempts” into an explicit operator surface:
prism_master_handoff(pid, to_identity, to_session_id?)— cooperative transfer. Caller MUST be current master.prism_master_claim(pid, to_identity, operator_id, operator_password, to_session_id?)— operator-authorized preempt. Caller proves authority via SPEC-038 §3.2 credentials; target identity is independent of caller. (The v0.1 contract had the claim verb promoting the caller — Texi’s first finding flipped this so the motivation actually works.)
to_session_idwins → otherwise candidate set is active rows for the identity within the heartbeat-freshness threshold → exactly-one fresh selects → multiple fresh rows returnstarget_ambiguouswith a candidatesession_idslist → no fresh rows returnstarget_stale→ zero rows returnstarget_not_registered. Both verbs returnstale_masteron a CAS-lost concurrent race. State updates are Redis-first per SPEC-032: the Session Manager facade flips the master slot atomically, then the Postgrescontroller_statusrows are reconciled.prism_statusreflects the new master immediately on return. NoMasterChangedenum was introduced — the existingMasterPreemptedsignal carries the delta (see below). -
prism_session_deregister(session_id)— surgical cleanup verb. Idempotent; releases both the Postgres controller row and the Redis hash + sessions-set entry for one session_id. The lever for scrubbing stale rows that piled up before the leak fix landed. -
MasterPreemptedpayload extension. All emission paths now carryprevious_master_identity,previous_master_session_id,new_master_identity,new_master_session_id, and areasonfield ("preempt"or"handoff"). Operator-driven preempts also carryby_operator=<operator_id>so the previous master can attribute the flip in audit logs. Delivery contract unchanged — direct to the previous master per the existing system-signal semantics. [PR #150b83d502]
Fixed
-
Controller-row Redis leak (postmortem
f7ff9a8e, companion fix to SPEC-082). The silent-reconnect path incontroller_service.register(§2.2) and the cross-machine force- preempt path (§2.4) both released the prior session’s Postgres row but left the Redis hash + sessions-set entry alive until the 90s TTL lapsed. Result:prism_statuscould report two active sessions for one identity for up to 90 seconds — the leak that surfaced 2026-05-04 evening and triggered the SPEC-082 motivation in the first place. Both paths now release Redis state immediately;prism_session_deregisterexists for surgical cleanup of any rows that pre-date the fix. [PR #150b83d502] -
SPEC-082 split-flush ordering (postmortem
695d29b3, hotfix to PR #150).handoff_masterandclaim_masterset the current master’sis_master=Falseand the target’sis_master=Truein the same SQLAlchemy unit of work and issued a singlesession.flush(). Migration 016’s partial UNIQUE constraint (is_master=true AND released_at IS NULLper project) forbids two active masters at any instant — and SQLAlchemy is free to reorder the target promotion ahead of the demotion inside one flush, which raised IntegrityError after the Redistransfer_masterhad already succeeded. Net effect: a Redis-vs-Postgres dual-plane split whereprism_statusreported one identity as master while the caller-must-be-master gate insidehandoffrecognised the other (the partial-UNIQUE diagnosis loop, surfaced by Texi diagnosis signal7a948a45). Fix is the same demote-flush-promote patternregister()already uses for preemption: demote the current master- flush, then promote the target + flush.
claim_masteralso now demotes ALL activeis_masterrows in the project as defense-in-depth against zombie rows from prior outages. New testtest_spec082_hotfix_split_flush.pypins the ordering by spying onsession.flush(). [PR #1520d0935a]
- flush, then promote the target + flush.
-
SPEC-082 test infra — fakeredis Lua + asyncio_mode. The new
SPEC-082 unit tests needed
fakeredis[lua](the Lua extra is required for the CAS scripts that drivetransfer_master) andasyncio_mode=autoinpytest.iniso the async fixtures pick up the right loop without per-test markers. Pinned both inrequirements-dev.txtand the pytest config so the suite runs green on a clean ephemeral container. [PR #15492424be]
2026-05-04
Added
-
Plan #10 closure — Governance Foundation at Machine Speed. Single
ratification arc executed in approximately 3.5 hours end-to-end.
Stat block:
Three feature flags shipped default-off:
Metric Value Artifacts ratified 6 (3 ADRs, 3 SPECs) PRs merged 9 (#114-#122) Production deploys 4 (avg 31.8s wall-time) Smoke assertions passed 67 RCAs (production incidents) 0 Concurrent agents 8 Signals exchanged 80–120 (zero lost or misrouted) PRISM_GOVERNANCE_RESOLVER_ENABLED,PRISM_CONSENSUS_PARALLELISM_ENABLED,PRISM_MEMORY_DOMAINS_ENABLED. Default-off invariant maintained throughout — every implementation PR proved behavioral inertness of its gated path before merge. Server1 final state: imagefc4428729bf, alembic migration 034 stable,prism_statusGREEN. See Plan #10 case study for the full timeline, agent roster, and lane retrospectives. -
Plan #10 Wave 3 ratified — SPEC-080 v0.2 (Donna PO, Texi review,
Candi authored). Tri-Graph Governance Recall + Capability Index.
Graph-backed rule/capability lookup with source, citation,
freshness, and supersession reporting. Advisory-only — never
outranks Ring authority or live
prism_startstate. Texi’s hardest review of the session: preventing graph recall from accidentally becoming a second authority system. Resolution anchored in concrete invariants — SPEC-020 Entity vs EntityState boundaries, type/edge registration before extractor writes, liveprism_startstate winning over graph projection, SPEC-065 telemetry isolation. v0.1 → v0.2 fold of 12 binding amendments completed in approximately 4 minutes. SPEC-080 Phase 2 verb (prism_governance_lookup) shipped same-day in PRs #126–#131 with a default-offPRISM_GOVERNANCE_LOOKUP_ENABLEDflag and a one-shotgovernance_backfillCLI seeding 196 :Artifact / 48 :Decision / 12 :SourceDocument+:InstructionSurface entities for PID-PGR01. -
Plan #10 Wave 2 ratified — SPEC-078 v0.2 + SPEC-079 v0.2
(Donna PO, Texi review, Candi authored).
- SPEC-078 v0.2 — Consensus-First Parallelism + Method Fragments. Formalizes a 3-tier consensus workflow (low / medium / high-architectural). Introduces method-fragment schema with a proof fragment shipped same-session.
- SPEC-079 v0.2 — Memory Domain Contracts + CI Loop. Defines 12 memory domains with read/write contracts that prevent cross-domain pollution. CI loop for continuous governance improvement.
-
Governance Foundation — Plan #10 Wave 1 ratified (Donna PO). Three
artifacts sealed in ADR #47 v0.2 → SPEC-077 v0.2 → ADR #48 v0.2 order:
- ADR #47 v0.2 — Governance Layer Precedence + Override Semantics
(supersedes ADR #45 v0.1). Establishes the 5-layer narrower-wins
model (global / tenant / org / project / user-session-runtime) with
file-level
mandatory: truefrontmatter as the only override gate. Mandatory canonical org guardrails cannot be bypassed by a narrower layer. - SPEC-077 v0.2 — Canonical Boot + Governance Resolution. Boot
model (static BIOS →
prism_start→ governance block); 5-state per-layer classification (found_nonempty/found_empty_stub/missing/skipped/invalid);PRISM_GOVERNANCE_RESOLVER_ENABLEDfeature flag default-OFF for safe rollout. - ADR #48 v0.2 — Persona / Identity / Specialization Field Model (supersedes ADR #46 v0.1). 5-field model (persona / identity / specialization / assignment / style); specialization is routing/memory/skill authority, not governance authority.
- ADR #47 v0.2 — Governance Layer Precedence + Override Semantics
(supersedes ADR #45 v0.1). Establishes the 5-layer narrower-wins
model (global / tenant / org / project / user-session-runtime) with
file-level
-
Launcher governance-var forwarding (Lafonda, PR #114
6f70b43).bin/coder.shsources$HOME/.prism/envearly (set -a / set +a wrap so vars auto-export to children) and forwards 8 governance vars (PRISM_GOVERNANCE_LAYOUT,PRISM_GOVERNANCE_ROOT,PRISM_TENANT_SLUG,PRISM_ORG_SLUG,PRISM_PROJECT_SLUG,PRISM_CONFIG_PROFILE,PROJECT_ROOT,PRISM_ROOT) to both Codex agent invocations + the Codex app-server background launch. Defensive[ -f ]test makes the source line a no-op when the env file doesn’t exist yet, so the launcher patch is independently shippable without the install-verb work. -
Install-lane governance helpers (Lafonda, PR #115
de33529). New module tree atmcp-node/src/ops/governance/:slugValidator.ts([a-z0-9-]+validation, refuses silent normalization per Texi review),envBlockWriter.ts(atomic write to$HOME/.prism/envpreserving operator extras + the operator-setPRISM_GOVERNANCE_RESOLVER_ENABLEDtoggle on re-run),templateCopier.ts(PRISM_GLOBAL.md template-copy per SPEC-077 §6, schema-version-compatible only). Install verbs do not auto-callrunGovernanceSetup()yet — held for the post-ratification activation flip. -
Runtime governance resolver +
prism_startextension (Donna, PR #1161dcf5f3). New modulemcp-node/src/ops/governance/resolver.ts:resolveGovernance()reads$HOME/.prism/env, classifies all 4 file-bearing layers per the SPEC-077 §4 5-state taxonomy, surfaces conflicts (invalid_frontmatter/dual_org_sources/layout_collision/schema_version_mismatch/layer_mismatch/slug_mismatch), reports mandatory guardrails, and composes thegov:N/Msummary per §8. ORG dual-source resolution per ADR #47 §4: narrower-wins by default; canonical wins only when broader ismandatory: true. Default-OFF — whenPRISM_GOVERNANCE_RESOLVER_ENABLEDis not exactly"true", the resolver returnsnulland theprism_startresponse shape exactly matches pre-SPEC-077 (nogovernancefield). Resolver failures are non-fatal in lifecycle — caught + logged, treated as flag-off so bootstrap never crashes on a malformed env file. 27/27 smoke assertions pass. -
BIOS templates bumped to
bios_version 2.4.0(Donna, PR #116).templates/CLAUDE.md+templates/AGENTS.mdreplace the old “Ring precedence: ORG.md > PRISM.md > this file” line with the SPEC-077 5-layer narrower-wins model +mandatory: trueoverride semantics. Behavior unchanged when the resolver flag is off. Local CLAUDE.md / AGENTS.md replicas (and the Ring 2 PRISM.md composed file) refresh on nextprism_sync_biosand re-compose.
Documentation
-
docs/architecture/governance-precedence.md(new, Desiree). Agent-facing reference for the 5-layer model: per-layer table, narrower-wins rule,mandatory: trueoverride gate, ORG dual-source resolution, layout disambiguation, and theprism_startgovernanceblock shape. Cross-references SPEC-077 v0.2 + ADR #47 v0.2 + ADR #48 v0.2 + the install-lane plan. -
docs/research/instruction-surface-inventory-2026-05-04.mdv0.1 → v0.2 (Desiree). Wave 1 ratification flip on the pending-state entries: SPEC-077 / ADR #47 / ADR #48 marked ratified; CLAUDE.md / AGENTS.md replicas note the 2.4.0 SOR vs 2.3.0 local-replica drift expected until nextprism_sync_bios; coder launcher entries flipped from “PR #114 in flight” to “PR #114 merged”;templates/prism-base.mdreference bumped to v1.3.0. -
templates/prism-base.mdv1.2.0 → v1.3.0 (Desiree). Replaces the 3-tier ring-precedence callout with the same 5-layer narrower-wins +mandatory: truetext the BIOS templates carry at 2.4.0. PRISM.md replicas re-compose to pick up the new text; this repo’sPRISM.mdwas hand-recomposed in the same PR so the project’s own instructions match its own BIOS.
2026-05-03
Added
-
Hybrid RAG fourth leg — temporal recency-decay (Donna, Plan #8 Phase 5).
semantic_recallfusion is now four-leg: vector + lexical + graph + temporal. Temporal scores each candidate asexp(-age_days / half_life)withhalf_life=180dand re-weights the existing fused candidate set rather than introducing new candidates — result-set composition is unchanged but recent-but-relevant memories rank ahead of stale ones at the same semantic score.temporal_scoreis exposed on eachRecallHitand persisted intomemory_recall_events.rrf_weights.legs.temporal. Closes the SPEC-059 §3.2 deferral. [PR #10399561fb, follow-up71a43d1] -
Graph leg traverses the tri-graph for entity-anchored queries
(Donna, Plan #8 Phase 4). When the query mentions
SPEC-NorADR-Ntokens, the graph leg now 1-hop bidirectional-walks all Semantic-layer typed edges (:REFERENCES,:IMPLEMENTS,:EXTENDS,:RELATES_TO,:SUPERSEDES,:DEPENDS_ON,:SPECIFIES,:FORMALIZES,:RESOLVES,:DOCUMENTS) and sums per-target edge counts. Queries without entity anchors fall back to the legacy:MENTIONSco-occurrence path, so existing callers see no behavior change. Closes the TRIGRAPH.md §8 Phase 5 deferral. [PR #1026771f46] -
Granular semantic edge taxonomy (Donna, Plan #8 Phase 3). The
spec / ADR / plan / retro / journal extractor now promotes section
headings into typed edges instead of collapsing them all into
:REFERENCES:## Implements→:IMPLEMENTS,## Extends→:EXTENDS,## Supersedes→:SUPERSEDES,## Related/## See also/## Complements/## Informs→:RELATES_TO. The:CAN_REFERENCEwhitelist on Canonical type pairs gates every subtype the same way it gates:REFERENCES. Existingscripts/backfill_spec_059_references.pyis idempotent and re-runs the extractor across the full corpus. [PR #101c9bb9b4] -
Recent postmortems surface on bootstrap (Donna, Plan #8 Phase 2).
prism_status(consumed byprism_start) now returns up to 5 most-recent unresolved postmortems for the calling persona, sortedcaptured_at DESC. Identity resolves from the session record first, falls back to theX-Prism-Identityheader when no session exists. Implements SPEC-063 §3.5; raises failure-relevant memory salience before the agent has to remember to recall, addressing the filed-but-not-recalled failure mode that drove the 2026-05-01 branch-confusion recurrence. [PR #100ea752f4, follow-up37dd978] -
rrf_weightstelemetry shape populated +X-Prism-Identityclient header (Donna, Plan #8 Phase 1).memory_recall_events.rrf_weightsis no longerNone— it carries{k, top_n, legs.{vec,lex,graph,temporal}.{top_n_count, mean_score, fetched, ...}}per recall, capturing observed leg contribution rather than static equal weights. The Node MCP shim now sendsX-Prism-Identityon outbound HTTP calls so the backend can attribute every recall to a persona; expected to drivecaptured_via='unknown'rate from effectively 100% to ~5%. Unblocks the SPEC-059 §3.4 dashboard panels that were rendering empty. [PR #99eb936d5] -
Dashboard
/memorypage — per-leg lift, per-agent recall, postmortem-rate trend (Porsche, PR #104). Three panels behind a new “Memory” sidebar entry between Telemetry and Daemons. Per-leg lift is a stacked-area read ofmemory_recall_events.rrf_weights.legs.{vec,lex,graph,temporal}.top_n_countwithlegImplementeddata-driven so the temporal series only appears once a non-zero contribution exists in the bucketed window. Recall-by-agent is per-captured_viastacked area with a separateunknownbucket. Postmortem trend is weekly stacked filings per persona with an unresolved-now overlay. [PR #1047c12b1d] -
Dashboard
/memorypage — Phase 3-5 panels (Porsche, PR #105). Second wave: a Graph Edge Inventory panel reads Neo4j directly (12-hour stacked-area buckets per edge type, plus current per-type totals in the legend), tracking the 11-edge taxonomy from PR #101 including the backfill spike as honest signal. The per-leg lift chart gains a count↔mean_score toggle: score view is a non-stacked line overlay (scores are not additive across legs) so the Phase 4 graph-leg lift over:MENTIONSbecomes visible as the graph line crosses above lex. [PR #105b12fb99] -
Dashboard
/memorypage — cross-cycle KPI summary panel (Porsche, PR #106, Plan #8 Phase 6). Top-of-page panel cross-tabs each Plan #8 cycle’s locked hypothesis text against live measurements with an explicit verdict tag — Cycle 1 (granular edge backfill) REJECTED with the corpus-discipline gap captured; Cycle 2 (graph-leg rewire) and Cycle 3 (temporal-score leg) MECHANISM VALIDATED with liverrf_weights.legs.{graph,temporal}.mean_scorereads. The retrospective probe-set landed the same day (5a8c739,docs/research/probe-set-2026-05-03.md) upgrades Cycle 2’s verdict to CONFIRMED on 4/4 query classes. Plan #8 final state captured indocs/research/plan-9-closure-summary-2026-05-03.md; tagplan-8-truly-complete. [PR #10659aa11b]
Notes
The five memory-correction PRs (#99–#103) shipped as a single bundled batch on 2026-05-03 evening rather than as five independent cycles. The pre-registered single-variable-per-cycle protocol from the closed-loop validation method was deliberately collapsed for this correction push; treat phases 1–5 as one super-cycle with a lumped pre/post measurement window beginning at the latest merge timestamp. Per-cycle records live onresearch/memory-system-improvements under
docs/research/cycles/cycle_0{1,2,3,4}_preregistration.md and are
re-labelled as retroactive validation records (not pre-registered
hypotheses) per the Texi architecture note 3b594f61. Forward-going,
any memory-system retrieval/scoring change requires a frozen probe-set
as a precondition — fixed query text, expected targets, baseline
snapshot, scoring rule, threshold rule, no post-hoc query editing.
2026-04-28
Added
-
prism_deployMCP verb — SPEC-051 Phase 1 (Donna). Replacesbin/prism-deploy-server1.sh(the highest-traffic agent script in the repo by token volume) with a structured-return MCP verb. Returns parsed JSON instead of dumping ~150–300 lines of rsync + docker-compose + cypher-shell scrollback into agent transcripts per call. Newmcp/deploy.pywith adeploy(target, mode)dispatcher +deploy_server1implementation; single ssh ControlMaster socket shared across the rsync, build, restart, health, and verify stages so the ~200ms handshake is paid once per verb call instead of per stage.bin/prism-deploy-server1.shshrinks from 90 lines to a ~50-line thin wrapper invoking the verb (retained for non-agent callers — CI, ad-hoc operator runs). Hardcoded API key removed per the no-hardcoded-machine-values rule; verb sources from~/.prism/credentials.personal.jsonor env.mcp/smoke_spec051_deploy.pycontract smoke against live server1 verifies{ok:true, verify:{alembic:023, trigraph_types:14, trigraph_edges:37, type_count:14, api_health:true}, duration_s:7.69}. Tracked by SPEC-051 + ADR-28. [commitb840d85, PR #7] -
prism_backup+prism_clone_fromMCP verbs — SPEC-051 Phase 2 (Donna). Two more bash scripts ported per ADR-28 (TTY-as-the-line), plus a sharedmcp/ssh_session.pyhelper extracted out ofmcp/deploy.pyso every server-touching verb amortizes the ~200ms SSH ControlMaster handshake.mcp/backup.pycaptures Prism creds + every editor MCP config known tohost_config(cross-platform viaPRISM_APP_SUPPORT) + Claude Code settings + shell rc files; writesMANIFEST.txtin the legacyrel|sizeformat sobin/prism-restore.shkeeps working unchanged.mcp/clone_from.pyorchestrates ssh +pg_dump→ local docker compose up postgres → drop+recreate →docker cp+pg_restore→ full stack up → verify (alembic, live vs. retired specs). Both registered as non-bootstrap-gated host-side operator verbs, async viaasyncio.to_thread.bin/prism-backup.shshrinks 95 → 30 lines;scripts/clone-server1-to-local.shshrinks 82 → 20 lines. Backup smoke verified end-to-end (7 files captured, 2 skipped, manifest matchesprism-restore.shreader); clone smoke is preflight-only by default and gated behindPRISM_CLONE_RUN=1for the destructive full-cycle test (drops the local prism DB).prism_deployre-verified post-refactor (alembic 023, 14 types, 37 edges, 7.21s). Tracked by SPEC-051 + ADR-28. [commitd5ad49e, PR #9]
2026-04-27
Added
-
Signal mesh architecture page (Desiree). New
/signal-meshdoc consolidates the signal subsystem into a single architecture page: lifecycle, identity-targeted addressing, three planes (verb HTTP / data WebSocket / liveness HTTP), four delivery strategies (ChannelsPush,AppServerInject,Piggyback,startup-drain), the doorbell pattern, durability backstop onsignal_queue, system signals (PeerJoined/Left/MasterPreempted), and the sender contract. Cross-refs SPEC-034/037/044/045/048 plus the Multi-Prism Controller and Agent Surfaces pages. Wired into the Architecture nav and the Project footer indocs.json. [commit637d786] -
install-landoc — refreshed for SPEC-045 unified WebSocket data plane (Desiree). Diagram edge label updated, Troubleshooting row on real-time signal delivery rewritten, and the stale “What LAN install does NOT cover” bullet about Redis exposure removed — real-time signal push works on LAN out of the box now via the authenticated WebSocket fan-out, so the old caveat misled readers. [commit637d786]
Changed
bin/coderlaunchers — Codex bootstrap prompt (Donna). Mirrors the auto-bootstrap pattern shipped earlier for Claude Code. Bothbin/coder.shandbin/coder.ps1now append a positional bootstrap prompt on thecodexinvocation that instructs Codex to (1) callprism_start(name=<project>, identity=<persona>), (2) display the Prism status card as the first line of the first substantive response, (3) fall back to the documented “MCP unavailable — operating in offline cache mode” string on bootstrap failure, and (4) summarise active context before proceeding. Closes the gap where Codex sessions launched viacoderstarted cold without hittingprism_start. The Claude Code launchers got the equivalent prompt in PR #5 (still open at time of writing). [commit42aeabe, PR #3]
Fixed
-
ADR-27 Phase 1+2 — SM facade is honestly Redis-fronted (Donna).
Surfaced after a server1 restart on 2026-04-27 demoted Donna’s stale
registration in Redis and promoted Candi (mini1, registered 70s
earlier).
prism_status(Postgres-backed) reported Donna as master;prism_whois(Redis-backed) reported Candi. Two services held competing copies of the same runtime fact. ADR-27 ratifies the invariants — (1) the session manager owns all realtime state and reads come from Redis on the hot path, never Postgres; (2) storage backends stay hidden behind their owning service, with no cross-service Redis-client imports orcontroller_registrationsreads for runtime data. Phase 1 (164fd30):controller_service.get_prism_statusswitches from_active_master/_active_peers(Postgres) toSessionStore.get_active_sessions(...)(Redis);last_heartbeatpopulated fromregistered_atas a temporary proxy. Phase 2 (0b88641):SessionRecordgainslast_seen_at,last_verb_at, and afreshness_atconvenience property;refresh_ttlHSETslast_seen_aton every heartbeat; newstamp_verb_atandget_tenant_sessions(tenant_id)SCAN aggregator;controller_service.stamp_engagementdual-writes Redis (hot path) and Postgres (audit) with non-fatal failure on either side;signal_service._resolve_identity_to_sessiondrops its directControllerRegistrationtiebreak query and orders entirely fromSessionRecord;persona_service.whoisdrops the PostgresGROUP BYfor tenant-widelast_heartbeataggregation in favor ofSessionStore.get_tenant_sessions(...);session_manager/api.pyrewritten to be honestly Redis-fronted (was a sham readingControllerRegistrationdirectly). [commits164fd30,0b88641, PR #1] -
SPEC-049 §3.4 —
manager_streamkeeps Starlette’s headers cache in sync with injectedsession_id(Donna). Cursor Bugbot flagged this on PR #1 (high severity). The previous implementation readwebsocket.headers.raw, which triggered Starlette’s cached_property onWebSocket.headersand materialised a Headers snapshot from the currentscope["headers"]. The subsequent mutation ofscope["headers"]to injectx-prism-session-idleft the cache stale, so the legacy handler readingwebsocket.headers[...]saw the pre-injection value (missing) and closed the WebSocket on auth failure. Net effect:/api/v1/sm/stream/{session_id}(the SPEC-049 §3.4 documented happy path used bymcp/session_stream.py) silently dropped the URL-form session_id. Symptoms were masked because signals fell through to the SPEC-044 piggyback fallback, but the WS plane wasn’t actually delivering live. Fix: readwebsocket.scope["headers"]directly without ever touching.headers.raw, then defensively clear the cached_property slot so the legacy handler rebuilds from the mutated scope. No upstream framework behavior monkeypatched. [commit1d0a6f4, PR #2]
v0.2.0 — 2026-04-26
First semver-tagged Prism release. Tagv0.2.0was pushed at commitb0d1584onfeat/spec-045-unified-stream. Backend + the new standalonesession-managercontainer both report version0.2.0. v0.2.0 is non-breaking for running clients — legacy/api/v1/controller/*and/api/v1/personas/*paths still respond. The breaking 410-Gone flip is a follow-up release after the agent fleet has restarted onto the SPEC-049/api/v1/sm/*paths. Headline specs shipping in this release: SPEC-049 (Identity & Session Manager service), SPEC-045 (Unified WS stream), SPEC-046 (agent surface adapters), SPEC-040 (hd_exechandoff pickup), SPEC-042 (WIP type vocabulary), SPEC-043 (start-delta symmetry), SPEC-038 v0.2 (collision policy + operator-gated force), SPEC-044 (channel push idle-wake fix), SPEC-037/045 §5.1 (server-sidedelivered_at).
Added
-
SPEC-049 — Identity & Session Manager Service (Donna’s design +
implementation). Single-writer service that owns all identity,
registration, election, and routing state under one process and one
HTTP namespace, replacing the scattered
/controller/*+/personas/*surface. New backend modulebackend/session_manager/ships in seven phases: (1a) module skeleton, (1b) session endpoints, (1c) personas endpoints + identity canonicalization, (1d) election endpoints (read-only in Phase 1), (1f) Redis-keyspace-event reaper retiring the oldControllerSweepWorker, (1g) WebSocket streaming under the manager +service.delegatecutover, (2) MCP client cuts over to/sm/*endpoints, (3) grep-guard + cleanup of legacy import surface, (4) standalonesession-managercontainer that can run separately from the API gateway. Canonical paths now live under/api/v1/sm/sessions,/api/v1/sm/personas,/api/v1/sm/elections,/api/v1/sm/ws. The legacy/controller/*and/personas/*paths still respond in v0.2.0 for fleet-wide rolling restart compatibility; the 410-Gone flip will land in a follow-up release once all live agents have restarted onto the new MCP client. [commitseb8e1ee..45b0a0b, releaseb0d1584] -
SPEC-040 —
hd_exechandoff pickup verb (Donna’s implementation). Symmetric toprism_wrap. After a session has wrapped (withnext_actionsrecorded on the wrap delta), a successor agent can callhd_execto pick up where the predecessor left off — the verb is a thin wrapper over_prism_start_implwithdelta_kind="pickup"and predecessor metadata threaded through. Closes a two-year-old vapor entry in the lifecycle plan and pairs with SPEC-043’s start-delta symmetry to make handoffs first-class events in the delta log. [commite41528a] -
SPEC-042 — WIP Type Vocabulary (Donna’s implementation).
Extensible, table-driven taxonomy for in-flight work concepts that
predate a formal SPEC:
concept,research,spec,plan,general. New tablewip_types(alembic migration023), new MCP verbprism_wip_typesto inspect the live vocabulary, andprism_wipwrites now type-tag entries against this table. Catalog is data-driven so adding a new WIP kind no longer requires a code change. [commit3bfca51] -
SPEC-043 — Session-Start Delta Symmetry (Donna’s implementation).
prism_startnow emits adelta_kind="start"lifecycle delta on every bootstrap, mirroring thewrapdelta on session close. Pairs with SPEC-040’spickupdeltas to give the delta stream a complete three-event lifecycle (start → checkpoint(s) → wrap | pickup). Visible inprism_start.recent_deltaspayload and via the WS event stream. [commit1d4ac66] -
SPEC-045 — Unified Session+Coordination Stream (Lola’s design,
Donna’s implementation). Closes the SPEC-044 LAN-reachability gap
surfaced in live test: MCP-side Redis subscriber was unreachable from
LAN clients because Redis
:6379is docker-internal on server1. SPEC-045 consolidates the live data plane onto an authenticated WebSocket served by the existing FastAPI port (/api/v1/session/ws), with Bearer +X-Prism-Session-Id+X-Prism-Identity+X-Prism-Project-Idheaders and server-side Redis pubsub fan-out to JSON envelopes. MCP gainsmcp/session_stream.py(daemon thread- own asyncio loop,
websockets>=12.0, exponential backoff 1s→30s ±20% jitter,Last-Event-Idresume) and the SPEC-034 §8 Redis subscriber is deleted. Same singleton API kept thechannel_bridge+ChannelsPushStrategycallers untouched. Heartbeat stays out-of-band on its own HTTP POST endpoint per the telecom rule (D1). gRPCCoordinationStreamservice kept in place during rollout (D3); LAN-facing role retired, full retirement tracked as TODO #97. Single auth boundary, single LAN port. Live e2e (cross-identity Lola→Donna) verified ~300ms end-to-end. [commit2e1a344]
- own asyncio loop,
-
SPEC-046 — Agent surface adapters (Donna’s design + implementation).
Generalizes
mcp/strategies/into a per-surface adapter layer that owns bootstrap + wrap hooks alongside signal-strategy selection. Newmcp/agent_surfaces/package:AgentSurfaceProtocol +BootstrapContext/WrapContextdataclasses +SURFACE_REGISTRY+ memoizedget_surface()driven byPRISM_AGENT_SURFACE. Phase 1 shipsClaudeCodeSurface(ownschannel_bridge.capture_session_lazyreset_coalescingon bootstrap,reset_allon wrap); Phase 2 ships best-effortClaudeDesktopSurface,CursorSurface,CodexSurface, andOtherSurfacefallback.prism_start/prism_wrapno longer referencechannel_bridgeby name — surface-specific lifecycle hooks are the only caller. CodexSurface carries explicit polish-queue comments naming Texi as designated owner; placeholder fields flag where SPEC-035 App Server inject hooks land.smoke_spec046_agent_surfaces.pycovers 18 checks across dispatch + Protocol conformance + bootstrap/wrap idempotency for every surface. SPEC-044 + SPEC-045 smokes re-run green. [commit1b7859a]
-
SPEC-038 v0.2 — Identity-collision policy + operator-gated force
preempt (Donna’s implementation). Three branches now formally
distinguished in
controller_service.register. (1) Same-machine reconnect (§2.2) — silent release-and-replace on terminal restart inside the 90s SessionStore TTL,release_reason='reconnect'; closes the UX gap where/exit+ relaunch as the same identity got 409’d. (2) Cross-machineidentity_conflict(§2.3) — structured 409 augmented withsame_machine: falseso the caller can tell honest collision from spoof. (3) Operator-gated force preempt (§2.4) —force=truenow requiresoperator_id+operator_passwordmatching the tenant’s bcrypt hash; missing or invalid creds → HTTP 403force_denied. Closes the v0.1 gap where any agent with the API key could silently preempt any session. Migration 022 addscontroller_registrations.process_pid(PID fingerprint),tenants.force_operator_id+force_password_hash(bcrypt). New routerPOST /api/v1/operator/force-credentials; bcrypt-hash on receipt, plaintext never logged. New MCP verbprism_set_force_credentials(bootstrap-skipped). All 6 branches verified live against deployed server1. [commit4652772] -
SPEC-044 idle-wake fix (Donna).
prism_startnow callschannel_bridge.capture_session_lazy()before returning, so a freshly-bootstrapped idle agent has the bridge ready when a signal arrives. Previously capture only fired on the next non-lifecycle verb (SPEC-041 skip), which left the doorbell silent for the exact “wake idle agent” use case SPEC-044 was written for.channel_bridge.push_doorbellnow returns a status string ("rang" | "coalesced" | "uncaptured" | "loop-closed") instead ofbool— the prior bool collapseduncapturedintocoalescedand hid this bug for a release cycle. [commit4652772]
Changed
bin/coderlaunchers — Codex CLI 0.125.0 mapping. The Codex agent path no longer invokes the stalecodex startsubcommand; it launchescodexdirectly with-C <project_dir>and explicit flag mapping. Prism autonomy → Codex--sandbox(safe-write→workspace-write,full-local→workspace-write,read→read-only); Prism mode → Codex--ask-for-approval(interactive→on-request,autonomous→never);-god→--dangerously-bypass-approvals-and-sandboxand overrides the normal mapping. Launcher also exportsPRISM_AGENT_SURFACEviaagent→surfacemapping (claude→claude_code,codex→codex,cursor→cursor) so Codex sessions stop registering asother. Newbin/smoke_coder_codex.shcovers interactive/read, autonomous/safe-write, autonomous/full-local, and-godoverride. PowerShell port matches line-for-line;pwshruntime verification pending.-modeand-autonomyare real CLI controls for Codex (versus Prism env metadata only for Claude Code, where-godadds--dangerously-skip-permissions). [commit56a9a17]
Fixed
-
SPEC-037 / SPEC-045 §5.1 — server-side
delivered_aton WS push (Donna). The signal envelope’sdelivered_atis now stamped at the WebSocket fan-out layer, not at the recipient client. Closes a reliability gap where a recipient that crashed mid-receive could re-deliver a signal that the sender already saw acknowledged. Pairs with the SPEC-037 piggyback drain to keep the “no signal lost, no signal duplicated” floor honest under WS reconnect. [commiteedee95] -
prism_whois— case-insensitive identity join +is_masterpropagation.prism_whoisno longer misses registrations whoseagent_identitydiffers only in case from the query, and theis_masterflag is now correctly populated from the live election table on the response. Both gaps had been masked by the long-running Donna/Lola single-master assumption; surfaced as the multi-agent fan-out on 2026-04-26 brought Candi, Texi, Desiree, and Lafonda online. [commit2971f01]
2026-04-26 — post-v0.2.0 tag
Same-day commits that landed after thev0.2.0tag atb0d1584(16:15 EDT). Operators pinned to the exact tag will not see these; operators trackingmainwill.
Added
- SPEC-048 (draft) — Codex app-server signal injection (Texi).
Adds a fallback-safe
CodexAppServerInjectstrategy plus the launcher plumbing it needs:bin/coder.shandbin/coder.ps1gain-codex-app-server,-codex-app-server-url, and-codex-app-server-portflags (modesoff | local | auto, defaultauto) which exportPRISM_CODEX_APP_SERVER_*env into the child Codex process. The injection strategy is best-effort — if the local Codex app-server isn’t reachable, signals fall back to the SPEC-037 piggyback path rather than failing loudly.CodexSurfaceselects this strategy when the env signals an active app-server. Smoke atmcp/smoke_spec048_codex_app_server.py. Spec stays at statusdraftpending Frank’s ratification of Texi’s design. [commitedd1d67]
Fixed
- Stream envelope — null-safe optional wire fields.
wrap_signal_envelopenow coercessignal_typeandsignal_idto strings via a_string_or(default, value)helper before placing them in the SPEC-045 §4.2 envelope, so WebSocket clients never seenullwhere the contract promises asubtype/event_idstring. Defaults:subtype="Unknown",event_id="". Closes a wire-shape gap that surfaced when rawsignal_queuerows occasionally carried nullsignal_typeafter legacy backfill. [commit2f48aa7]
2026-04-25
Added
-
SPEC-044 — Channel-Based Signal Push (Donna’s implementation).
Wires the Prism MCP server as a Claude Code Channel so signal
notifications push into idle sessions instead of waiting for the
next verb response. New
_PrismFastMCPsubclass advertises the experimentalclaude/channelcapability and captures the main MCP loop for cross-thread notification scheduling.mcp/channel_bridge.pylets the Redis subscriber thread firenotifications/claude/channeldoorbells onto the main loop with one-outstanding coalescing per drain cycle.ChannelsPushStrategy.deliverbuffers AND rings the doorbell — the piggyback path stays intact for the next-verb-call path. Launchers gain--dangerously-load-development-channels server:prism.mcppinned to~=1.27.0because the FastMCP override touches private API. Three smoke files, 11 guards, all green. [commit0f9f937] -
SPEC-037 — Backend-side signal piggyback (Donna). Eliminates the
silent-loss class where a signal landed in
signal_queuewhile the recipient’s session existed but was idle. Server now drains pending signals onto the response of every bootstrapped verb the recipient calls, markingdelivered_at+delivery_method='piggyback'in the same transaction. Closes the SPEC-034 honesty gap where the bridge reporteddelivered=truefor queued-but-undelivered signals. [commitbd2367d] -
SPEC-039 — NYI runtime contract (Donna).
mcp/nyi.pyadds the canonicalnot_yet_implementedpayload +@prism_nyidecorator +audit_nyi_markers()scanner.prism_auditnow surfaces everyPRISM-NYImarker in source plus unmarked references in constitution markdown (Rings 1-2.5 only). Hybrid failure mode: tracked stubs are advisory, untracked stubs and constitution drift flipexit_statustofail. 20 unit tests. [commitf40d3a0] -
SPEC-041 + ADR-25 — Lifecycle / messaging separation (Donna).
prism_startno longer drains pending signals — the legacy startup-drain block is gone. New_LIFECYCLE_VERBSset inmcp/server.pyspecial-casesprism_start/prism_checkpoint/prism_wrapinsiderequire_bootstrapso they skip the SPEC-037 piggyback drain too.prism_wrapdocstring now points callers atprism_signals_pendingfor last-chance delivery. Single responsibility, race correctness, hd_exec composition. ADR-25 captures the principle. Supersedes the 2026-04-24 changelog claim that signals “drain on the target’s next prism_start when offline” — delivery is now viaprism_signals_pendingor piggyback on any non-lifecycle verb. [commitf40d3a0]
Changed
-
ADR-26 v2 — Auto-declare on first use (Donna, replacing v1
strict-reject from the same day). Live testing of strict-mode
surfaced the wrong default for a solo-operator AI-FIRST workflow:
the elicitation picker forced human-in-the-loop friction every
time a fresh identity launched. Frank’s design intent: typed
identity not in registry → auto-declare and proceed.
prism_starton whois miss for non-Bot identity now callscreate_personawithfocus="(auto-declared on first launch)"andsurface_hintfromPRISM_AGENT_SURFACE, then continues bootstrap. Elicitation picker preserved as a fallback only when auto-declare itself fails (rare: backend race or validation collision). Migration is implicit — orphans self-heal on relaunch. [commitc863227]ADR number 26 was later filled in Postgres by an unrelated Diagnostic Tool Library decision (filed 2026-04-27, see/adrs/adr-026-diagnostic-tool-library-container-side-python-host-side-node), so the published ADR-26 page is no longer the auto-declare design. The auto-declare design lives canonically in the memory namespace per Frank’s standing field-collapse workaround — retrievable viasemantic_recall(query="persona auto-declare on first use"). Commitc863227remains the implementation reference.
Fixed
-
prism_wraprestored as MCP tool. The SPEC-031 refactor extracted_do_hygieneout ofprism_wrapbut left@mcp.tool()@require_bootstrapon the inner helper. Net effect:_do_hygienewas exposed asmcp__prism___do_hygiene(private API leak) andprism_wrapwas unreachable from MCP — operators could not cleanly close a session, only checkpoint. Decorators swapped back;_do_hygieneis internal-only, called by bothprism_wrapandprism_checkpointwhich gate bootstrap at the outer layer. [commita14f586]
-
SPEC-036 v0.2 — Scaffold persona-leak fix (Lola’s design,
Donna’s implementation).
CLAUDE.mdboot readsPRISM.md(step 1) beforeprism_start(step 3), so apersona: <name>line in composed frontmatter was being absorbed as the agent’s identity, racing with runtime identity resolution. Two failure modes confirmed in the field: offline mode (Lofanda on Candi’s Windows install) adopted Lola for the entire session; online mode (Donna on mini2) greeted as Lola before self-correcting at step 3. Scaffolder now stripspersona:from composed frontmatter and_ACTIVE_CONTEXT.md. [commits5bbb138,c439ebf]
2026-04-24
Added
-
SPEC-034 — Agent-to-Agent Signal Delivery (Lola’s design, Donna’s
implementation). Redis pub/sub transport + pluggable per-surface
delivery strategies let Prism agents send structured signals
(ReviewRequested, ReviewCompleted, TaskAssigned, Acknowledgment,
StatusUpdate) to named peers without human relay. Signals persist
in
signal_queue(durability backstop) and drain on the target’s next bootstrapped verb when offline. Broadcast support viato="*". Full §3 Lola↔Donna round-trip verified end-to-end bymcp/smoke_spec034_signal.py. Deployed to server1. [commitsf1c536f,d8abf06,186efec,8d9d0e3] -
SPEC-035 — Agent engagement signal + routing preference (Donna).
Active sessions advertise an
engagementstate on the controller registration (activevsidle), andsignal_service.sendnow prefers anactivepeer overidlewhen the same identity has multiple registrations. Eliminates the racing-Donnas case where a signal addressed to “Donna” could land on whichever session registered last instead of the one currently doing work. [commit11537f7] -
SPEC-031 —
prism_checkpointverb + enrichedprism_statuspayload (Lola’s design, Donna’s implementation).prism_checkpointruns allprism_wraphygiene (delta flush, memory triggers, last_wrapped_* write-back) without deregistering the caller from the controller — so agents can “save the game” between discrete work units without re-bootstrapping.prism_statusresponse reshaped to SPEC-031 §4.2: project block, session block, agents flat list, top-N pending TODOs,pending_nudgesstub (ready for SPEC-029), pre-formattedstatus_linematching the SPEC-021 Ring-0 format.bios_versionbumped 2.1.0 → 2.2.0 with checkpoint-vs-wrap guidance inCLAUDE.md/AGENTS.md. [commits2a1bc33,9aad2d5] -
Persona registry + runtime identity (Lola’s design). Tenant-scoped
personastable (alembic 020) records persistent agent identities decoupled from editor surfaces — surface stays baked (physical), identity is runtime-assigned. Two MCP verbs:prism_persona_create(bootstrap-gated) andprism_whois(NOT bootstrap-gated — needed to answer the “who should I be?” question before bootstrap completes). Redis cache atprism:personas:{tenant_id}with Postgres preload on backend lifespan; no TTL, write-through invalidation.bin/coder --as <identity>launcher flag exportsPRISM_AGENT_IDENTITYto the child editor process without touching editor config.prism_startgained anidentityarg and an identity-elicitation branch — when the env var is unset, start returns{requires_elicitation: true, elicitation_kind: "identity", personas: [...]}carrying the whois payload so the agent can prompt the operator and re-enter with the chosen identity.install/install.pyno longer bakes identity defaults into the MCP env block. [commit09e53ae] -
MCP heartbeat auto-reregister on 410 Gone — session-drift recovery.
Previously, a stale-swept session (controller_sweep_worker marking
released_at=nowafter ≥10min of no verb calls) would silently drop the agent off the routing table; the heartbeat loop would log the 410 and stop. Now the heartbeat mints a fresh session_id, callsPOST /controller/registerwith the same identity/surface/machine_id, and fires a caller-supplied callback that updates the MCP’s_SESSION_IDSand the HTTP client’s session header. Agents self-heal without operator intervention. [commitd38ee76] -
/metricsPrometheus endpoint. FastAPI now mountsprometheus_client.make_asgi_app()at/metrics. An always-onPrometheusMetricReaderwrites intoprometheus_client.REGISTRYalongside the OTLP exporter (whenOTEL_EXPORTER_OTLP_ENDPOINTis configured). SPEC-030 Phase 6 counters + SPEC-034 signal counters are now scrapeable without an external collector. [commitb89c710] -
SPEC-034 observability counters.
signals_sent_total(by pid + signal_type + delivered|queued|broadcast outcome),signals_drained_on_startup_total(per drain call, quantity = signals delivered),system_signals_emitted_total(PeerJoined / PeerLeft / MasterPreempted × session|broadcast target). Mirrors SPEC-030 Phase 6 pattern; lazy import + try/except so metric bugs never fail the service. [commit920e42a] -
Cross-platform backup + restore scripts.
bin/prism-backup.sh+bin/prism-restore.sh(bash, Mac/Linux) andbin/prism-backup.ps1+bin/prism-restore.ps1(pwsh 7+, Windows) snapshot user-scoped Prism state (credentials, editor MCP configs, shell rc, PowerShell profile) into~/.prism/backups/<TS>/. Restore is interactive with per-file diff- confirm + pre-restore safety copies. Manifest format is
identical cross-platform.
[commits
d3cc767,371ed88]
- confirm + pre-restore safety copies. Manifest format is
identical cross-platform.
[commits
Changed
-
prism install— cross-platform industrialization (Lafonda + Donna, parallel). Mode-aware install with--mode local|lan|cloud+ interactive 1/2/3 prompt. Local mode preflights Docker (CLI + Compose v2 + daemon); LAN mode preflights/health+/api/v1/projectsauth before touching any config. Cross-platform launcher setup: macOS/Linux chmod + symlink + managed~/.zshrc/~/.bashrcblock; Windowscoder.cmdshim- User PATH via
[Environment]::SetEnvironmentVariable. Per-editorPRISM_AGENT_IDENTITY/PRISM_AGENT_SURFACEwritten into every MCP block (Lola for Claude Desktop, Donna for Claude Code, etc.). Auto-detect existing backend URL+key from editor configs before falling back to defaults — never clobbers a working install without--force. Backend preflight symmetric for both local and lan. MCP venv auto-provisioned on first run; Python dep preflight.cmdUpguards against accidental second-backend starts on LAN clients (installed mode must belocal). [commits65d47c7,543440c,48f7b1d,9538981]
- User PATH via
-
bin/coder.shself-sufficient + nativebin/coder.ps1port. Launcher derivesPRISM_ROOTfrom script location and readsPRISM_API_URL/PRISM_API_KEY/PROJECT_ROOTfrom~/.prism/credentials.personal.json. Env vars still override; onlyPRISM_API_KEYhard-fails when absent from every source. PowerShell 7+ port matches the bash contract line-for-line. Drops the DFW-Helpers.ps1 dependency the legacy launcher carried. [commit678ffb3] -
docs/INSTALL.mdrestructured into Local / LAN / Cloud (deferred) client-install modes. Separate preflight + cred-handling for each mode. Server-side install (backend host) moved to a trailing section pointing atDEPLOY.md+bin/prism-server-install.sh. [commits0e58558,a075a99] -
**
coderlauncher arc — single-dash long flags + identity un-baking- Windows PATH parity.** Both
bin/coder.shandbin/coder.ps1flipped to single-dash long flags (-as,-mode,-autonomy,-god) so the bash/pwsh contracts match line-for-line. The TS CLI no longer bakesPRISM_AGENT_IDENTITYat install time, socoder --as <Identity>actually overrides instead of fighting the baked default.coder.ps1gained Windows User-PATH install via[Environment]::SetEnvironmentVariableso a fresh Windows install picks upcoderwithout a manual PATH edit. [commits1726e64,b7a440b,b74424a]
- Windows PATH parity.** Both
Fixed
-
Lease conflict path — ASYNC SQLAlchemy gotcha.
lease_service.request’stry: await session.flush() except IntegrityError:pattern was hitting two stacked bugs on unique-violation: (1)MissingGreenletduring asyncpg’s dialect-level exception translation (context lost); (2)PendingRollbackErrorfrom outer-transaction poisoning even with a savepoint. Rewrote usingpostgres_insert.on_conflict_do_nothing( index_elements=[...], index_where=text("released_at IS NULL"))against the partial UNIQUE index — no exception raised, no greenlet/rollback recovery needed, gRPC servicer correctly surfacesALREADY_EXISTSinstead ofUNKNOWN. [commit6b2727f] -
smoke_spec030_phase1assertion shape. Updated to match SPEC-031 §4.2’s newprism_statuspayload (project block, session block, agents flat list, total_agents, status_line) instead of the pre-SPEC-031{pid, master, peers, caller, total_active}fields. [commit6b2727f] -
docker-compose.personal.yml— Redis loopback bind. Redis was internal-network-only; SPEC-034 MCP subscribers run host-side and need pub/sub access. Addedports: ["127.0.0.1:6379:6379"]with loopback-only binding (same posture as backend’s 8765 mapping). Server LAN deployment intentionally unchanged — exposing server1’s redis is a separate deployment decision with ufw/auth implications. [commit8d9d0e3] -
backend-grpccontainer healthcheck. The Dockerfile’s default HTTPcurl :8000/healthHEALTHCHECK could never pass in a gRPC-only container. Compose now overrides with a realgrpc_health_probe -addr=:50051against a properly wiredgrpc.health.v1.Healthservice. No more perpetually-unhealthy backend-grpc confusing operators during real incidents. [commitb960f21] -
Prism self-host bootstrap + reserved-name error shape. The
RESERVED_NAMESPACESguard (last touched in the DFW→Prism rename at commit7f26450) was blocking the legitimate self-host seed — a fresh personal stack couldn’t bootstrap its ownPrismmeta-project because the reserved-name check fired before the tenant had any rows to collide with.bootstrap_service.bootstrapnow detects the self-host seed case (name="prism"and zero Prism-named projects in this tenant) and passesallow_reserved_name=Truethrough toscaffold_service.build_manifest. The guard still blocks users naming their own project “Prism” on a tenant that already has one, plus the other reserved names (tools,vault,shared,_framework). Router now returns a structured HTTP 422 on reserved-name violation instead of a raw 500 + stack trace. Caught by Candi on mini2 during a cleanprism up+prism install --mode localwalk-through. [commit823521b] -
Windows-clone install flow — CRLF guardrails + missing
cli/dist/note. Windows Git’s defaultcore.autocrlf=truewas silently corruptingbackend/docker-entrypoint.shon cold clone — the shebang became#!/usr/bin/env bash\r, the Linux kernel readbash\ras the interpreter name, andbackend-grpccrash-looped with no clear error surface (prism upstill reported the HTTP backend healthy on 8765). Two-layer defense: (1) repo-level.gitattributesforcing LF on shell / Dockerfile / Python / YAML / TOML / JSON / Markdown, keeping*.ps1 / *.cmd / *.batat CRLF for native Windows tooling; (2) Dockerfile-levelsed -i 's/\r$//'on the entrypoint beforechmod, so the image self-heals regardless of how the source reached the host.docs/INSTALL.mdpicked up a “Windows line-ending note” subsection, acli/dist/-not-committed note (thenpm installpreparescript builds it — a fresh clone must run that beforeprism ...works), and two new troubleshooting rows covering theenv: 'bash\r'symptom + the missing-dist module-not-found symptom. Caught by Candi during the 2026-04-24 Windows retest. [commita5fbb9c]
Runtime verification
All four SPEC-030 smokes pass against server1 after this arc:smoke_spec030_phase1, smoke_spec030_leases, smoke_spec030_approvals,
smoke_spec030_phase3 — 100% green. SPEC-034 full §3 Lola↔Donna
round-trip verified via smoke_spec034_signal.py against localhost.
2026-04-23
Added
-
SPEC-032 Phase A — Redis session plane dual-write (Option B).
MCP clients never connect to Redis directly — coordination flows
through
SessionStoreon the backend (register/refresh_ttl/release/ get_master/get_active_sessions/publish_*). CD-vs-CD tie handling + fakeredis integration tests. Hard prereq on backend startup:session_store connectedlog line or backend refuses to start. [commits642bc61,dc68c14] -
SPEC-030 Phase 5 — Approval flow + Phase 6 — Observability.
approval_requeststable with CHECK-constrained statuses (pending| approved|rejected|timed_out). Partial indexes on pending-only rows (hot path: push + timeout sweep + requester listing). Phase 6 brings OTelMeterProvider+ five controller counters (elections, stream events, lease grants, approval lifecycle, stream drops) + active-registrations observable gauge. OTLP exporter via gRPC; no-op whenOTEL_EXPORTER_OTLP_ENDPOINTunset. [commits6c95f48,31f6fa8]
Fixed
- Installer stamps per-editor identity vars. Every editor’s MCP
block now carries
PRISM_AGENT_IDENTITY+PRISM_AGENT_SURFACEso the controller can tell Lola (Claude Desktop) from Donna (Claude Code) from Cursor from Codex instead of all four registering asunknown/other. Caught during a multi-agent session where both Desktop + Code ended up unregisterable-as-peers. [commitac47715]
Earlier
For entries older than 2026-04-23, seegit log --oneline on main.
The project history from DFW → PrismGR → Prism is told narratively
in History. The changelog proper starts when the controller
plane (SPEC-030) + session plane (SPEC-032) shipped together, which
is the moment Prism became operationally stable enough to warrant
curated release notes.
