Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
c06f1b1
test: freeze remediation audit baseline
wolverin0 Jul 11, 2026
d62262c
fix: stabilize candidate validation ordering
wolverin0 Jul 11, 2026
18a4104
feat(auth): add immutable MCP request context
wolverin0 Jul 11, 2026
cf0a1da
fix(mcp): enforce complete tool action registry
wolverin0 Jul 11, 2026
44d0955
fix(mcp): constrain tenant scope and principal propagation
wolverin0 Jul 11, 2026
304b718
fix(setup): declare local MCP trust mode
wolverin0 Jul 11, 2026
a37f517
fix(postgres): bind tenant context before connect
wolverin0 Jul 11, 2026
4896f16
fix(postgres): add tenant row security policies
wolverin0 Jul 11, 2026
6ccb818
fix(storage): make claim identities tenant-local
wolverin0 Jul 11, 2026
93a2d59
fix(postgres): tenantize the event ledger
wolverin0 Jul 11, 2026
f3d9edc
fix(postgres): enforce scoped runtime boundaries
wolverin0 Jul 11, 2026
64ce387
fix(postgres): deny unsupported team surfaces
wolverin0 Jul 11, 2026
eec27ce
fix(qdrant): quarantine unauthoritative retrieval
wolverin0 Jul 11, 2026
c0ff503
fix(security): gate canonical claim envelope
wolverin0 Jul 11, 2026
5755a95
fix(storage): enforce persisted envelope gateway
wolverin0 Jul 11, 2026
becbcca
chore(codex): route remediation through custom agents
wolverin0 Jul 11, 2026
d466cd2
fix(security): harden auxiliary persistence boundaries
wolverin0 Jul 11, 2026
d2d1a11
fix(security): gate external persistence writers
wolverin0 Jul 11, 2026
e537eaa
fix(security): enforce Atlas persistence envelopes
wolverin0 Jul 11, 2026
a3e3824
fix(security): harden bridge persistence transport
wolverin0 Jul 11, 2026
702b59d
fix(security): inventory legacy persistence safely
wolverin0 Jul 11, 2026
a858419
fix(deploy): require private authenticated services
wolverin0 Jul 12, 2026
b71e18f
fix(security): bind supply-chain evidence
wolverin0 Jul 12, 2026
9b3e16c
fix(security): enforce secure Qdrant transport
wolverin0 Jul 12, 2026
8d80abb
fix(integrity): close Phase 1 verification regressions
wolverin0 Jul 12, 2026
132e5d0
test(security): align Qdrant ML transport fixture
wolverin0 Jul 12, 2026
95c2b3a
docs(audit): record Phase 1 budget convergence
wolverin0 Jul 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .codex/agents/mm-docs-ledger.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name = "mm_docs_ledger"
description = "Evidence-focused documentation worker for remediation ledgers, audit deltas, runbooks, and external-action records."
model = "gpt-5.6-terra"
model_reasoning_effort = "medium"
sandbox_mode = "workspace-write"
nickname_candidates = ["Terra Ledger", "Terra Scribe", "Terra Delta"]

developer_instructions = """
Obey the repository AGENTS.md and edit only documentation/planning files explicitly owned in the parent prompt.
Never change production code or tests.
Treat command output and committed diffs as evidence; never mark a finding resolved from intent or an agent self-report.
Preserve finding IDs, rollback instructions, external blockers, and the distinction between implemented and verified.
Do not mutate live databases or external systems and do not commit unless the parent explicitly assigns a worktree and commit.
Return the exact files changed and unresolved evidence gaps.
"""
15 changes: 15 additions & 0 deletions .codex/agents/mm-explorer.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name = "mm_explorer"
description = "Fast read-only MemoryMaster code mapper for inventories, dependency tracing, and bounded evidence gathering."
model = "gpt-5.6-terra"
model_reasoning_effort = "low"
sandbox_mode = "read-only"
nickname_candidates = ["Terra Map", "Terra Trace", "Terra Scout"]

developer_instructions = """
Work read-only and obey the repository AGENTS.md plus the parent task.
Use MemoryMaster recall before architectural assumptions when its MCP transport is available.
Prefer GitNexus query/context and targeted rg/file reads over broad dumps.
Never propose or make architecture decisions; surface them to the parent with evidence.
Return concise findings with exact files, symbols, risk, and the smallest next action.
Do not edit files, create commits, mutate live databases, or run external-state-changing commands.
"""
16 changes: 16 additions & 0 deletions .codex/agents/mm-fast-worker.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name = "mm_fast_worker"
description = "Efficient implementation worker for isolated LOW/MEDIUM-risk fixes with explicit file ownership and acceptance tests."
model = "gpt-5.6-terra"
model_reasoning_effort = "medium"
sandbox_mode = "workspace-write"
nickname_candidates = ["Terra Patch", "Terra Build", "Terra Fix"]

developer_instructions = """
Obey the repository AGENTS.md and the exact owned-file boundary in the parent prompt.
Work only in the assigned isolated worktree and preserve all unrelated changes.
Before modifying an existing symbol, run GitNexus upstream impact analysis.
If risk is HIGH or CRITICAL, stop without editing and return the blast radius to the parent for rerouting.
For a security or integrity fix, first add and run an adversarial test that fails for the intended reason.
Make the smallest complete change, run focused tests and Ruff, and report exact evidence.
Never touch the live MemoryMaster database, push, publish, deploy, rotate credentials, or commit unless explicitly authorized.
"""
15 changes: 15 additions & 0 deletions .codex/agents/mm-security-reviewer.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name = "mm_security_reviewer"
description = "Read-only high-reasoning reviewer for security boundaries, integrity invariants, bypasses, and missing adversarial coverage."
model = "gpt-5.6-sol"
model_reasoning_effort = "high"
sandbox_mode = "read-only"
nickname_candidates = ["Boundary Review", "Red Review", "Security Gate"]

developer_instructions = """
Review read-only as an independent owner and obey the repository AGENTS.md.
Focus on exploitable bypasses, authorization/scope errors, raw or encoded secret persistence, partial failures, replay/idempotency, and missing tests.
Trace actual callers and sinks with GitNexus and targeted source reads.
Separate merge blockers from follow-ups; cite exact files/symbols and provide a concrete reproduction or invariant for every blocker.
Do not edit, stage, commit, mutate databases, or approve work merely because tests pass.
Return a concise blocker-first report to the parent.
"""
15 changes: 15 additions & 0 deletions .codex/agents/mm-test-runner.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name = "mm_test_runner"
description = "Fast verification worker for focused pytest, Ruff, scanners, collection checks, and evidence summaries."
model = "gpt-5.6-terra"
model_reasoning_effort = "low"
sandbox_mode = "workspace-write"
nickname_candidates = ["Terra Gate", "Terra Probe", "Terra Verify"]

developer_instructions = """
Obey the repository AGENTS.md and run only the verification scope assigned by the parent.
Do not edit source, tests, plans, configuration, or documentation.
Use temporary databases and fake/local services; never mutate the live MemoryMaster database.
Report the exact command, exit code, pass/skip/xfail counts, duration, and concise failure signatures.
Do not infer broad success from a focused test and do not rerun a failing command repeatedly without a new hypothesis.
Leave commits, staging, GitNexus reindexing, and full-suite decisions to the parent.
"""
16 changes: 16 additions & 0 deletions .codex/agents/mm-worker.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name = "mm_worker"
description = "General implementation worker for bounded MemoryMaster packages that need stronger multi-step coding and validation."
model = "gpt-5.6-sol"
model_reasoning_effort = "medium"
sandbox_mode = "workspace-write"
nickname_candidates = ["Core Worker", "Package Worker", "Integration Worker"]

developer_instructions = """
Obey the repository AGENTS.md and the exact owned-file/worktree boundary in the parent prompt.
Query MemoryMaster before architectural decisions when its MCP transport is available.
Run GitNexus upstream impact before editing every existing symbol and stop for parent warning before HIGH/CRITICAL work not already disclosed.
Add a witnessed failing adversarial test before security or integrity fixes.
Keep changes atomic, immutable, and narrowly scoped; use temporary databases and fake/local external services.
Run focused verification and Ruff, then return changed files, risks, commands, and unresolved blockers.
Never push, publish, deploy, mutate product data, or commit unless explicitly authorized.
"""
5 changes: 5 additions & 0 deletions .codex/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[agents]
max_threads = 4
max_depth = 1
job_max_runtime_seconds = 1800
interrupt_message = true
7 changes: 7 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Deny the entire build context, then allow only Dockerfile COPY inputs.
**
!Dockerfile
!pyproject.toml
!README.md
!memorymaster/
!memorymaster/**
58 changes: 56 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
# Copy to `.env` and edit as needed:
# cp .env.example .env
#
# `.env` is gitignored — never commit real secrets. All values below are
# optional; a fresh install works with zero env vars as long as you either
# `.env` is gitignored — never commit real secrets. Values are optional unless
# the selected deployment profile marks them required. A fresh local install
# works with zero env vars as long as you either
# (a) set GEMINI_API_KEY for the free cloud default, or (b) run Ollama
# locally. Everything else is tuning.
#
Expand All @@ -30,6 +31,49 @@ MEMORYMASTER_WORKSPACE=.
# Default: unset
# MEMORYMASTER_CONFIG_FILE=config.json

# ---------------------------------------------------------------------------
# Deployment authorization
# ---------------------------------------------------------------------------

# MCP authorization is mandatory. local-trusted is for one private stdio
# process controlled by one OS user and uses SQLite only. PostgreSQL application
# runtime is team-only; do not point a local-trusted process at PostgreSQL.
# Values: local-trusted | team
MEMORYMASTER_MCP_AUTH_MODE=local-trusted

# Team mode requires every value below. The database target must be the
# non-owner application DSN, never the migrator DSN. Scopes are an explicit,
# comma-separated allowlist; wildcards are rejected.
# MEMORYMASTER_MCP_PRINCIPAL=agent-id
# MEMORYMASTER_ROLE_AGENT_ID=writer
# MEMORYMASTER_MCP_TENANT_ID=tenant-id
# MEMORYMASTER_MCP_WORKSPACE=/absolute/path/to/workspace
# MEMORYMASTER_MCP_ALLOWED_SCOPES=project:example,global
# MEMORYMASTER_MCP_DB=postgresql://app-role:password@host/database

# Reserved sensitive-read grant. Team mode currently rejects enabled values
# because v0011 intentionally exposes only public or principal-owned private
# rows; keep this at 0 until database policy support is implemented.
# Values: 0 (team mode)
# MEMORYMASTER_MCP_ALLOW_SENSITIVE=0

# Disposable PostgreSQL RLS integration test only. The admin DSN must use a
# dedicated SUPERUSER or BYPASSRLS schema owner; the app DSN must use a distinct
# restricted role. Tests refuse known live DSN variables and require the
# explicit disposable opt-in. Never set these to a product database.
# MEMORYMASTER_TEST_POSTGRES_DSN=postgresql://migrator:password@host/test_database
# MEMORYMASTER_TEST_POSTGRES_APP_DSN=postgresql://app-role:password@host/test_database
# MEMORYMASTER_TEST_POSTGRES_RLS_DISPOSABLE=1

# Required only when rendering docker-compose.postgres.yml. Use a generated
# secret and rotate any environment that used the retired fixed credential.
# MEMORYMASTER_POSTGRES_PASSWORD=

# Required only when rendering docker-compose.yml. Supply immutable image
# references verified for your platform; tags and unqualified names are unsafe.
# QDRANT_IMAGE_DIGEST=sha256:<64-hex-digest>
# OLLAMA_IMAGE_DIGEST=sha256:<64-hex-digest>

# ---------------------------------------------------------------------------
# LLM provider (auto-ingest Stop hook + steward + entity extraction)
# ---------------------------------------------------------------------------
Expand Down Expand Up @@ -217,6 +261,16 @@ OLLAMA_URL=http://localhost:11434
# Default: http://localhost:6333 (only honoured when explicitly set)
QDRANT_URL=http://localhost:6333

# Required by the hardened Compose/Helm Qdrant profile. Generate and provision
# this out of band; never commit the value.
# QDRANT_API_KEY=
# QDRANT_TLS_CERT=
# QDRANT_TLS_KEY=
# QDRANT_CA_CERT=

# Optional path to a trusted CA certificate for a TLS-enabled Qdrant endpoint.
# QDRANT_CA_CERT=

# ---------------------------------------------------------------------------
# Lifecycle tuning (volatility: low,medium,high triples)
# ---------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions .mcp.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"env": {
"MEMORYMASTER_DEFAULT_DB": "/path/to/memorymaster.db",
"MEMORYMASTER_WORKSPACE": "/path/to/your/project",
"MEMORYMASTER_MCP_AUTH_MODE": "local-trusted",
"QDRANT_URL": "http://localhost:6333",
"OLLAMA_URL": "http://localhost:11434"
}
Expand Down
113 changes: 113 additions & 0 deletions .planning/OPERATING-ENVELOPE-2026-07-11.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# MemoryMaster Operating Envelope

**Status:** Frozen Phase 0 baseline
**Measured:** 2026-07-11 UTC
**Database access:** Strictly read-only
**Live-data mutations authorized:** None

## Snapshot

| Metric | Value |
|---|---:|
| Claims | 108,217 |
| Events | 1,033,626 |
| Verbatim rows | 1,067,072 |
| Distinct verbatim session IDs | 184,889 |
| Candidate claims | 21,828 |
| Confirmed claims | 18,720 |
| Archived claims | 48,726 |
| Stale claims | 14,656 |
| Conflicted claims | 2,087 |
| Superseded claims | 2,200 |
| SQLite DB | 5.123 GiB |
| WAL | 7.705 MiB |
| Drive used | 85.82% |
| Drive free | 66.06 GiB |

## Candidate age

Snapshot cohort: 21,822 candidates at 2026-07-11T01:49:58Z. Six arrived immediately afterward; the program cohort is frozen at 21,828.

| Age | Count |
|---|---:|
| <1 day | 1,012 |
| 1-3 days | 1,558 |
| 3-7 days | 214 |
| 7-14 days | 127 |
| 14-30 days | 385 |
| 30-60 days | 2,393 |
| 60-90 days | 16,132 |
| >=90 days | 1 |

- P50: 70.737 days
- P90: 74.716 days
- P95: 75.390 days
- P99: 75.679 days
- Maximum: 111.091 days

The target `candidate_age_p95 <= 7 days` currently fails.

## Capacity window

Window: 14 completed UTC days, 2026-06-27 through 2026-07-10.

- Reconstructed candidate inflow: 10,000 / 714.29 per day.
- Candidate dispositions: 12,050 / 860.71 per day.
- Safe 80% intake ceiling: 688 per day.
- Observed intake is 103.7% of the safe ceiling: gate fails.
- Require at least one successful steward cycle per completed UTC day.
- Pass requires a seven-day rolling inflow <=688/day for seven consecutive completed days.

The inflow figure is reconstructed from current candidates plus transition events. It is not authoritative because 2,455 recent `llm-stop-hook` candidates have no creation event.

## Retention and growth gates

Verbatim retention stops at whichever limit is reached first:

1. 30 days of age;
2. 512 MiB raw content;
3. 75,000 most-recent distinct session IDs.

Warn at 80% of any limit. Current 30-day demand is 357.96 MiB and 74,061 distinct session IDs.

Until a 30-day physical-size series exists:

- Warn when seven-day rolling physical DB growth exceeds 64 MiB/day.
- Critical when seven-day rolling growth exceeds 128 MiB/day or any single day exceeds 256 MiB.
- Record DB bytes, WAL bytes, and free-disk bytes daily; replace provisional gates after 30 complete days.

Disk watermarks:

- Warning: >=75% used or <75 GiB free.
- Critical: >=85% used or <50 GiB free.
- Capture hard stop: >=92% used or <10 GiB free.

The current drive is percentage-critical and must be tracked as an external/operator action; this plan does not authorize deletion or compaction of live data.

## Backlog completion

- Frozen cohort: 21,828 candidates at 2026-07-11.
- Target review date: 2026-09-30.
- Completion requires original-cohort `still_reviewable = 0`.
- `confirmed + archived_with_reason + rejected_with_reason = 21,828`.
- Every outcome must have an append-only event.
- Global current candidates must have P95 age <=7 days.
- Global candidate count must be <=4,816, equivalent to seven days at the 688/day safe ceiling.
- Do not pre-allocate confirmed/archive/reject counts; truth review determines the split.

## Instrumentation required

- Emit one authoritative claim-created/entered-candidate event per claim.
- Add steward `run_id`, start/end timestamps, inspected/disposed counts, outcomes, reasons, duration, budget, and failures.
- Add a canonical disposition reason; `rejected` is not a current lifecycle status.
- Record daily DB/WAL/free-disk bytes and backlog snapshots.
- Add canonical session lifecycle and byte counters.

## Measurement queries

- Status counts: `SELECT status, COUNT(*) FROM claims GROUP BY status`.
- Candidate ages: `julianday(snapshot_utc) - julianday(created_at)` for current candidates.
- Reconstructed inflow: claims created in the window whose current status is candidate or that have an event entering/leaving candidate.
- Dispositions: unique claims with validator transition events leaving candidate during the window.
- Verbatim volume: row count, distinct `session_id`, and `SUM(LENGTH(content))` grouped by timestamp windows.
- File sizes and free disk were measured through read-only filesystem metadata.
49 changes: 49 additions & 0 deletions .planning/PHASE0-RED-TEST-MATRIX.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Phase 0 Adversarial Red-Test Matrix

All tests use temporary databases, isolated environment variables, fake providers, and local/fake services unless explicitly marked external. Unsafe current behavior should be committed as `xfail(strict=True)` tests and demonstrated with `--runxfail`; fixes remove the marker.

## Shared fixtures

- `isolated_mm_env`: clears inherited DB/Qdrant/provider/auth settings and redirects state/spool/snapshots to `tmp_path`.
- `policy_db`: claims in every lifecycle state across tenants/projects.
- `synthetic_secret`: deterministic non-credential test token.
- `durable_payload_scan`: scans all durable string/JSON fields for a fixture.
- `db_fingerprint`: proves denied operations cause no domain mutation.
- `FakeQdrant`: returns caller-controlled IDs/payloads without network/model dependencies.
- `rendered_hook`: renders hook templates into isolated state directories.

## Matrix

| Finding | Test file | Required red tests | External dependency |
|---|---|---|---|
| MM-SEC-01 | `tests/test_mcp_authorization_boundary.py` | reader cannot ingest with spoofed source; unknown team principal fails closed; scope allowlist cannot expand context; list/query/pin/redact cannot cross project/tenant; every MCP tool declares an action | Real Postgres/RLS subset requires DSN |
| MM-SEC-02 | `tests/test_qdrant_authoritative_filtering.py`; `tests/test_qdrant_retrieval_quarantine.py`; `tests/test_verbatim_qdrant_quarantine.py` | never return orphan payload; filter archived/candidate/stale/conflicted/wrong-scope/wrong-tenant/sensitive/private; payload cannot override DB; safe lexical/FTS fallback; direct adapters and disabled CLI fail before model/network/backend access; equal-count/different-ID reconcile | Real authenticated/TLS Qdrant final parity (`BLOCKED-EXTERNAL`) |
| MM-SEC-03 | `tests/test_persisted_envelope_sensitivity.py` | plain and encoded secret matrix over every claim/citation/provenance field; legacy sensitive metadata hidden from list/query/export/Qdrant | None |
| MM-SEC-04 | `tests/test_write_gateway_paths.py` | compact-summary, steward existing-row update, verbatim/spool/Atlas/miner/import paths reject secret fixture | None |
| MM-ARCH-01 | `tests/test_entity_schema_composition.py` | normal init then graph schema; registry-first extract/stats/related; read tools issue no DDL | None |
| MM-ARCH-02 | `tests/test_retrieval_surface_parity.py` | conversational vs keyword IDs across MCP/context/hook/CLI; trusted defaults exclude provisional statuses | ML parity may require model |
| MM-REL-02 | `tests/test_mcp_read_only_contract.py` | query succeeds under held write lock; unchanged access count; one aggregated spool signal; one retrieval per detail level | None |
| MM-OPS-01/02/04 | `tests/test_deployment_contracts.py` | required secret interpolation; private backend ports; matching entrypoint/health; Helm probes; pinned images | Built-runtime/Kubernetes final checks |
| MM-UX-01 | `tests/test_setup_profile_verification.py` | requested component failure returns nonzero/PARTIAL; provider/MCP/hook/vector checks are independently reported | Docker/provider optional cases |
| MM-COST-01/02 | `tests/test_stop_hook_capture_policy.py` | default quiet/nonblocking; only appended lines processed; persisted budget survives restart; finite defaults | None |
| MM-DEMO-01 | `tests/test_atlas_mock_evidence_guard.py` | missing provider fails without evidence; explicit mock requires dev gate; mock evidence cannot feed claims/actions | None |
| MM-LIFE-01 | `tests/test_scheduled_archive_lifecycle.py` | scheduled archive increments version, timestamps, event, cache/vector/outbox; template contains no direct status SQL | None |

## Existing tests requiring semantic updates

- Unknown/None principal default-writer tests become explicit local-profile behavior only.
- Tenantless visibility/pin tests become explicit local-profile behavior only.
- Unlimited budget behavior becomes an explicitly unsafe legacy/profile test, not the default.
- Atlas mock-default tests require a dev gate.
- Direct maximum-capture Stop-hook tests require an explicit flag.
- Count-only Qdrant reconciliation tests are replaced by set/content convergence.

## External-only gates

- Postgres RLS and application-role enforcement.
- Built container readiness, network exposure, and MCP handshake.
- Kubernetes scheduling/readiness/network policy.
- Real Qdrant auth/TLS/reconciliation.
- ML/hybrid parity when required models are unavailable.

These become `BLOCKED-EXTERNAL` with owner/evidence requirements when unavailable; static/fake-backed tests remain mandatory in normal CI.
Loading
Loading