feat: write leafs incrementally without rebuilding the graph. (#29)
Ladybug 0.19 stays FTS/HNSW queryable on MERGE of new ids; DROP INDEX was the fatal path. bin/brain/add.go and POST /ingest land facts+info in one transaction so watch/mail/git can become leafs now (Gitea #14).
This commit is contained in:
+5
-3
@@ -80,14 +80,16 @@ Conflicting pairings (≥2 yes vs ≥2 no) = hypothesis (OQ1 → v2 resolution).
|
||||
They do not exec Python. Control questions for recall@5 live in
|
||||
`internal/brain/rank` so CI can test the table without libladybug.
|
||||
Python `bin/kb/{get,stats,eval}` remain for GitHub Actions until the runner
|
||||
fetches Zig + libs (`bin/cgo/zig`). Index/write is still `bin/kb/index`
|
||||
fetches Zig + libs (`bin/cgo/zig`). Incremental write is `bin/kb/add`
|
||||
(`bin/brain/add.go`). Bulk index/write is still `bin/kb/index`
|
||||
(`docker compose --profile index`).
|
||||
|
||||
## Agent API (D20)
|
||||
|
||||
`bin/brain/serve.go` exposes the same `internal/httpapi.Ops` table as OpenAPI
|
||||
(`GET /openapi.json`) and MCP (`POST /mcp` JSON-RPC `tools/list` +
|
||||
`tools/call`). Tool names match paths: `search`, `get`, `stats`, `audit`.
|
||||
`tools/call`). Tool names match paths: `search`, `get`, `stats`, `audit`,
|
||||
`ingest` (add a leaf; omit body for the CLI hint).
|
||||
Agents should use these endpoints instead of shebang CLIs.
|
||||
|
||||
## Reasoner (D18)
|
||||
@@ -98,5 +100,5 @@ CPU sidecar: compose profile `reasoner` (`OLLAMA_NUM_GPU=0`,
|
||||
`127.0.0.1:11435`). Bake-off: `bin/reasoner/bakeoff.go`. Weights stay out
|
||||
of the 2dph image. See [docs/reasoner.md](reasoner.md).
|
||||
|
||||
Gap to v1 (write, hops, corpus, agent loop): [roadmap](roadmap.md),
|
||||
Gap to v1 (hops, corpus, CI eval): [roadmap](roadmap.md),
|
||||
[epic #16](https://git.produktor.io/eSlider/2dph/issues/16).
|
||||
+7
-13
@@ -23,8 +23,9 @@ Decisions: [PLAN.md](../PLAN.md).
|
||||
Read path Go + Zig CGO (D21). HTTP + OpenAPI + MCP (D20). PicoClaw compose
|
||||
profile + CPU reasoner (D18). Mail sync → import → rebuild. D14 shebangs.
|
||||
Compose `api` (no CPython) / `index` (Python write). Issues #1–#5, #7–#13.
|
||||
|
||||
`POST /ingest` is a rebuild **hint**. `add` is not implemented.
|
||||
[#15](https://git.produktor.io/eSlider/2dph/issues/15) lever/loop.
|
||||
[#14](https://git.produktor.io/eSlider/2dph/issues/14) `bin/brain/add.go` /
|
||||
`POST /ingest` (Python `kblib.add_leafs`; no Go upsert port).
|
||||
|
||||
## Blockers
|
||||
|
||||
@@ -34,24 +35,18 @@ question
|
||||
├─ FTS + HNSW ← in
|
||||
├─ facts / info roots ← in
|
||||
├─ web (D17) ← in
|
||||
├─ brain/add ACID ← in
|
||||
├─ Cypher hop ← #17 schema yes, search no
|
||||
├─ brain/add ACID ← #14 rebuild only
|
||||
└─ facts+chats corpus ← #18
|
||||
```
|
||||
|
||||
1. **[#14](https://git.produktor.io/eSlider/2dph/issues/14) write** —
|
||||
`bin/brain/index.go --rebuild` (Python `kblib`). No incremental
|
||||
`brain/add`. Watch/mail/git cannot become facts “now”.
|
||||
2. **[#17](https://git.produktor.io/eSlider/2dph/issues/17) hops** —
|
||||
1. **[#17](https://git.produktor.io/eSlider/2dph/issues/17) hops** —
|
||||
`Leaf-[:FROM_FILE]->File-[:HAS_VERSION]->Commit-[:AUTHORED]->Person`
|
||||
exists; `--hop` still errors. Without a walk, D9/D10 are paper.
|
||||
3. **[#18](https://git.produktor.io/eSlider/2dph/issues/18) corpus** —
|
||||
2. **[#18](https://git.produktor.io/eSlider/2dph/issues/18) corpus** —
|
||||
rebuild loads repo markdown + mail as `info`. `facts/extract` pairing
|
||||
and `bin/chats` are not indexed. WhatsApp is a stub. PII stays in `var/`.
|
||||
4. **[#15](https://git.produktor.io/eSlider/2dph/issues/15) lever/loop** —
|
||||
2dph is the lever (`search` → `get` → `audit`). PicoClaw is the loop.
|
||||
Document the contour in-repo; CPU turns need a large context window.
|
||||
5. **[#19](https://git.produktor.io/eSlider/2dph/issues/19) CI eval** —
|
||||
3. **[#19](https://git.produktor.io/eSlider/2dph/issues/19) CI eval** —
|
||||
recall SoT should be `bin/brain/eval.go` via Zig, not Python `bin/kb/eval`.
|
||||
|
||||
## Not v1
|
||||
@@ -61,7 +56,6 @@ contradiction resolution, OQ3 duckdb-md export, OQ4 YAML-first leafs.
|
||||
|
||||
## Close epic #16 when
|
||||
|
||||
- facts+info can be written without a full rebuild for every leaf
|
||||
- `--hop` stops erroring and runs a Cypher path from search hits
|
||||
- ops pairing + chat import land as leafs on rebuild
|
||||
- MCP tool order is documented and still gated by tests
|
||||
|
||||
+4
-2
@@ -43,10 +43,12 @@ That binds `127.0.0.1:8888`. JSON format must stay enabled.
|
||||
|
||||
## Index then search
|
||||
|
||||
Write path is Compose profile `index` (Python Ladybug rebuild) until
|
||||
`brain/add` is v2. The operator command is `bin/brain/index.go`.
|
||||
Write path is `bin/brain/add.go` for a leaf (or `POST /ingest`). Bulk
|
||||
corpus rebuild remains `bin/brain/index.go --rebuild` (Compose profile
|
||||
`index`). Do not DROP INDEX on Ladybug 0.19.
|
||||
|
||||
```bash
|
||||
bin/brain/add.go --text "arc-1 runs Matrix" --root facts --source "compose.yml x docker ps"
|
||||
bin/brain/index.go --rebuild
|
||||
bin/brain/search.go "LadybugDB vector index" # facts → info → web (D17)
|
||||
bin/brain/search.go "upstream flag" --no-web
|
||||
|
||||
Reference in New Issue
Block a user