Operations · 4. Memory and Trust

Memory is where you look at what the daemon knows. Trust is where you look at whether you can rely on it. This chapter is reference. Each screen leads with what it is for and why you would open it, then the exhaustive control list.

4.1 Memory › Facts: the whole visible store

Open this when you want to answer "did that get written, and when". It is the durable record: every fact the daemon can currently see, paged, searchable, and rewindable to any point in the past.

This screen is not the section-model renderer everything else uses. It is hand-built, because it needs server-side pagination, server-side search and a per-row dereference of the full untruncated value (render.js:10588).

The toolbar

ControlTypeDefaultWhat it doesQuery parameter
searchsearch boxemptyServer-side search across entity, key and value. 250 ms debounce, then a full reload from page oneq
as ofdatetime-localemptyThe ingest-time machine. Shows the store as it was at that instant. A tag appears in the count line when setas_of_unix_ms
supersededtoggleonInclude facts retired by a cross-entity supersedeinclude_superseded=0 when off
reserved __\*toggleoffInclude daemon-reserved entities: coordination announces, extension grants, session bindings, legal holdsinclude_reserved=1 when on

Turn superseded off when you want only what currently resolves. Turn reserved on when you are debugging coordination, punchcards or extension grants; those are all facts under reserved prefixes, not separate files (daemon chapter 1 §1.8).

Clicking a reserved-prefix chip turns the reserved toggle on for you, because a prefix filter for __x:: with reserved facts hidden would return nothing (render.js:10779).

The count line, and the census

The count line reads, for example:

100 shown of 4,812 visible · 5,026 stored (98 private + 116 reserved hidden)

Those numbers are not estimates. The stored figure and the private/reserved split are derived from two limit=1 probes against the same route, one with reserved off, one with reserved on, so the split comes from the daemon's own response fields (render.js:10672). With a search or prefix active, "visible" becomes "matches".

Prefix chips

Below the count, up to 12 chips, one per entity prefix present in the loaded rows, each with its count, plus an all chip. Clicking one applies a server-side entity_prefix filter and reloads; it is not a client-side hide.

Groups are collapsible <details>; the four largest open by default and your open/closed choice survives paging (render.js:10760). Groups carry a colour tint by prefix: execplan accent, bench ok, incident critical, design trust, session warn (render.js:10566).

A row, and what expanding it does

A row shows key, entity, badges and a stored-at timestamp, over a truncated value. Two badges matter:

BadgeMeans
supersededRetired by another fact. Its superseded_by id is in the tooltip
N chThe value was truncated at N characters. Open the row for the full text

Clicking or pressing Enter expands the row, which fetches the full fact by id and renders every field: fact_id, entity, key, actor, confidence, horizon_class, tokens, version, stored_at, and superseded_by where present, then the complete value, pretty-printed if it parses as JSON (render.js:10711). If the dereference fails, the drawer says so with the HTTP status and falls back to the row's truncated value rather than showing nothing.

Paging

LimitValueBehaviour
Page size100 rowsServer-side cursor pagination
DOM cap2,000 rowsPast this, paging stops and the page says: narrow with search or a prefix chip
Infinite scrollonA sentinel 500px below the fold triggers the next page

A Load more button also appears, showing the remaining count when the daemon reports a total.

The degraded path

On a daemon without the listing route, a 404 on the first page flips the whole surface to the recent-window feed with a warning banner saying exactly that, and no server paging or search (render.js:10837). The banner is not decoration, the numbers you see afterwards are a window, not the store.

4.2 Memory › Memory: the recent window, per tenant

Open this when you want a quick read on which tenants are active. It is the last 50 facts, grouped by tenant, over GET /v1/console/facts?top_k=50 (pages.js:208).

ControlDefaultWhat it does
Filter tenants…emptyClient-side filter over the rendered rows
hide system tenantsonHides tenants whose id starts with __, __agent::, __ops::, __bootstrap__:: and siblings, which carry daemon internals

Each tenant expands to its eight most recent facts as key/value rows. This is a summary surface; Facts (§4.1) is the authority.

4.3 Memory › Tenants: and the AMR defaults panel

Open this to see which memory stores exist and how retrieval is routed for each. Adaptive Manifest Routing (AMR) picks retrieval lanes per query; this screen is where the default lane policy lives (pages.js:228).

The header controls

ControlWhereDefaultWhat it does
⚙ cogTenants card header, right-Reveals the AMR defaults card above the list. It starts hidden
hide system tenantsTenants card header, rightonView filter over the list
Filter tenants…First row of the listemptyClient-side filter

The AMR defaults panel

Set the lane policy once; tenants inherit unless pinned. The panel opens with a subscription line stating the current entitlement, then the lane controls (pages.js:115):

ControlTypeDefaultWhat the lane is
automatic, let AMR choose lanestoggleonRecommended. AMR reads the lane manifest and fuses the lanes that earn their tokens, per query
lexical (BM25)info rowalways onFree, local. Not a toggle; it cannot be turned off
dense lanetoggleoffSemantic similarity over embeddings: meaning, not spelling. Bring-your-own-embedder or managed
graph lanetoggleoffEntity links walked at query time
entity lanetoggleoffWho/what-keyed recall: ask about a person, get their dossier
event lanetoggleoffTime-anchored recall: what happened, when, in what order
nav lanetoggleoffSummary-tree descent for corpora too large to scan
verbatim lanetoggleonExact-quote recall without duplicating content. Free, local
Apply defaults to all tenantsbutton-See below

Expanding a tenant gives the same lane list, prefixed by a use AMR defaults toggle (on) that pins or inherits, and a Collaborate with team row marked as a paid-plan capability.

Apply defaults to all tenants is STUBBED, and the source says why: there is no bulk route. Only a per-tenant category PATCH exists, and "all" would be an unbounded client loop over every tenant, outside the curated single-call mutation model (pages.js:1672).

That means, plainly: the lane toggles on this screen are display controls. They show the policy; they do not write it from here.

4.4 Memory › Documents

Open this to see what corpora the daemon has read. Tenants expand to their documents and chunk counts, with an ingest form beneath (pages.js:1215).

ControlTypeDefaultStatus
Filter tenants / documents…searchemptyClient-side
Choose folder…button-STUBBED, a browser picker that would fill the prefix
source path / globtext, monoemptyOperator-only
doc prefixtext, monoemptyOperator-only
target tenantselectdefaultOperator-only
chunking profileselectdefault · 512 tokAlso markdown-aware, code-aware
extract entities (NER)toggleonOperator-only
Scan pathbutton-SHIPPED, live. POST /v1/workspace/scan
Queue ingestbutton-STUBBED

Queue ingest is gated for a stated reason: the only real route is a synchronous local-ingest that needs a documents[] payload, while this control models "queue a path for the agent to pick up". The shapes do not match and there is no path-to-documents bridge to ground it (pages.js:1670). Ingest from the CLI or MCP instead.

4.5 Memory › Review: contradictions and consolidation

Open this when two agents have written opposing facts and you need to pick a winner. Three cards (pages.js:476).

Review queue

Surfaced runs from the consolidation scheduler, over GET /v1/console/review/queue?limit=50. The card states the scheduler's state explicitly and distinguishes two empty cases, which is the whole value of the panel:

StateMessage
Scheduler on, store cleanscheduler is on and the store is currently clean, no contradiction or expiry proposals
Scheduler offenable CORECRUXD_CONSOLIDATION_SCHEDULER=1 to surface contradiction + expiry proposals; live contradictions are shown below in the meantime

Each surfaced run expands to its surfaced-at time, contradiction count, expiry-proposal count, then one row per contradiction (entity, key, the two polarities, the fact ids) and one per expiry proposal (reason, entity, key, confidence, fact id).

Live contradictions

A read-only live pass that runs regardless of the scheduler, so the screen is useful with the flag off. Each row: entity and key, the reason, the two polarities, the fact ids, and the clashing values.

Consolidation

The form that resolves one. Every field is operator-only.

FieldTypeDefault
entitytext, monoempty
keytext, monoempty
canonical valuetextarea, 3 rowsempty
target fact idstextarea, 3 rows, monoempty
protected fact idstextarea, 2 rows, monoempty
confidencetext, mono0.8
protect floortext, mono0.99
Consolidate factsdanger button-

Consolidate facts is SHIPPED and live, and it is destructive. It shows a confirmation naming the entity, the key and the exact count of target facts that will stop resolving before it fires (render.js:754):

Writes a canonical fact for <entity> · <key> and SUPERSEDES the N listed target fact(s); they stop resolving. Fact-store mutation. Proceed?

Facts above the protect floor are rejected by the daemon.

4.6 Memory › Lane weights (operator only)

Open this to change how retrieval ranks results. The whole page is operator-only; a customer sees a note explaining that forward-facing consoles hide operator deep machinery (pages.js:1414, render.js:2648).

Three cards (pages.js:704).

Scope

ControlTypeDefaultWhat it does
tenantselectempty (global)Global defaults, or a discovered tenant
custom tenanttext, monoemptyA tenant id the select does not list
enable RRF fusiontogglereflects the live valueWhether reciprocal-rank fusion is on for this scope
reasontextemptyAn operator note recorded with the change
Load lane weightsbutton-Reads the CoreCrux global or tenant boost overlay
Apply lane weightsbutton-SHIPPED, live, destructive

Presets

ControlDefaultWhat it does
presetselect, emptybaseline, lexical, dense, graph
Stage presetbuttonFills the weights form only. Nothing is written
Reset lane weightsdanger buttonSHIPPED, live, destructive

Weights

Ten non-negative multipliers, seeded from the live overlay when one loads (pages.js:138):

LaneDefault
BM25 lexical1
Dense / cosine1
Sparse1
HyDE1
Topology0
Vernacular0
Indexing0
Trait expansion0
Navtree0
Events0

Both writes confirm first, and both confirmations name their blast radius (render.js:760):

Writes FUSION_RRF_LANE_WEIGHTS to CoreCrux for <scope>, changes retrieval ranking for that scope. Proceed?

Clears the lane-weight overlay (global scope), retrieval reverts to CoreCrux defaults for every tenant that inherited it. Proceed?

The reset clears only the lane-weight overlay keys for the scope, not the whole overlay.

4.7 Memory › Global (Professional mode only)

Shared surfaces that outlive a session (pages.js:1065). One live card and three honest notes.

CardStatus
EngramsLive over GET /v1/engrams. Filterable; each engram expands to kind and summary
BenchSTUBBED, the ScoreCrux leaderboard is an external surface; this daemon has no bench endpoint
SitesSTUBBED, no hypernym-sites endpoint on this build
Fact storeA pointer card: the fact store's home is Memory › Facts

4.8 Trust › Receipts: the CROWN listing

Open this to answer "is there a record of that, and does it verify".

A live listing over GET /v1/receipts/list, newest first (render.js:12125).

ControlDefaultWhat it does
searchemptyClient-side across observation id, principal, kind, session, signer and receipt id. 200 ms debounce
kind chipsallUp to 12, from the daemon's own kind_counts. Single-select
Load older-Cursor pagination, 50 per page

A row carries the observation kind (colour-toned), the principal, a session short-id, the timestamp, the signature algorithm and signer short-id, the body hash, the chain sequence, and one of two badges:

BadgeMeans
CROWN body ✓The full body, signature and verification are dereferenceable here
envelope onlyThe body lives in the hosted-tier dataplane. This daemon holds the signed envelope and nothing more

Expanding a fetchable row pulls three endpoints and renders the daemon's verification verdict verbatim, including the raw JSON (render.js:12240). The verdict shows green only when signature_valid is true and error_code is OK.

The console never computes "valid" itself. It is a transport for the daemon's answer.

An envelope-only row explains itself in one paragraph: a CPU-only daemon holds no dataplane pool, so the body is not dereferenceable here.

The help card at the bottom is the honest boundary. It states that offline verification is corecruxctl inspect-receipt <id> or corecruxctl evidence <id> --keyring <path>, which check the Ed25519 signature without the daemon, and names the bundle export route.

4.9 Trust › Gates: the Article 14 approval queue

Open this when an agent has asked for permission. This is the canonical human go/no-go queue (render.js:12313).

Each pending gate is an always-open card showing the work id, a GATED badge, its age, the requested action and target state, the requesting passport, the action id and status, plus a link into the relation graph.

ControlPostureWhat it does
ApproveOperator onlyPOST /v1/work/gate/{actionId}/approve, attributed to your bound passport
RejectOperator onlyThe matching reject route

Both refuse without a bound passport, with the Article 14 message. On success the card reports the receipt short-id and the list reloads. In customer posture the buttons are replaced by a sentence saying approvals are operator-gated.

The empty state is the documentation

When the queue is clear, the page does not just say "none". It explains what a gate is, how one is created, and what resolving it produces (render.js:12367):

RowContent
producerWork-gate policy on a state transition
endpointGET /v1/work/gate/pending, and the approve/reject pair
requested_actionupdate_state, the only gated action today, plus a target state
resolutionA CROWN ad_ga_* receipt attributed to the approving passport

It then prints the blocker taxonomy, needs_info versus needs_approval, and runs a client-side join over /v1/work listing every blocked item carrying blocker_kind = needs_approval. Those are the items a gate would be owed for. That join is the most useful thing on the page when the queue is empty.

Withhold all

A separate control on the section-model variant of this page. SHIPPED, live, destructive, and it is not a batch route; there is none. It reads the pending list and loops a reject over every one (render.js:774). Its confirmation says so:

Rejects ALL currently-pending gated transitions (keeps every one from proceeding), each attributed to your passport. Bulk action across every pending gate. Proceed?

4.10 Trust › Pending mints (operator only)

Open this when an agent has asked for a passport. It is the same shape as Gates: an operator decision, attributed (pages.js:454).

The Bound approver panel

This is where you bind the passport every gated write is attributed to, and it is the first thing to do on a new browser (render.js:853).

ControlDefaultWhat it does
current approver-Shows the bound id, or No approver bound, bind one to accept/reject (Art.14)
Approver passport-A select populated from GET /v1/passports. If the daemon returns none, it degrades to a free-text input and says why
Binddisabled until the list loadsWrites the id to localStorage under crux-console-bound-passport
Cleardisabled when unboundRemoves it

The binding is browser-local, shared by mint decisions and work-gate approvals. It is a client identity selection, never a fabricated value.

A mint request card

FieldDefaultNotes
reason-Read-only, from the request
requested category-Read-only; not supplied when absent
Categorypre-filled from the request when it is one of personal \work \publicRequired. Accept refuses without it
Name (optional)emptyA display name
Accept-Mints; on success reports the minted category and refreshes
Reject-Rejects and refreshes

Both refuse without a bound passport: Bind a passport to accept, mint decisions must be attributed (Art. 14).

The card header shows the requester, the request's age in words, and the requesting passport.

When the feature is off

A 404 renders Feature disabled, passport mint requests are not enabled on this daemon. The flag is CORECRUXD_FEATURE_PASSPORT_MINT_REQUESTS, default off (config.rs:961).

4.11 Trust › Passport

Open this to see who the daemon thinks exists. A filterable list over GET /v1/passports (pages.js:253).

Each passport expands to id, name, owner, position, company, category, reputation tier, receipt count and notes, only the fields that are populated.

New passport

A + in the card header reveals the mint form below the list.

FieldTypeDefaultNotes
idtext, monoemptyLowercase, digits, - or _
categoryselectworkAlso personal, public
nametextemptyDisplay name
ownertextemptyWho owns or manages it
positiontextemptyRole or title
companytextemptyOrganisation
notestextarea, 2 rowsempty-
Create passportbutton-SHIPPED, live. POST /v1/passports. No confirmation, additive

Open this to see whether two identities have been proposed as the same principal. The rule is one sentence: inference proposes, consent disposes (render.js:12438).

A candidate never resolves on its own. The principal resolver ignores it until an operator confirms.

The help panel states the whole pipeline in grounded terms:

RowContent
producerPOST /v1/identity/candidates/propose, the only shipped producer
input · bindingsTwo distinct passports co-occurring in one tenant and project within the temporal window
input · observationsDistinct signing identities co-occurring in one session
confirmPOST …/{id}/confirm with the cross-signature proof, minting a resolving cross-signed link
rejectPOST …/{id}/reject: keeps the audit trail, never resolves
revokePOST /v1/identity/links/{id}/revoke, retires a confirmed link
flagCORECRUXD_IDENTITY_LINKS=1; all /v1/identity/* 404 when off

Controls

ControlPostureWhat it does
Seed candidatesOperator only; disabled with a stated reason otherwiseRuns both proposers. Reports created N (examined M) with a per-source breakdown (render.js:12468)
Confirm formOperator only, on a proposed candidateSix fields: local passport id (pre-filled personal-default), remote fingerprint (pre-filled from the observed subject), remote public key hex, created-at, sig local, sig remote
Confirm candidate-SHIPPED, live, destructive. Confirms only if the daemon verifies both signatures

Confirmation warns first:

Creates the resolving identity link for candidate <id> (local <a> ↔ remote <b>), only if both signatures verify server-side. Irreversible resolution. Proceed?

Reject is not a console control. The page says so and gives the exact route.

Candidate rows are colour-toned by status: confirmed ok, rejected critical, proposed trust. A 404 renders a warning naming the flag.

4.13 Trust › Mediation

Open this to find out whether a hosted engine is wired in, and what it would give you. The page branches on exactly three real states (render.js:12578).

ResponseCardSays
404CE postureEngine mediation is not configured. It names CORECRUXD_ENGINE_BASE_URL and its optional API key, lists the three proxied read routes, and states plainly that this daemon holds no engine state; it proxies, it does not run the engine
502Configured but unavailableThe base URL is set but the proxied read failed. It notes that the upstream body, headers and API key are never forwarded; this is the terse 502 posture, and tells you to check the URL, the key and engine health
200Mediated summarymediated, engine_reachable, engine_latency_ms, fetched_at_unix_ms, then the proxied summary verbatim

No dead controls are rendered. The unconfigured state is a card of text, not a form that would do nothing.

4.14 Failure states across these two destinations

What you seeWhat it is
Facts falls back with a warning bannerOlder daemon: no /v1/facts/list. You are seeing a recent window
A fact's value ends in with an N ch badgeTruncated in the list. Expand the row for the full text
Review says "scheduler off"CORECRUXD_CONSOLIDATION_SCHEDULER is off. Live contradictions below still work
Lane weights shows unavailable · <status>The CoreCrux overlay proxy did not answer
A gate approve says "Bind a passport first"No bound approver. Trust › Pending mints, Bound approver panel
Identity is a warning bannerCORECRUXD_IDENTITY_LINKS is off
Receipts shows only envelope only rowsExpected on a CPU-only daemon. Only local ad_ga_* gate-approval receipts are dereferenceable
Mediation shows the CE posture cardNo engine base URL configured. This is the default

Sources