Native OpenAI Codex plugin for durable Substrate memory: hosted sign-in, automatic canonical recall, lifecycle capture, explicit wiki tools, and optional prior-history import.
Requires Codex CLI 0.147.0+ and Python 3.11+ available as python3 (python3.exe on Windows). Codex 0.133.0 does not provide SessionEnd.
The release marketplace is the normal installation surface once a release is published. For a source checkout:
codex plugin marketplace add Substrate-memory/codex-substrate-memory --ref v0.2.0
codex plugin add codex-substrate-memory@substrate-memoryStart a new Codex session. Open /hooks, review the exact six packaged commands, and trust them. Installation never bypasses Codex hook trust.
No TOML editing, pasted API key, or global notify replacement is required. Codex gives hooks an owner-private data root; the bundled MCP launcher resolves the same installed per-plugin root without exposing it to the model or user configuration.
Ask Codex to use substrate_setup with action: begin. Open the returned complete authorization URL and approve the one-time code yourself. substrate_setup with action: poll completes the connection. The hosted credential is held in the OS secret service when available, otherwise an owner-private fail-closed file—not TOML, argv, tool output, or logs.
Prior-history import is a separate decision. substrate_history_consent can decline or return instructions, but model/MCP calls cannot approve. Approval requires running the plugin's history-consent command in a direct interactive terminal and typing the displayed phrase. Declining does not disable future capture or recall. Approval imports interactive root Codex/VS Code threads through documented codex app-server read APIs; it does not scrape rollout JSONL, hidden reasoning, or subagent threads.
| Tool | Purpose |
|---|---|
substrate_search |
Search canonical entity-quality-v2 memory cards. |
substrate_wiki_search |
Search all permitted published wiki pages. |
substrate_read |
Read one published wiki page. |
substrate_query |
Ask a cited question over published memory. |
substrate_ingest |
Submit source text for asynchronous ingestion. |
substrate_job_status |
Check an asynchronous ingestion job. |
substrate_remember |
Durably admit a fact/decision and report queued, delivered, or rejected truthfully. |
substrate_sync |
Request a queue drain and report actual delivery state. |
substrate_status |
Show content-free connection, queue, and import status. |
substrate_setup |
Begin, poll, inspect, or repair hosted sign-in. |
substrate_history_consent |
Decline history import or request direct human-approval instructions. |
Packaged adapters consume documented SessionStart, UserPromptSubmit, PostToolUse, Stop, PreCompact, and SessionEnd JSON. They never read transcript_path.
UserPromptSubmit: durably admits the visible user prompt, then may add bounded cited recall.PostToolUse: durably admits bounded visible tool input/results.Stop: durably admits onlylast_assistant_message.PreCompact/SessionEnd: content-free boundaries only.SessionStart: lineage/start boundary only.
Hooks perform no delivery retries. A long-lived MCP worker drains the private SQLite WAL queue with transactional multiprocess claims, deterministic idempotency keys, and bounded retry backoff. Capture failure never blocks ordinary Codex use.
Automatic recall fails closed unless the server advertises stream-v2, entity-wiki-v1, and entity-quality-v2 with canonical redirects/cards. Returned items must be canonical immutable entity paths and quality version 2. Explicit wiki search remains a separate surface.
- Fixed origin:
https://app.trysubstrate.co; redirects are rejected. - Credentials and configured secrets are redacted before persistence.
- State, queue, credentials, and import checkpoints reject symlinks and require private storage.
- Hook state/checkpoints store only identifiers, counters, digests, acknowledgements, and content-free errors.
- History discovery is bounded to 10,000 interactive root threads; each thread is bounded to 1,000 visible messages / 2,000,000 serialized characters.
- Redaction cannot prove arbitrary sensitive prose absent. Visible content is sent to the trusted hosted Substrate service after redaction.
substrate-codex configure, the global notify adapter, and sweep-rollouts remain non-default migration aids. configure --write is retired and never changes config.toml. Native packaging never replaces an existing global notify hook.
python -m pip install -e '.[dev]'
python -m ruff check .
python -m pytest -q
python -m compileall -q src scripts
python scripts/verify_public_plugin_candidate.py --root .
CODEX_PLUGIN_SOURCE_COMMIT="$(git rev-parse HEAD)" python scripts/build_plugin.py --checkSee docs/architecture.md, docs/operation.md, docs/threat-model.md, and docs/releasing.md. Publication/deployment and live-production certification are separate actions; this repository does not claim permission enforcement or connected-system actions.
MIT © 2026 Sightline Technologies Inc.