Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
397709a
feat(graph): publish provenance-bound snapshots
theDakshJaitly Aug 22, 2026
790f5c8
feat(graph): gate consumers on verified freshness
theDakshJaitly Aug 22, 2026
cebb46a
test(eval): exclude snapshot provenance from semantic hashes
theDakshJaitly Aug 22, 2026
dad82aa
docs(patterns): record safe graph snapshot evolution
theDakshJaitly Aug 22, 2026
f1fa483
docs(graph): record freshness follow-up caveats
theDakshJaitly Aug 22, 2026
850748a
fix(eval): hash semantic graph snapshot provenance
theDakshJaitly Aug 23, 2026
fd38737
fix(graph): bind targeted reads to exact freshness
theDakshJaitly Aug 23, 2026
b39060e
feat(graph): add explicit safe graph maintenance
theDakshJaitly Aug 23, 2026
fe211d0
perf(graph): add status characterization harness
theDakshJaitly Aug 23, 2026
a8c214c
docs(graph): record freshness and recovery architecture
theDakshJaitly Aug 23, 2026
4f48489
merge: integrate graph freshness dependency
theDakshJaitly Aug 23, 2026
bdf30b6
feat(graph): implement the repository GraphPort adapter
theDakshJaitly Aug 23, 2026
a1a8b0f
feat(hub): expose real graph search and health
theDakshJaitly Aug 23, 2026
c57f599
feat(hub): run explicit graph maintenance jobs
theDakshJaitly Aug 23, 2026
168bc64
feat(hub): add the read-only Code workbench
theDakshJaitly Aug 23, 2026
09834fc
fix(hub): map graph input validation consistently
theDakshJaitly Aug 23, 2026
1db5dd4
test(hub): cover graph security packaging and browser states
theDakshJaitly Aug 23, 2026
17e2f9b
docs(hub): record graph integration architecture
theDakshJaitly Aug 23, 2026
b5d7d13
test(graph): stabilize CI portability and Linux visuals
theDakshJaitly Aug 23, 2026
68445b0
test(graph): make reader races portable across Node versions
theDakshJaitly Aug 23, 2026
3c72051
test(graph): budget legacy rebuild scenarios
theDakshJaitly Aug 23, 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
32 changes: 23 additions & 9 deletions .mex/ROUTER.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ edges:
condition: when setting up the dev environment or running the project for the first time
- target: patterns/INDEX.md
condition: when starting a task — check the pattern index for a matching pattern file
last_updated: 2026-08-23
last_updated: 2026-08-24
---

# Session Bootstrap
Expand All @@ -40,23 +40,37 @@ Then read this file fully before doing anything else in this session.
- The Project Hub now projects Lane C's immutable canonical activity and legacy
decision log through a bounded, read-only Activity timeline. Recorded actors
remain immutable while current alias resolution is shown separately.
- Versioned graph snapshot provenance and read-only freshness inspection gate
grounding in check, doctor, and dashboard flows without implicit graph sync.
- Explicit graph status, refresh, and isolated rebuild/recovery commands preserve
the last trustworthy index behind one cross-process maintenance lease.
- Targeted graph get/query/impact consumers use one provenance-bound immutable
snapshot and discard output if graph or exact source identity changes.
- The graph half of Checkpoint 2 is working in the Project Hub: grouped symbol
and source Search, the read-only Code workspace, structured graph Health, and
explicit refresh/rebuild jobs all use the repository-bound GraphPort adapter.
Hub graph reads preserve engine ranking and never maintain the index implicitly.
- Graph evaluator determinism includes semantic snapshot provenance while
excluding only operational timestamps and Git coordinates.

**Not Built:**
- The real Wiki adapter and type-parity registration against the teammate engine.
- Real Graph/Wiki Hub adapters, Workstream/Inbox/Relay/Playbook persistence,
Catch Up actions, activity creation, graph freshness/recovery, and later
delivery checkpoints from the human-team program.
- Real Wiki Hub search, health, and maintenance; Workstream/Inbox/Relay/Playbook
persistence; Catch Up actions; activity creation; and later delivery
checkpoints from the human-team program.
- Public package-root exports for the provisional team contracts.

**Known Issues:**
- The teammate Wiki implementation branch/commit is not yet available, so the
consumer contract remains provisional.
- The teammate Wiki implementation is not yet complete and pinned at a
qualifying commit, so the consumer contract remains provisional.
- The current scaffold architecture, conventions, decisions, stack, and setup
context files are still largely unpopulated placeholders.
- Real parser, filesystem, index, migration, and graph-grounding compliance must
be verified against the pinned teammate implementation, not inferred from the mock.
- Hub Graph/Wiki controls remain unavailable until their corresponding real
adapters are integrated; development fixtures are never production data.
be verified against the completed, pinned teammate implementation, not
inferred from the mock.
- Hub Wiki controls remain unavailable until the real adapter is integrated;
development fixtures are never production data. Graph repair controls appear
only when a fresh status or executable Lane A remediation makes them safe.

## Routing Table

Expand Down
2 changes: 2 additions & 0 deletions .mex/patterns/INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@ Lookup table for project-specific pattern files.
| Pattern | Use when |
|---------|----------|
| [`contract-first-external-adapter.md`](contract-first-external-adapter.md) | Freezing a consumer port before an independently owned implementation is pinned |
| [`fresh-graph-hub-integration.md`](fresh-graph-hub-integration.md) | Connecting a real graph read or maintenance capability to the local Project Hub |
| [`local-first-team-state.md`](local-first-team-state.md) | Adding canonical team artifacts, read-only repository observations, or per-user SQLite state |
| [`secure-local-project-hub.md`](secure-local-project-hub.md) | Adding a loopback Hub route, API contract, browser session, or explicit local job |
| [`safe-graph-snapshot-evolution.md`](safe-graph-snapshot-evolution.md) | Changing graph indexing, freshness inspection, or recovery without publishing mixed or unsafe snapshots |
120 changes: 120 additions & 0 deletions .mex/patterns/fresh-graph-hub-integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
---
name: fresh-graph-hub-integration
description: Connect graph reads and maintenance to the Project Hub without mixed snapshots, implicit writes, reranking, or private-data leakage.
triggers:
- "Hub graph integration"
- "Code workspace"
- "graph Search"
- "graph Hub job"
edges:
- target: "safe-graph-snapshot-evolution.md"
condition: "when changing freshness, graph storage, source binding, or recovery"
- target: "secure-local-project-hub.md"
condition: "when changing Hub routes, sessions, safe projections, SSE, or jobs"
- target: "../../docs/design/hub-graph-integration.md"
condition: "when reviewing the current Graph-to-Hub architecture and bounds"
grounds_to: []
last_updated: 2026-08-24
---

# Fresh Graph Hub Integration

## Context

The Hub is a consumer of the internal `GraphPort`, not another graph engine.
Graph reads may return source only after proving that indexed facts, the
published snapshot, and the exact live source bytes describe one repository
observation. Graph maintenance is a separate, explicit user action. The Hub
must not open graph SQLite directly, shell out to `mex graph`, fuse rankings,
or make Wiki availability appear real.

## Steps

1. Bind one package-private repository adapter to the Hub process. Implement the
frozen `GraphPort` by calling Lane A modules directly; do not add a package-
root export, raw SQLite callback, command escape hatch, or subprocess.
2. Route every graph-derived response through the complete freshness handshake:
inspect a stable `fresh` graph, adopt one inode-bound immutable SQLite
session, read graph facts and hash-matched contained source, build the whole
bounded response in memory, revalidate database/snapshot/source freshness,
and only then release it. Discard the complete response on any final mismatch.
3. Batch facts that must agree. Search symbols and sources through one
`searchBundle()` session; assemble symbol identity, source, and the selected
callers/callees/impact view through one `readSymbolWorkspace()` session.
4. Preserve engine order and scores. Keep Wiki, symbol, and source groups
separate, with independent cursors and group-local cursor failures. Never
rerank graph output or fuse scores across domains.
5. Bind each canonical base64url cursor to its operation, snapshot hash,
normalized request (including limits and workspace view), and offset. Treat
a request mismatch as `VALIDATION_FAILED` and a snapshot mismatch as
`REVISION_CONFLICT`. Keep normal pagination separate from safety truncation.
6. Project only allowlisted fields into private Hub contracts. Bound source,
paths, diagnostics, matched terms, relations, impact, and the serialized
response. Map internal failures to stable MEX Problem Details without raw
SQLite, Git, filesystem, recovery-path, stderr, or stack information.
7. Derive graph job eligibility from the current structured Health observation,
then revalidate it immediately before durable job creation. For a non-fresh
graph, a missing or unsafe remediation command is not an enabled control; a
structurally fresh graph may explicitly allow both operations.
8. Run refresh/rebuild only through injected executors. Pass the job
`AbortSignal` into Lane A, persist only fixed phases and trustworthy numeric
counts, retain the Hub generation/lease checks, and let Lane A's cross-process
maintenance lock arbitrate Hub and CLI writers. Rebuild requires the browser
confirmation step; neither operation runs during an ordinary read.
9. Keep Wiki explicitly unavailable until its real adapter passes the frozen
conformance boundary. Do not fill Graph or Wiki gaps with production fixtures.

## Gotchas

- A fresh status observed before a request is not a freshness proof for its
response. Final revalidation is mandatory, including after source reads.
- An immutable SQLite handle still needs inode, sidecar, and snapshot binding.
Atomic database replacement and WAL activity must fail visibly.
- Source must come from one contained, fd-stable buffer whose decoded hash
matches the indexed row. Never pair an old declaration with newly read text.
- A group-specific bad cursor may fail only that Search group, but final
freshness invalidation invalidates both graph groups and returns no partial data.
- `nextCursor` means another normal page exists; `truncated` means a safety or
content bound omitted data. They are not interchangeable.
- Health capability is structural. A missing index can still expose a safe
rebuild operation, while writer activity or an observation race exposes no
repair control.
- Job progress messages can contain paths or source details. Persist phase and
numeric counts only; discard the message.
- Successful graph maintenance invalidates cached Search, Code, Health, Jobs,
and capability queries. It does not authorize automatic maintenance later.

## Verify

- [ ] Search and Code use one initial and one final freshness observation and
return no partial response after database, snapshot, source, WAL, or ABA races
- [ ] Symbol/source ranking and relation ordering match the engine exactly
- [ ] Cursor operation, request, limit, view, and snapshot binding are covered
- [ ] Missing, stale, rebuild-required, corrupt, degraded, and interrupted
states map to stable safe errors
- [ ] Source, relation, impact, diagnostic, cursor, and 1 MiB response bounds pass
- [ ] Host/session protection covers reads; Origin, JSON, and CSRF protect jobs
- [ ] Refresh/rebuild contention, cancellation, late progress, restart, and
shutdown preserve the last trustworthy graph and never mutate source
- [ ] Read-only endpoints leave Graph/Wiki files, Git, worktree, Activity, and
local state byte- and mtime-identical
- [ ] Packed Search/Code/Health and real refresh/rebuild jobs pass without public
declaration leaks or production fixtures
- [ ] Graph protocol goldens, evaluator tests, TUI regressions, typechecks,
browser accessibility, package smoke, and `git diff --check` pass

## Debug

First classify the failing boundary: request validation, current graph status,
immutable-session adoption, indexed source binding, final freshness, safe Hub
projection, durable job ownership, or Lane A maintenance. Preserve the stable
MEX code and reproduce the exact boundary. Do not fix freshness failures by
retrying inside an ordinary read or by returning the already-buffered subset.

## Update Scaffold

- [ ] Update `.mex/ROUTER.md` when Graph or Wiki Checkpoint 2 capability changes
- [ ] Update `docs/design/hub-graph-integration.md` when a bound, error, or
freshness/job invariant changes
- [ ] Keep `src/index.ts`, graph protocol output, ranking, and `mex tui` unchanged
unless a separate public-boundary change explicitly owns them
116 changes: 116 additions & 0 deletions .mex/patterns/safe-graph-snapshot-evolution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
---
name: safe-graph-snapshot-evolution
description: Evolve graph indexing or freshness checks without publishing mixed facts, mutating reads, or losing the last trustworthy snapshot.
triggers:
- "graph freshness"
- "graph snapshot"
- "graph indexing"
- "graph recovery"
- "SQLite graph"
edges:
- target: "../context/architecture.md"
condition: "when changing the graph data plane or its consumers"
- target: "../context/conventions.md"
condition: "when verifying a graph implementation change"
grounds_to: []
last_updated: 2026-08-22
---

# Safe Graph Snapshot Evolution

## Context

The graph database is both a query surface and the grounding baseline for drift
checks. A graph that is internally valid but represents mixed source, config,
Git, or compiler observations is not trustworthy. Ordinary inspection must also
remain read-only: SQLite recovery, schema repair, indexing, and grounding writes
belong only to explicit maintenance workflows.

## Steps

1. Define source extensions, ignore rules, config inputs, grammar identity, and
extractor/resolver versions in one corpus policy shared by indexing and
freshness inspection.
2. Discover source and config inputs through repository-contained canonical
paths. Bind each read to a regular-file descriptor and verify the original
path still resolves to the same inode after the read.
3. Make parsers and compiler extraction consume the captured bytes. Do not let
a downstream compiler host silently re-read live source or config files.
4. Revalidate Git coordinates, the exact source corpus, config inputs, and any
additional semantic inputs at the final boundary before publication.
5. Persist a versioned provenance snapshot in the same transaction as graph
facts. A failed stage, parse, invariant check, or publication race must not
advance snapshot metadata.
6. Inspect with raw read-only/immutable SQLite access only after checking WAL,
rollback-journal, containment, and file identity. Validate every schema
object and data shape required by graph readers before reporting `fresh`.
7. Preserve the prior trustworthy graph when an explicit rebuild candidate is
incomplete or failed. Build under a repository-scoped owner-token lock,
validate a same-directory candidate, revalidate the live database, and only
then publish by atomic rename. Surface failure rather than printing a
successful no-op summary.
8. Guard graph-derived reads for their complete use window. If the database or
selected path changes, discard the whole batch of derived findings. Bind any
returned live source to one contained fd-stable byte buffer whose decoded
hash matches the indexed row, so an A→B→A edit cannot escape validation.
9. Keep retrieval ranking and protocol-v3 record shapes untouched unless the
task explicitly changes that public boundary; rerun the exact JSONL goldens.
10. Normalize evaluator provenance field-by-field. Exclude only explicitly
operational snapshot fields; malformed or future snapshot shapes must fail
closed instead of disappearing from the semantic graph hash.

## Gotchas

- Size and mtime are hints, not content identity. Same-size edits can restore an
mtime and still require reindexing.
- An immutable SQLite connection assumes its file never changes. A clean probe
before opening is insufficient; revalidate around and after graph use.
- A live WAL may contain the current schema while the main file looks stale or
corrupt. Treat writer activity as transient/degraded, never durable damage.
- `PRAGMA quick_check` does not prove application compatibility. FTS shadow
tables, fingerprint JSON, LSH bands, ownership, and dangling references need
explicit invariants.
- Source bytes can change A→B→A while a compiler runs. Final source hashing alone
cannot detect facts extracted from B; extraction must be bound to A.
- Graph diagnostics and remediation commands must be truthful. Do not recommend
a command for a state it cannot safely repair.
- Wall-clock status timings vary by machine and process-start overhead. Keep
the benchmark non-gating, record its environment, and protect correctness
with deterministic race, non-mutation, and bounded-work tests.

## Verify

- [ ] Added, modified, deleted, same-size/restored-mtime, branch, config,
grammar, extractor, and policy drift cases are deterministic.
- [ ] Active/unreadable WAL and rollback journals never produce `fresh` or a
false corruption diagnosis.
- [ ] Missing, legacy, newer, malformed, and structurally corrupt schemas have
accurate diagnostics and safe remediation.
- [ ] Source/config symlink escape, retarget, atomic replacement, and ABA tests
preserve the prior snapshot.
- [ ] Failed parse/stage/publication tests preserve prior facts and metadata.
- [ ] Candidate replacement, candidate WAL, rollback, maintenance-lock, and
first-publication failure tests leave either the prior graph or no graph.
- [ ] Ordinary check, doctor, dashboard, and status paths do not change graph
bytes, sidecars, metadata, or directory mtimes.
- [ ] `get`, `query`, and `impact` return no partial records when freshness,
source identity, sidecars, or the selected database change mid-read.
- [ ] `npm run typecheck`, `npm test`, `npm run eval:test`, and `npm run build`
pass, along with protocol-v3 goldens and `git diff --check`.
- [ ] Only intended paths are staged; generated graph databases and unrelated
working-tree files remain excluded.

## Debug

First separate transient writer activity from durable corruption. Compare the
persisted snapshot, exact `files(path, content_hash)` rows, current corpus and
config hashes, Git observations, and required reader invariants. When a race
test fails, verify which layer re-read the filesystem after secure discovery;
fix that boundary instead of adding timing delays.

## Update Scaffold

- [ ] Update `.mex/ROUTER.md` when freshness, refresh, or recovery capabilities
move from "Not Built" to "Working".
- [ ] Add new graph failure modes to this pattern after they are reproduced and
covered by a deterministic regression.
Loading