# MemoryOps Console

The same-origin console at `/console` is the operational surface for a MemPlumb Runtime. It is not a demo, a separate control plane, or a replacement for the CLI. Every mutation calls the authenticated Runtime API and every displayed count comes from a Store read model.

## Open the local console

On Windows, double-click the portable `memplumb.exe` or run it without arguments. The launcher starts or reuses a hidden SQLite Runtime on the first free loopback port beginning at `6066`, opens the console, and completes the local credential handoff automatically. Docker is not required.

From a terminal, the same lifecycle is explicit:

```powershell
memplumb console
memplumb console --no-open
memplumb console-stop
```

`console --no-open` is useful when the Runtime should start without changing the current browser. It returns a single-use authorized URL and its expiry; open it within 60 seconds, or rerun the command to mint a fresh URL. If an automatic browser launch fails, the normal `console` command returns the same kind of manual fallback. `console-stop` stops only the launcher-owned Runtime for the selected database and Workspace. A different process already using `6066` is never terminated; the launcher uses `6067` or the next available port instead.

The launch URL carries a separate 60-second, single-use bootstrap token in its fragment, not the Runtime credential. Before application state is initialized, the console validates the fragment and replaces the current history entry with a clean `/console` URL. It then exchanges the token once over same-origin HTTP and writes the returned credential to `sessionStorage`. It does not persist the credential in local storage or expose it in browser-launch arguments. A later launch can reuse the local Runtime through the sensitive launcher state held under `%USERPROFILE%\.memplumb\run\`; see [Authentication and tenant isolation](./security.md) for that trust boundary.

English and Chinese are the same product surface. Language switching changes labels and help text without changing the active Runtime, authenticated identity, navigation, or in-progress Replay Lab drafts.

## Users and jobs

- AI application engineers ingest events, inspect current Memory, and verify the exact Context supplied to an agent.
- Agent-platform and reliability engineers find failed Events or degraded dependencies and inspect durable pipeline evidence.
- Reviewers, resolvers, and auditors operate the blind quality loop without receiving capabilities from an unrelated admin role.
- Evaluation and release engineers curate governed production failures plus their captured Memory state into Memory Cases and compare candidate-generation behavior in durable Replay Runs.
- Security and compliance operators inspect provenance, releases, controls, and lifecycle evidence without relying on sampled traces.

## Information architecture

The primary navigation is deliberately limited to five stable product domains:

1. **Overview** shows authenticated identity, final action capabilities, exact Workspace aggregates, Runtime readiness, active Policy/Release identity, recent privacy-bounded Event summaries, a first-success path, and capability-aware operational tasks.
2. **Memory** contains active Memories and the Context Inspector. The Inspector creates a durable Context Run; it is not a dry-run playground.
3. **Pipeline** contains cursor-stable Event and Context Run lists. Selecting an item fetches its protected detail and evidence only when authorized.
4. **Quality** contains My Work, Queue, Disputes, Write Adjudications, Audit, and Review Policy Settings. These remain separate workflows under one product domain rather than six top-level products.
5. **Evaluation** contains Replay Lab, Runs, and Cohort Plans. Replay Lab switches among Retrieval Replay, Write Counterfactual, and Write Quality; selects privacy-bounded homogeneous Cases; edits the matching Context or Memory Policy and gate thresholds; and starts durable replays. Runs shows state, gate, scope-appropriate metrics/findings, coverage, and per-Case deltas. Cohort Plans lets a release operator atomically freeze the complete authenticated Write Quality population, resume durable shards, and inspect release-evidence freshness without seeing private Case membership.

On mobile, the same five domains remain in the same order with horizontal navigation when needed. Secondary workflows are contained within their domain, tables become labeled records, and object details use the full viewport. English and Chinese use one information architecture and preserve in-progress Replay Lab policy/threshold drafts when the language changes.

## First durable success

An identity with `memory:write` can complete the Memory and Context portion of a production-shaped path without leaving the console. A bound evaluator identity with `evaluation:write` can then attach the business result to the same Context Run:

```text
Ingest Event -> inspect extraction/policy/write stages
             -> inspect accepted Memory revisions
             -> build a Context Run for the Actor
             -> inspect selected and excluded retrieval evidence
             -> run the caller-owned Agent
             -> record Outcome (task success, safety pass, score, rubric)
```

The console generates an idempotency key for Event ingestion. The ingest drawer offers natural-language and structured-Facts modes; an empty Workspace starts in structured-Facts mode so the first Memory result is explicit. Structured Facts accept one or more `kind`, `key`, `value`, `confidence`, sensitivity, optional `valid_from`, and optional `expires_at` rows, omit `text` from the request, and are the deterministic path when the caller already knows the memory identity and governance metadata. Credential sensitivity is rejected by the default Memory Policy.

After ingestion, the console opens the durable Event Trace when the identity has read access and shows a bilingual result summary: whether the Event was recorded, accepted Memory count, rejected candidate count, unchanged candidate count, and whether no Memory was created or updated. The summary retains only counts plus the Actor and Event IDs needed for direct actions; it does not retain candidate or Memory values in browser storage. Actions are capability-aware: readers can inspect the Event, Context, and current Memory, while writers can switch a no-candidate result to structured Facts. Event persistence alone is never presented as Memory success.

The Context Inspector caps the candidate limit at the API contract maximum of `50`. A zero-selection Context Run distinguishes no candidates, no eligible candidates, and eligible candidates that were not selected by the current query or budget. It is durable and auditable, but it does not complete the first Memory-use loop until at least one Memory is selected. The inspector keeps capability-aware recovery actions for Actor Memory, structured-Fact ingestion, and persisted retrieval evidence. If the detail request fails after Context creation, the created Context ID and result remain visible with a retry action instead of being discarded; the Outcome summary and write form remain unavailable until that protected detail can be read, so an unread state is never presented as "no Outcome".

The first-success path on Overview makes the next durable step explicit: **Event -> Context -> Outcome**. It reaches complete only when an authenticated Outcome reports both task success and safety pass for a Context Run that selected at least one Memory; an unverified, failed, unsafe, or zero-selection result cannot complete the path. Outcome can only be written by a principal with `evaluation:write` and a bound evaluator; local or managed admin credentials cannot impersonate an evaluator. The write uses an `Idempotency-Key` that stays stable when the same form is retried after a network failure. After a successful write, the Console reloads the protected Context projection and displays only the allowlisted evidence fields: Outcome ID, task success, safety pass, score, rubric version, evaluator authentication, and creation time. It deliberately does not display raw `evidence`, `tags`, `dimensions`, or evaluator identity from the browser summary.

Event lists exclude text and metadata; Context Run lists exclude assembled Context, Memory IDs, scores, and ranking. Protected content is fetched only for an explicitly selected object.

## Capability contract

`GET /v1/session` is the source of truth for UI actions. It returns final booleans such as `memory_write`, `quality_work`, `quality_resolve`, `quality_audit`, `evaluation_read`, `evaluation_write`, `evaluation_execute`, `evaluation_export`, and `operations_overview`; the browser does not infer authority from raw scopes. In particular, local and managed admin identities can configure and audit quality work but cannot impersonate an evaluator or resolver. `evaluation_write` enables the Write Adjudication form only for an evaluator-bound principal, `evaluation_execute` enables Case curation and Replay Run creation, and `evaluation_export` separately protects full Case content.

## Write Adjudication workbench

Quality -> Write Adjudications turns an exact production Write Decision into reviewer evidence. An evaluator enters the Decision ID, rubric, expected action, confidence, optional reason codes, safety flag, segment/tags, note, and bounded JSON evidence. The browser does not accept evaluator identity fields; the Runtime derives them from the managed `evaluation:write` key and requires an idempotency key for the append-only mutation.

The list requires `evaluation:read` and exposes only a privacy-bounded summary. Filters cover Decision, Actor, rubric, evaluator, authentication, and latest revision. Full notes and evidence are fetched only when a selected row is opened by an identity with `review:audit`. When `latest_only=true` and `authenticated_only=true`, the Store first determines the actual latest evaluator revision and then applies authentication; an older trusted revision can never reappear after a newer unverified revision.

An authenticated selected judgment shows **Save as Quality Case** only when the session also has `evaluation_execute`. The browser submits only `source_type=write_adjudication` and the Adjudication ID. It cannot upload an Oracle, evaluator, Observation, or source hash; the Runtime re-resolves latest-before-auth eligibility and conflicts.

`GET /v1/operations/overview` is admin-only and returns exact aggregate counts without embedding recent rows or sensitive content. `GET /v1/events` and `GET /v1/context-runs` use independent opaque keyset cursors and bounded projections. The current Memory list API remains bounded rather than cursor-paged, so the console visibly reports the 200-row boundary and requires Actor/query narrowing instead of presenting a partial list as complete.

## Memory Case and Replay workflow

On a Context Run detail, **Save as Memory Case** appears only when the Runtime has an accepted authenticated canonical Retrieval Adjudication and the identity has `evaluation_execute`. Otherwise the console directs the operator back to Quality; it does not synthesize trusted evidence in the browser.

On an Event detail, **Save as Write Case** appears beside each Write Decision for an identity with `evaluation_execute`. This creates `memory-case-v5` from the server-held exact Write Decision Observation; the browser cannot upload or alter the candidate, current Memory, observed policy, or Decision.

Replay Lab loads `GET /v1/replay-lab/configuration`, paged Case summaries, and recent Run summaries. The operator selects Cases, edits a complete candidate Context Policy JSON document, sets retrieval thresholds, and creates a Run with a client idempotency key. Case queries, Memory values, State Snapshots, and content fingerprints remain server-side. The console then opens Runs, polls a selected non-terminal Run, and presents aggregate baseline/candidate metrics, gate checks, regression names, execution coverage, and ordered Case classifications. Per-Case detail shows local aliases, candidate-pool additions/removals, ranks, score components, positive misses, hard-negative hits, unjudged selections, Oracle coverage, and budget change. Full Case content is fetched only with `evaluation_export`.

Interrupted queued or expired-lease work can be resumed through the Runtime API; cancellation skips pending Case results. The default `memory_state_retrieval.v1` coverage badge is a product boundary, not decorative metadata: candidate-pool generation, the portable logical index contract, scoring, filters, budget, and semantic similarity are covered. `physical_candidate_index=false` says that the historical ANN traversal is provenance rather than replayed execution; extraction and write policy are also not covered. Older Case v1 evidence remains visibly labeled `frozen_retrieval.v1`.

In **Write Counterfactual** mode, Replay Lab filters to `memory_write_counterfactual.v1`, edits a candidate Memory Policy, and exposes only write thresholds. The captured observed policy is the baseline unless a caller supplies an explicit baseline through the API or CLI. Per-Case results display baseline/candidate actions, `unchanged|changed|risk_increased|risk_reduced`, safety signals, aggregate totals, and gate checks. The UI does not display retrieval precision/recall for this scope because it has no production quality Oracle. See [Memory Write Counterfactual](./memory-write-counterfactual.md).

In **Write Quality** mode, Replay Lab filters to authenticated `memory_write_quality.v1` Case v6 evidence, keeps a separate 13-threshold draft, and edits the same Memory Policy family. The report shows exact-action and accept/reject accuracy, action confusion, 15 aggregate totals, `improved|regressed|unchanged|changed` classifications, quality findings, safety-critical errors, and per-Case baseline/candidate correctness. It does not reuse the Counterfactual Risks panel or retrieval metrics. Full Case detail shows the bounded Oracle only under `evaluation_export`; reviewer notes/evidence remain behind `review:audit`. Existing v4 evidence remains available through the same quality scope. See [Production Memory Write Quality](./memory-write-quality.md).

The default `maximum_unjudged_selected=0` control is exposed with the other thresholds. It blocks a candidate policy that selects a captured-state Memory for which the governed Oracle has no judgment. The console reports this as evidence coverage, not as an automatic negative label.

### Cohort Plan freshness

In **Cohort Plans**, opening a Plan loads its privacy-safe detail and automatically asks the Runtime to compare the frozen population with the current eligible population using the default seven-day evidence window. The freshness panel distinguishes `fresh`, `stale`, `blocked`, and `expired`; shows evidence age, maximum age, remaining validity, validity deadline, and check time; summarizes added, removed, changed, and unchanged counts; and shows the population-current and maximum-age gates separately. A manual refresh repeats the Store check. While an unfinished Plan is being polled every 2.5 seconds for progress, the console deliberately does not repeat the population scan on every tick.

The browser applies a second explicit allowlist before retaining the freshness response. It stores only counts, hashes, timestamps, policy/gate state, and bounded failure codes, never Case IDs or private manifests. `fresh` means the Plan is eligible to be used as release evidence at that check time; it does not create or sign a release in the browser. Release Artifact v12 repeats the check in the trusted Store path, and signing, deployment startup, and long-running canary routing enforce the bound validity deadline independently.

This is the compounding product asset: reviewed failures, temporal claims, policy decisions, evaluator calibration, migration baselines, and verifiable evidence bundles become more valuable with production use and materially harder to replace than a generic trace dashboard.

See [Memory Case and Replay Lab](./memory-case-replay.md) for the durable contracts and privacy boundary.
