For Agents

Reverse-chronological session log. Newest entries at top, grouped by date (## YYYY-MM-DD). Each bullet: one piece of work, short summary, wikilinks to docs touched. Updated by obsidian-documenter on every project doc write. Read by historian at bootstrap.

2026-09-07

  • πŸ”¬ Knowledge-graph research recommends narrowing this project to a single reconciler and dropping grafeo. A day of research (two audits, a prior-art probe, four surveys) concluded that the only thing in the graph stack worth building is a reconciler: a job that resolves note code_refs anchors against a current code index and flips status: stale on symbol_missing or code_changed, setting verified: today otherwise. Estimated 150-300 lines, and SQLite suffices β€” grafeo is unnecessary for it. Everything else has a credible existing tool (Serena for live symbols, Basic Memory for typed concept edges, codebase-memory-mcp for a committed cross-repo artifact). Also: the paused graphtest rustc_driver HIR walker is superseded by rust-analyzer scip, which yields stable symbols with no nightly pin β€” do not revive it. ⚠️ Nothing is decided; the standing alternative is to drop the project and trial trace-mcp, whose decision-verification already returns the same three verdicts. ⭐ If grafeo goes, chrono stops being free β€” it arrives transitively via grafeo’s arrow-export β€” 2026-09-07-scope-recommendation-reconciler, knowledge-graph-research-2026-09-07
  • Created the project. Rust workspace at /Volumes/bandi/coding/ai-project-brain β€” edition 2024, resolver 3, two members (packages/app, packages/core/project), all deps inherited from the root [workspace.dependencies]. β›” Scaffold only: main.rs is 10 lines, lib.rs is the cargo-generated add() stub, project.rs is empty. No architecture to document yet β€” ai-project-brain
  • ⚠️ Recorded the grafeo feature matrix, because embedded / server / edge are three different products and the split is invisible on docs.rs. default = ["embedded"] gives the in-process engine (GQL, vector/text/hybrid indexes, CDC, graph algorithms, rayon); server adds all query languages (cypher, sparql, gremlin, graphql, sql-pgq) plus async-storage, triple-store, shacl; edge/browser strips to lpg + gql + regex-lite for wasm. The workspace runs default features β€” GQL only, no server-mode languages β€” grafeo-feature-matrix
  • ⭐ The gotcha worth the note: grafeo is SILENT in your logs by default. tracing is an opt-in grafeo feature (tracing = ["grafeo-engine/tracing"]), NOT part of embedded/default β€” it arrives free with server, and that asymmetry is the trap. Symptom: own tracing::info! calls appear, graph layer emits zero spans and zero events, nothing errors, no warning. The natural debugging path blames the subscriber (EnvFilter, RUST_LOG, init order) β€” all of which are fine; the instrumentation was never compiled in. Live risk right now, not hypothetical: packages/app/src/main.rs already initializes tracing_subscriber::fmt() with EnvFilter, so the receiving end works and only the sending end is missing. Fix is features = ["tracing"] on the grafeo entry in the root [workspace.dependencies] β€” grafeo-feature-matrix
  • ⚠️ cargo remove is a workspace-aware garbage collector, not a per-manifest text edit (cargo 1.95.0). cargo remove -p <member> <dep> also prunes the matching root [workspace.dependencies] entry once no member references it. This breaks the obvious migration path β€” add to member β†’ copy up to workspace β†’ remove from member β†’ re-add as inherited β€” because step 3 deletes what step 2 just wrote, and the failure surfaces one step later at cargo check with workspace.dependencies` was not defined, making the root manifest look like it was never edited. Fix: write dep.workspace = true into the member manifest directly, never routing through cargo remove β€” cargo-workspace-dependency-inheritance
  • ⭐ Added chrono for timestamps β€” and it cost ZERO new crates, because it was already in the tree. Checking Cargo.lock before choosing a crate showed chrono v0.4.45 already compiled in, arriving transitively as chrono ← arrow-array v58.4.0 ← arrow-ipc ← grafeo-engine ← grafeo (feature "arrow-export") β€” and arrow-export is part of grafeo’s default embedded set, so any project on default grafeo already has chrono. Active features were alloc/std/now/clock but not serde; serde v1.0.229 was likewise already present. Declaring chrono = { version = "0.4.45", features = ["serde"] } therefore only switched on impls inside a crate already there β€” verified: 149 packages in Cargo.lock before and after, one chrono entry, no duplicate versions. ⭐ The reusable rule: grep Cargo.lock before adding any crate β€” matching what a heavy dependency already chose is free and semantically correct, since grafeo speaks chrono internally via arrow, so timestamps round-trip without a conversion layer. time or jiff would have added a parallel crate tree AND a type-mismatch boundary at the DB edge β€” chrono-already-in-tree-via-arrow
  • πŸ”§ cargo tree verifies dependency edits while the build is red. The workspace source was mid-edit and would not parse (a struct field awaiting its type: last_index_date: ,), so cargo check --workspace failed for reasons unrelated to the dependency work. cargo tree -p <crate> --depth 1 resolves purely from the manifests and does not compile, so it still confirmed that dep.workspace = true inheritance resolves to the intended versions (project v0.1.0 β†’ chrono v0.4.45 + tracing v0.1.44). Companion checks that also survive a broken build: cargo check -p <unaffected-crate> (proves the root manifest is valid TOML and resolves), cargo tree -p <crate> -e features -i <dep> (proves a feature actually activated), and grep -c '^\[\[package\]\]' Cargo.lock before/after (proves nothing was silently pulled in). Mental model: cargo has two front ends β€” resolution and compilation β€” and a syntax error cannot invalidate a cargo tree result β€” cargo-tree-verifying-deps-while-build-is-red
  • ⚠️ std::path::Path cannot be a struct field by value β€” two structs here were written as path: Path / base_path: Path. Path is unsized (it wraps [u8]), so it fails with the size for values of type `[u8]` cannot be known at compile-time β€” an error that never names Path and reads like it is about something else. PathBuf is the owned form; same three-way pattern as &strβ†’String and &[T]β†’Vec<T>. Same half-finished struct work that made the build red above β€” rust-path-vs-pathbuf-struct-field
  • πŸ“‹ Recorded the current dependency set on the project MOC β€” root [workspace.dependencies]: async-trait 0.1.92, chrono 0.4.45 (+serde), futures-util 0.3.34, grafeo 0.5.42, tokio 1.53.1 (+full), tracing 0.1.44, tracing-subscriber 0.3.23 (+env-filter). Member split follows lib-emits / binary-subscribes: packages/app takes six incl. tracing-subscriber (it owns the binary), packages/core/project takes chrono + tracing only β€” Workspace Dependencies
  • Initialized activity log and project folder.