Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 5 additions & 1 deletion AGENT_USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,11 @@ description: Local-first persistent memory for this project. Use it whenever
- Treat any `[mem:*]` block already in your context as authoritative.

## Tools (MCP server: graphctx)
- remember(text, kind?, scope?, ttl?)
- remember(text, kind?, subject?, predicate?, session_id?, base_seen_fact_id?)
- pass `base_seen_fact_id` (from `recall`/`why`) when changing an existing
value: with it the old fact is superseded cleanly; without it a
contradicting write at equal precedence is marked disputed and surfaced
for `resolve_conflict` (never silent last-writer-wins)
- recall(query, budget_tokens?)
- inject_context(event, session_id?, user_prompt?)
- checkpoint_session(session_id?)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ npx tsx src/cli.ts bench

Expected current state:

- `npx vitest run`: 297 tests pass.
- `npx vitest run`: 315 tests pass.
- `npm run pack:smoke`: packed tarball installs, runs the demo, and serves
MCP from a clean temp app.
- `npx tsx src/cli.ts eval all`: 19 gate suites pass.
Expand Down
8 changes: 4 additions & 4 deletions docs/STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
| retrieve/retriever | §13 | ✅ | vector ∪ BM25 + entity + scope; commit-anchored filter |
| retrieve/vectors | §13 | ✅ | sqlite-vec hybrid; offline local embedder; BM25 fallback (I9) |
| retrieve/signals + rank | §13 | ✅ | scope/entity scorers; fusion w/ confidence + recency (S5) |
| resolve/precedence + conflicts | §14 | ✅ | full precedence (prose < user profile, D14); resolveConflicts + reconcileWrite optimistic concurrency (never silent LWW) |
| resolve/precedence + conflicts | §14 | ✅ | full precedence (prose < user profile, D14); resolveConflicts + reconcileWrite optimistic concurrency wired into the live learn() path (never silent LWW: equal-precedence user contradictions dispute unless the writer passed base_seen_fact_id) |
| inject/gate | §15 | ✅ | centroid drift + entity-change + event-class; selective PreToolUse |
| inject/ledger | §15 | ✅ | DB-backed cross-process/cross-channel anti-repetition |
| inject/budget | §15 | ✅ | utility ranking + redundancy penalty + must-include bonuses + caps |
Expand Down Expand Up @@ -76,9 +76,9 @@
|---|---|---|
| `hook <event>` p95 | < 150ms | 15.51ms ✅ |

_Last updated: Windows is now a first-class dev platform (homedir-derived user-global paths, named-pipe daemon sockets, shim-free dev-tool spawns in eval suites, forward-slash generated-marker facts, windows-latest CI job), Private-key scanning now covers DSA, encrypted PEM, and PGP private key block headers, MCP `resolve_conflict` now evaluates user, workspace, and current-session facts together, `graphctx resolve` now refuses non-open-loop facts instead of silently superseding durable memory, Storage migration 0006 adds a composite invalidation conflict lookup index, Session-scoped invalidation now keeps identical open loops isolated across sessions while deduping repeats within a session, Demo seed memory now uses Runtime.rememberFact, open-loop session memory now carries current git anchors, CLI `tui --tab` now fails fast on invalid tabs, CLI/MCP fact-kind validation uses a shared `FACT_KINDS` domain enum, TUI promotion uses Runtime/Probation gates instead of direct activation, Runtime/TUI/CLI/MCP explicit remember paths share safe git-anchored invalidating writes, Runtime/TUI/MCP forget paths share git-anchored temporal closeout, MCP forget stamps git closeout anchors, retrieval candidates are scope-filtered before semantic reranking, retrieval candidates receive final workspace/session scope filtering, superseded facts close temporal validity with `t_expired` and commit anchors, retrieval recency ranking uses the runtime clock, ranking/conflict tests use deterministic fact IDs and clocks, vector embedding cache uses the runtime clock, outcome telemetry uses an injectable clock, injection anti-repetition ledger uses the runtime clock, promotion verification timestamps use the runtime clock, promotion gates rescan secret-shaped fact identity, why renders invalidating commit closeout anchors, revert revalidation respects branch representation, revert revalidation skips bad historical anchors, atomic temporal lifecycle closeout anchors, TUI read model redacts secret fact text, conflict notes redact identity/object secrets, structured why redacts evidence chain metadata, structured why redacts fact identity and scope strings, structured why redacts promotion audit text, structured why redacts git anchors, structured why redacts evidence payloads and tags, why output shows expired/invalidated temporal closeout, send-edge safety scans fact tags for secrets, command cards avoid false HEAD verification claims, low-trust claims blocked from PreToolUse guardrail injection, candidate facts kept out of vector search until promotion, lifecycle-synced vector index entries for expired/reactivated facts, secret-redacted semantic rerank text, retriever-level send-unsafe fact suppression, tag-update secret sensitivity restamping, secret-redacted FTS/vector fact indexing, FTS path-query fail-soft handling, runtime-level injection context redaction, hook tool-result redaction before injection context, shared retrieval-context redaction for CLI/MCP/hooks, atomic invalidation effects, supported-by temporal evidence edges, tool-arg redaction before retrieval, hook prompt redaction before retrieval, transcript-tail redaction before retrieval, symlink-safe workspace config reads, symlink-safe local store paths, symlink-safe AGENTS.md boot capsule writes, symlink-safe generic adapter marker writes, symlink-safe OpenCode config writes, symlink-safe Cursor mcp writes, symlink-safe Claude settings writes, workspace-confined CI workflow extraction, workspace-confined agent prose extraction, workspace-confined Docker/Compose extraction, workspace-confined test config extraction, workspace-confined tooling config extraction, workspace-confined tsconfig extraction, workspace-confined editorconfig extraction, workspace-confined runtime version extraction, workspace-confined lockfile extraction, workspace-confined package script evidence, shared realpath workspace evidence checks, symlink-aware injection staleness checks, generated-marker symlink skip, procedure verifier secret scanning, extraction subject secret scanning, hook session-id redaction, MCP session-reference secret refusal, open-loop session metadata secret refusal, explicit memory metadata secret refusal, packageManager canonical facts, package-manager-aware script extraction, runtime-version deterministic extraction, multi-cookie session redaction, MCP error redaction, fail-closed retrieval for unvalidated commit-scoped facts, semantic CLI recall ranking, auth/cookie header secret scanning, scoped semantic retrieval expansion, workspace-confined injection staleness checks, package metadata extraction, high-trust test/Docker/tooling/tsconfig deterministic extraction, high-trust Python toolchain extraction, high-trust pyproject package-manager extraction, pyproject dependency-group Python command extraction, high-entropy redaction hardening, repo-id-isolated temporal validity, measured hook latency, fail-closed adapter install/uninstall, typed CLI error formatting, answer-bearing coding query expansion, Python package-manager retrieval expansion, redacted TUI selected-fact detail panels, TUI page/jump keyboard navigation, composed TUI empty states with operator status surfaces, SessionStart suppression of superseded user preferences, chunk-safe TUI key decoding with left/right and j/k navigation, bounded secret-redacted TUI prompt input, vector-safe commit-hygiene query expansion, searchable TUI memory lists, and tox/nox Python test harness extraction. 297 tests, 19 gate suites green, all I1-I9 hold._
_Last updated: Durable-write concurrency hardened (reconcileWrite now guards the live learn() path so equal-precedence user contradictions dispute instead of silently superseding, remember accepts base_seen_fact_id for clean updates, and read-modify-write transactions run BEGIN IMMEDIATE so overlapping promotion sweeps serialize instead of losing promotions to swallowed SQLITE_BUSY_SNAPSHOT errors), Windows is now a first-class dev platform (homedir-derived user-global paths, named-pipe daemon sockets, shim-free dev-tool spawns in eval suites, forward-slash generated-marker facts, windows-latest CI job), Private-key scanning now covers DSA, encrypted PEM, and PGP private key block headers, MCP `resolve_conflict` now evaluates user, workspace, and current-session facts together and includes disputed facts so surfaced contradictions stay resolvable through the advertised tool, `graphctx resolve` now refuses non-open-loop facts instead of silently superseding durable memory, Storage migration 0006 adds a composite invalidation conflict lookup index, Session-scoped invalidation now keeps identical open loops isolated across sessions while deduping repeats within a session, Demo seed memory now uses Runtime.rememberFact, open-loop session memory now carries current git anchors, CLI `tui --tab` now fails fast on invalid tabs, CLI/MCP fact-kind validation uses a shared `FACT_KINDS` domain enum, TUI promotion uses Runtime/Probation gates instead of direct activation, Runtime/TUI/CLI/MCP explicit remember paths share safe git-anchored invalidating writes, Runtime/TUI/MCP forget paths share git-anchored temporal closeout, MCP forget stamps git closeout anchors, retrieval candidates are scope-filtered before semantic reranking, retrieval candidates receive final workspace/session scope filtering, superseded facts close temporal validity with `t_expired` and commit anchors, retrieval recency ranking uses the runtime clock, ranking/conflict tests use deterministic fact IDs and clocks, vector embedding cache uses the runtime clock, outcome telemetry uses an injectable clock, injection anti-repetition ledger uses the runtime clock, promotion verification timestamps use the runtime clock, promotion gates rescan secret-shaped fact identity, why renders invalidating commit closeout anchors, revert revalidation respects branch representation, revert revalidation skips bad historical anchors, atomic temporal lifecycle closeout anchors, TUI read model redacts secret fact text, conflict notes redact identity/object secrets, structured why redacts evidence chain metadata, structured why redacts fact identity and scope strings, structured why redacts promotion audit text, structured why redacts git anchors, structured why redacts evidence payloads and tags, why output shows expired/invalidated temporal closeout, send-edge safety scans fact tags for secrets, command cards avoid false HEAD verification claims, low-trust claims blocked from PreToolUse guardrail injection, candidate facts kept out of vector search until promotion, lifecycle-synced vector index entries for expired/reactivated facts, secret-redacted semantic rerank text, retriever-level send-unsafe fact suppression, tag-update secret sensitivity restamping, secret-redacted FTS/vector fact indexing, FTS path-query fail-soft handling, runtime-level injection context redaction, hook tool-result redaction before injection context, shared retrieval-context redaction for CLI/MCP/hooks, atomic invalidation effects, supported-by temporal evidence edges, tool-arg redaction before retrieval, hook prompt redaction before retrieval, transcript-tail redaction before retrieval, symlink-safe workspace config reads, symlink-safe local store paths, symlink-safe AGENTS.md boot capsule writes, symlink-safe generic adapter marker writes, symlink-safe OpenCode config writes, symlink-safe Cursor mcp writes, symlink-safe Claude settings writes, workspace-confined CI workflow extraction, workspace-confined agent prose extraction, workspace-confined Docker/Compose extraction, workspace-confined test config extraction, workspace-confined tooling config extraction, workspace-confined tsconfig extraction, workspace-confined editorconfig extraction, workspace-confined runtime version extraction, workspace-confined lockfile extraction, workspace-confined package script evidence, shared realpath workspace evidence checks, symlink-aware injection staleness checks, generated-marker symlink skip, procedure verifier secret scanning, extraction subject secret scanning, hook session-id redaction, MCP session-reference secret refusal, open-loop session metadata secret refusal, explicit memory metadata secret refusal, packageManager canonical facts, package-manager-aware script extraction, runtime-version deterministic extraction, multi-cookie session redaction, MCP error redaction, fail-closed retrieval for unvalidated commit-scoped facts, semantic CLI recall ranking, auth/cookie header secret scanning, scoped semantic retrieval expansion, workspace-confined injection staleness checks, package metadata extraction, high-trust test/Docker/tooling/tsconfig deterministic extraction, high-trust Python toolchain extraction, high-trust pyproject package-manager extraction, pyproject dependency-group Python command extraction, high-entropy redaction hardening, repo-id-isolated temporal validity, measured hook latency, fail-closed adapter install/uninstall, typed CLI error formatting, answer-bearing coding query expansion, Python package-manager retrieval expansion, redacted TUI selected-fact detail panels, TUI page/jump keyboard navigation, composed TUI empty states with operator status surfaces, SessionStart suppression of superseded user preferences, chunk-safe TUI key decoding with left/right and j/k navigation, bounded secret-redacted TUI prompt input, vector-safe commit-hygiene query expansion, searchable TUI memory lists, and tox/nox Python test harness extraction. 315 tests, 19 gate suites green, all I1-I9 hold._

_Quality counters: Tests: 297. Gate suites: 19._
_Quality counters: Tests: 315. Gate suites: 19._

_Runtime-clock note: direct CLI, eval, and benchmark retrievers pass
`Runtime.clock`, so pull and push retrieval use the same recency clock seam._
Expand Down Expand Up @@ -119,4 +119,4 @@ now have explicit scanners instead of relying only on entropy fallback._
| Code quality | ✅ | new `eval quality` passes 6/6: full-repo Biome, strict TS config/scripts, shared command-surface helpers for CLI help/docs/README reachability, eval-suite runner/test coverage, final README docs-as-code, and generated migration packaging guard |

_Loop note: composite metric = (failing_gates × 100) + (un-perfected aspects); within-aspect
measured gains are recorded in the `memory` graph. Tests: 297, gate suites: 19 (`eval all` includes run/memory/promote/drift/retrieval/gate/security/branch/temporal/conflict/procedure/mcp/storage/telemetry/provenance/resilience/benchmarks/cli-docs-demo/quality)._
measured gains are recorded in the `memory` graph. Tests: 315, gate suites: 19 (`eval all` includes run/memory/promote/drift/retrieval/gate/security/branch/temporal/conflict/procedure/mcp/storage/telemetry/provenance/resilience/benchmarks/cli-docs-demo/quality)._
5 changes: 4 additions & 1 deletion src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ program
subject: opts.subject,
predicate: opts.predicate,
kind,
// Interactive read-then-write: the CLI resolves the current value at
// write time, so a deliberate update supersedes instead of disputing.
baseSeenFactId: rt.currentFactIdFor(opts.subject, opts.predicate),
});
refreshAgentsCapsule(rt);
process.stdout.write(`Remembered ${fact.fact_id}: ${renderCard(fact).markdown}\n`);
Expand Down Expand Up @@ -621,7 +624,7 @@ program
const { runParallelConflictEval, formatParallelConflictReport } = await import(
"./eval/suites/parallel-conflict.js"
);
const r = runParallelConflictEval();
const r = await runParallelConflictEval();
process.stdout.write(formatParallelConflictReport(r));
return r.pass;
};
Expand Down
Loading
Loading