feat(persona): typed Engram + admission membrane types (#1121 PR-1)#1129
Merged
Conversation
PR-1 of the AIRC inbox → cognition-admission → engram-storage bridge described in continuum#1121 and elaborated in today's airc design discussion (Joel + Codex + claude tab #1). Pure value types only — NO Recipe impl, NO admission gate logic, NO PersonaInbox wiring, NO ORM persistence path. Subsequent PRs layer those over these types. Adds: - Engram { id, kind, content, origin, recall_keys, admitted_at_ms, trust_state_at_admission, admission_trace_id } — the storable unit - EngramKind { Episodic, Semantic, Procedural, SelfReflection } — biological-memory analogs as a single discriminator (vs separate types per kind, which composes badly) - EngramOrigin enum { Airc(AircMessageRef), Chat(ChatMessageRef), Tool(ToolInvocationRef), SelfReflection { parent_engram_id } } — variant-typed provenance so each origin's identity primitive is type-system-enforced - AircMessageRef — protocol-compatible reference (transport=airc, room_id, message_id, sender_id, sent_at_ms, received_at_ms, content_hash, signature, proof_refs, schema_version, client_name). Per Joel 2026-05-13: continuum accepts AIRC data by proof/contract, NOT by client identity. Official airc CLI is not privileged; client_name is informational only and never load-bearing for trust decisions. Any producer emitting valid envelopes is acceptable. - ChatMessageRef + ToolInvocationRef — sibling reference types - AdmissionDecision { Admit, Drop, Quarantine } — three terminal outcomes from the admission gate. Quarantine is forensic-not- destructive (per cognitive-immune-model #1122 §3.8) — preserves candidate without admitting to live recall surface - AdmissionDropReason { NotMemorable, PolicyDeniedAdmission, Duplicate } — typed reasons (categorized intentional rejection) - AdmissionError { EnvelopeVerificationFailed, TrustBoundaryRejected, ReplayDetected, RecipeFailure, UnsupportedSchemaVersion } — thiserror typed failure modes for the admission machinery itself. Per Joel's no-fallback rule and the no-try/catch-in-execute discipline: errors are returned not swallowed. Same shape as NoLocalModelLoadable (#1089) and NoMultimodalBase (#1074). - TrustState { Untrusted, Authenticated, Knocker, ApprovedPeer, IntragridMember, SocMember, SelfTrust } — models policy/trust of source, NOT implementation brand (per Joel 2026-05-13). Ordered with PartialOrd so admission gates can compare source_trust >= threshold directly. Convention notes: - Uuid fields use #[ts(type = "string")] — matches existing pattern in cognition_io.rs / channel_items.rs - Timestamps are u64 epoch ms with #[ts(type = "number")] — matches existing PersonaInboxFrame.oldest_timestamp pattern. Workspace chrono crate doesn't have serde feature enabled by default and the persona modules use the u64-epoch shape consistently - All types ship with #[derive(TS)] + export_to ../../../shared/generated/persona/<TypeName>.ts - ts-rs export triggered via explicit export_bindings_<typename> tests per the gpu/memory_manager.rs pattern Validation: - 20/20 tests pass: serde roundtrips for every type, discriminator- tag verification for tagged enums, thiserror Display + serde paths, TrustState ordering for threshold comparison, optional client_name (None + non-airc-CLI value both accepted), all 10 ts-rs export_bindings tests - 10 generated TypeScript files materialize under src/shared/generated/persona/ (Engram.ts, EngramKind.ts, EngramOrigin.ts, AircMessageRef.ts, ChatMessageRef.ts, ToolInvocationRef.ts, AdmissionDecision.ts, AdmissionDropReason.ts, AdmissionError.ts, TrustState.ts) Deferred to follow-up PRs: - PR-2: AircEvent envelope + IsMemorable Recipe impl + admission gate logic (the cognition that produces these types' values) - PR-3: PersonaInbox / PersonaInboxFrame wiring (the integration) - PR-4: Engram ORM persistence path - PR-5: Recall surface (engrams → RAG context) Pairs with cognitive-immune-model (#1122) — the storage substrate those defenses operate over. Pairs with forge-alloy proof contracts (#1119) — same typed-Rust-with-ts-rs-export discipline applied to the runtime cognition layer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 13, 2026
joelteply
added a commit
that referenced
this pull request
May 13, 2026
* feat(persona): IsMemorable Recipe + admission gate (#1121 PR-2) (#1133) Layers the admission policy machinery over the storage-shape types shipped in PR-1 (#1129). Splits cleanly into two responsibilities: - Gate (structural) — `AdmissionGate::admit()` runs prereqs that are independent of any specific persona's policy: envelope structure verification, trust-tier threshold check, replay protection. Failures here return typed `AdmissionError` variants, never silent drops. Always emits a `SEAM_ADMISSION` trace entry so forensics see the gate ran (matches `recorder.rs`'s always-call-record_turn discipline). - Recipe (policy) — `IsMemorable` trait. Implementations decide whether a candidate that *passed* the structural prereqs should be admitted, dropped, or quarantined. Different personas plug in different recipes (a fuzzy/agent persona uses permissive `HeuristicIsMemorable`; a SOC governance persona will use a strict policy-driven recipe in PR-3+). Ships the v1 default `HeuristicIsMemorable`: dedup → length → noise phrase → admit. No quarantine outcome (binary on inputs); the first quarantine-emitting recipe will be a similarity-based one in a later PR. `AdmissionConfig::permissive_v1()` (Authenticated threshold, 24h quarantine TTL) and `AdmissionConfig::strict_v1()` (IntragridMember threshold, 1h TTL) cover the two starting positions. 20/20 unit tests cover: every `AdmissionError` path (envelope, trust, replay, recipe failure, schema version), heuristic policy decisions (short / noise / duplicate / admit-with-provenance), trace seam emission invariant (every path emits exactly one SEAM_ADMISSION), recipe-error/quarantine propagation, config preset thresholds, and ts-rs binding generation for the two TS-exported types (AdmissionCandidate, AdmissionConfig). Pure value layer; no PersonaInbox wiring, no ORM persistence, no AIRC event-converter — those land in PR-3+ on top of this gate. Pairs with: - persona::engram (storage-shape types from #1129) - persona::trace (SEAM_ADMISSION constant added here) - docs/grid/COGNITIVE-IMMUNE-MODEL.md (defense posture this gate participates in: apoptosis-cheaper-than-corruption, B-cell anergy, forensic-not-destructive) Card: continuum#1133. Parent design: continuum#1121. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(admission): pre-normalize noise phrases + symmetric envelope tests Folds in two review nits from claude-tab-2 on continuum#1134: 1. **Pre-normalize noise phrases** at construction time (lowercased + trimmed) so `IsMemorable::evaluate` doesn't re-lowercase 8 phrases per call. Heuristic recipes are the per-message hot path; this was wasted work. Adds `HeuristicIsMemorable::with_noise_phrases<I, S>( min_len, phrases)` constructor that does the normalization once; `default_v1()` routes through it. 2. **Symmetric envelope-empty-field tests**. Coverage previously had only `empty_signature_returns_envelope_verification_failed`; the `content_hash` and `schema_version` empty-field branches in `verify_airc_envelope` were uncovered. Asymmetric coverage lets one of the three regress silently. Adds the matching two tests. Tests: 22/22 persona::admission pass (was 20). No behavior change for admit/drop decisions; same envelope structural failures, same trust / replay / recipe paths. Same pre-existing test_id prefixes preserved. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Test <test@test.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3 tasks
joelteply
added a commit
that referenced
this pull request
May 13, 2026
…1132 PR-2) (#1136) (#1137) The auto-generated per-module index.ts barrels in shared/generated/ must stay in sync with the .ts files emitted by the ts-rs export tests. When they drift, types are invisible to TS consumers even though the .ts file exists on disk — exactly the regression that bit PR #1129 (commit db271d3 manually added 12 export lines after the fact). This ratchet makes the same regression structurally impossible: - Walks every module dir under src/shared/generated/ - For each, lists the .ts files on disk + parses index.ts for `export type { X } from './Y'` lines - Asserts every on-disk file is referenced; every reference has a file - Failure message names exact drift + suggests `npx tsx generator/generate-rust-bindings.ts` recovery Critical correctness detail: extracts the FROM path (`Y`), not the exported type name (`X`). ts-rs `#[ts(rename = "...")]` produces `export type { ToolCall } from './AgentToolCall'` where the file is AgentToolCall.ts but the type is renamed to ToolCall. Earlier draft of this ratchet got this wrong and falsely flagged every rename usage on canary; corrected before commit. Tests (8/8 passing on canary state): - 5 parser unit tests pinning canonical / rename / double-quote / multi-line / malformed-tolerance behaviour - 1 drift-detection unit test asserting both regression modes (missing-from-barrel + dangling-export) surface correctly - 1 integration scan over real shared/generated/ tree - 1 known-modules sanity check guarding against accidental dir deletion hiding drift behind an empty module Same shape as Lane F PR-1 deletion ratchet (#128) — walk source, assert pattern, fail loud with actionable message. Card: continuum#1136. Lane partner: claude-tab-2 PR #1135 (#1132 PR-1, AIRC + queue-lifecycle smoke slice; this is the ts-rs export check slice they explicitly handed to me). Co-authored-by: Test <test@test.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 13, 2026
joelteply
added a commit
that referenced
this pull request
May 14, 2026
) Closes the e2e admission loop on top of the storage types (PR-1, #1129) and the gate machinery (PR-2, #1134) by giving callers ONE pure-Rust object — `InboxAdmissionRunner` — that wraps the recipe + config + trust mapping for a persona, exposing a single `admit(&inbox_msg, ...)` method that returns the typed `AdmissionDecision`. What ships: - `InboxAdmissionRunner<R: IsMemorable>` — generic per-persona runner. Convenience constructors: `default_v1()` (HeuristicIsMemorable + permissive config + permissive trust mapping) and `strict_v1()` (same recipe + strict config + strict trust mapping). - `TrustMapping` — configurable map from `SenderType` (Human/Persona/ Agent/System) to `TrustState`. `default_v1()`: Human=IntragridMember, Persona/Agent=ApprovedPeer, System=SelfTrust. `strict_v1()`: demotes Persona+Agent to Authenticated for SOC governance contexts. - `inbox_message_to_candidate(msg, mapping)` — pure converter. Synthesizes a `ChatMessageRef` origin (internal Continuum chat is Chat-origin, not AIRC; AIRC envelope path lands in PR-5 alongside the AIRC event converter that carries signature/proof material the inbox doesn't). - `inbox_message_to_origin(msg)` — pure helper (always Chat for v1). - `content_hash_sha256(s)` — canonical hash format `"sha256:<hex>"` used by the converter so dedup keys are consistent across all admission paths. What this PR does NOT ship (deferred): - Call-site integration with `PersonaInbox::drain_frame()` — PR-4 adds the actual call from the cognition path. - Engram persistence — admitted engrams come back from the runner; caller stores them. PR-5+ adds the ORM persistence path. - AIRC envelope origin converter — separate slice; AIRC events carry signature/proof material `InboxMessage` doesn't. Tests: 16/16 covering content_hash_sha256 (canonical format, deterministic, distinguishing), TrustMapping (default + strict), pure converters (origin always Chat, candidate carries full provenance, trust varies by SenderType), runner end-to-end (admit well-formed, drop short, drop duplicate, strict-admit System via SelfTrust, strict- reject Persona at trust boundary, custom recipe via generic, accessors, seam-emission invariant across outcomes). Card: continuum#1140. Builds on continuum#1129 + continuum#1134 (both merged on canary). Co-authored-by: Test <test@test.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 14, 2026
joelteply
added a commit
that referenced
this pull request
May 14, 2026
…#1185) Per task #71 — survey of every .json under src/system/recipes/. Findings: the 28 split into 3 pipeline shapes (15 static-view, 10 single-persona-chat, 1 full multi-persona) plus 2 outliers (gan, academy-training). The 10 single-persona-chat are missing 6 steps that multi-persona-chat has (loop-risk, fast-respond, training-mode, record-interaction, chat/send, cooldown). NO recipe currently integrates the engram admission gate shipped on canary in #1129/ #1134/#1143/#1155/#1163. 5 identified gaps with concrete next-sprint cards: 1. Engram integration in Shape B + C (11 recipes need cognition/ admit-inbox-message + cognition/recall-engrams) 2. Resolve academy-training half-migrated state 3. Document gan orphan intent 4. Shape B → Shape C decision (or shared inheritance) 5. version field discipline across all 28 Pure docs PR. Output at docs/cognition/RECIPE-AUDIT-2026-05-14.md. Closes #71. Co-authored-by: Test <test@test.com>
2 tasks
joelteply
added a commit
that referenced
this pull request
May 15, 2026
…ract (#1282) Add `tests/no_cpu_fallback_contract.rs` — three forbidden-strings ratchets that fail the build if a future PR weakens the no-CPU-fallback contract: 1. `select_best_device_panics_loudly_on_no_gpu` — asserts `inference/model.rs::select_best_device` keeps the `panic!("No GPU device available for inference. CPU fallback is disabled.")` loud-fail and tries CUDA + Metal before panicking. 2. `ort_providers_documents_no_cpu_fallback_contract` — asserts `ort_providers.rs` keeps the "CPU fallback is forbidden" comment that documents the rule from source. 3. `llamacpp_adapter_uses_loud_fail_for_no_local_model` — asserts `LlamaCppAdapter` uses the typed `NoLocalModelLoadable` error (shipped in #1093 / lane A PR-2) rather than a silent skip. Pattern: same forbidden-strings ratchet shape as lane F PR-2 (#1129 TS persona forbidden-strings), applied to the Rust inference layer. A test failure points the future-PR-author at the exact contract they're about to weaken. Closes the acceptance criterion #3 of #1262 ("regression test per fallback path"). Final PR (4 of 4) for the silent CPU fallback audit. Verified: - cargo test --features metal --test no_cpu_fallback_contract: 3 passed, 0 failed Lane: alpha flywheel #1272 lane 6. Audit: #1262 (comment) Co-authored-by: Test <test@test.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR-1 of the AIRC inbox → cognition-admission → engram-storage bridge described in #1121 and elaborated in today's airc design discussion (Joel + Codex + claude tab #1).
Pure value types only — NO Recipe impl, NO admission gate logic, NO PersonaInbox wiring, NO ORM persistence. Subsequent PRs layer those over these types.
What ships
Joel's protocol-not-client rule
`AircMessageRef` is a protocol-compatible reference, not a binding to the airc CLI. Per Joel 2026-05-13 (relayed by Codex): Continuum accepts AIRC data by proof/contract, not client identity. Any producer emitting valid envelopes (correct `transport=airc`, `signature`, `sender_id`, etc.) is acceptable. `client_name` is optional and informational only — never load-bearing for trust decisions. Tests verify that None and non-airc-CLI client_names are both accepted at the type level.
`TrustState` similarly models policy/trust of the SOURCE, not which implementation produced the data.
Cross-references
Test plan
Deferred to follow-up PRs
🤖 Generated with Claude Code