Commit graph

8028 commits

Author SHA1 Message Date
CREDO23
56fdda6871 refactor(knowledge_store): name the two index entry points for their scope
index_revision promised an argument it does not take — its docstring had
to open by disclaiming it — and reindex is the same verb the legacy
per-document editor path already uses, which is the writer this phase
guards against.

Fossil's rebuild was the obvious alternative and is wrong here: the run
upserts and prunes, and document ids survive it because they reach the
browser through the Zero publication. Nothing is wiped but chunks.

The two differ only in scope, so the names say scope: index_changes
folds in what moved since the stamp, index_tree reconciles against the
whole tree and is the only one that can notice a deletion it never saw.

Celery task names are untouched; they are the wire contract.

Also corrects the umbrella plan, which described this as "wipe +
rebuild" while 04-derived-index.md said document rows are never wiped.
2026-07-30 12:17:10 +02:00
CREDO23
58126c5d30 refactor(knowledge_store): group the derived index into its own package
The core package was clean apart from two files: everything under
knowledge_store imports only itself and app.config, while indexer.py
reached into app.db, the indexing pipeline and the agents middleware.
Per ADR 0002 that file is a driven consumer, not core, and nothing in
the layout said so.

Moves it to knowledge_store/index/ as converge.py + queue.py, and the
three celery entry points to celery_tasks/knowledge_store/. Task names,
queue routes and beat entries are unchanged; only module paths move.

index/__init__.py deliberately re-exports nothing. queue.py is a
writer's last step and has to stay cheap to import, so a convenience
re-export would put the ORM and the pipeline on every save's import
path. A test pins that, and fails if the re-export comes back.
2026-07-30 11:51:18 +02:00
CREDO23
49f7c89414 test(tasks): cover the drift monitor's verdict and per-workspace isolation
This check is what replaces reading migration reports by hand once
workspaces are flipped, so an "ok" it reports has to mean git and
Postgres actually agree. Runs against real repos and rows: a seeded
workspace reads ok, an unseeded document reads drift, an unflipped
workspace is not checked, and one failing workspace still leaves the
next one checked.

Mutation-verified: collapsing _status to a constant "ok" fails.
2026-07-30 11:21:40 +02:00
CREDO23
884b05a084 test(knowledge_store): pin enqueue_index's swallow and its happy path
enqueue_index deliberately swallows broker failures so a committed save
never fails on a queue problem. Untested, that swallow makes a typo
look exactly like a broker outage: nothing enqueues and nothing
complains. Covers the dispatch, the kill switch, the non-numeric id
drop, and the swallowed connection error.
2026-07-30 11:21:40 +02:00
CREDO23
28a5eaf60c test(tasks): cover the drift sweep's candidates and queue routing
The sweep is the only recovery for indexing lost to a broker or worker,
and it was the one piece of phase 4 with no test at all. Pins the
flipped-only filter, the skip when a stamp is level or a store is
missing, the enqueue cap, and the routing split where a never-indexed
workspace goes to the rebuild task rather than the fast queue.

Both of those last two were verified by mutation: dropping the flipped
filter and inverting the routing each fail a test.
2026-07-30 11:21:28 +02:00
CREDO23
9fecf54df5 docs(plans): sync phase statuses with what shipped
The umbrella's subplan index still said PLANNED for phases 2-5 while
the inline sections said SHIPPED, and phase 5 had no status line at
all. Both now record: 1-4 shipped, 5 tooling shipped with fleet flips
and cut-time deletion pending, C2 read_file citation envelope the one
open phase-2 item.
2026-07-30 10:39:39 +02:00
CREDO23
487aac0a33 Merge PR #1647: derive the postgres chunk index from git
Lands the Phase 4 derived-index work and aligns it with the shipped
conventions: repo paths keep the documents/ root, flag checks go through
the per-workspace knowledge_store_enabled_for, the retitle mechanism is
folded into the batched revision recorder, lock expiry stays loud, and
the migration is renumbered 175 -> 176 on top of the flip-flag one.
Incremental index tasks now retry on lock contention so saves landing
mid-rebuild don't wait for the hourly sweep.
2026-07-30 10:30:51 +02:00
Anish Sarkar
80cb76ac8f docs(plans): record phase 4 as built 2026-07-30 03:10:24 +05:30
Anish Sarkar
3f541d7bb8 fix(documents): stop legacy writers from fighting the store indexer
The editor reindex titles a document from its first heading while the indexer titles it from the filename, so both running flips the title on every save; guarded inside _reindex_document so neither call site can miss it. Version restore returns 409, since it rewrites content without a revision and the next reindex would revert it. Unrelated: all three version routes passed a User where check_permission expects an AuthContext, so every one of them 500'd.
2026-07-30 03:10:14 +05:30
Anish Sarkar
6d19049141 feat(documents): enqueue indexing from both store writers
Enqueue-only and never raising: the content is already committed, and the drift sweep is the backstop. Also drops the stale blob when a retitle moves a document, which otherwise turned one document into two files the moment an indexer existed.
2026-07-30 03:10:04 +05:30
Anish Sarkar
d89d2e680b feat(tasks): index store revisions and sweep drifted workspaces
Hourly with a per-run enqueue cap, not daily: KNOWLEDGE_STORE_ENABLED is process-global, so the first sweep after enabling it is a fleet-wide backfill. Rebuilds route to the connectors queue; the per-save task stays on the fast queue.
2026-07-30 03:09:58 +05:30
Anish Sarkar
501775e505 test(knowledge_store): cover convergence, rebuild determinism, and parity 2026-07-30 03:09:52 +05:30
Anish Sarkar
f4a519bedc feat(knowledge_store): converge the postgres index from a store revision
index_revision and reindex share one convergence body, so the incremental and rebuild paths cannot drift. Rows are adopted by path and pruned only when they carry the ownership marker, so an upload is not duplicated and a connector row is not deleted. A partial failure withholds the stamp; an intentional skip still stamps.
2026-07-30 03:09:44 +05:30
Anish Sarkar
fb6776992a test(indexing_pipeline): pin chunk line spans and the note identity seam 2026-07-30 03:09:40 +05:30
Anish Sarkar
e83f68cee9 feat(indexing_pipeline): thread chunk line spans through the cache
Spans are located by ordered cursor search at read time rather than stored in the cached value, so no chunker_version bump and no fleet-wide re-embed. Reused chunks now carry the new span, because unchanged text still moves when a paragraph is inserted above it.
2026-07-30 03:09:32 +05:30
Anish Sarkar
05f41dacbe feat(db): add derived-index columns for drift marker and chunk spans
One migration for both tables so the two columns cannot become two Alembic heads. No backfill: NULL last_indexed_revision is what makes the drift sweep pick a workspace up, and NULL spans repopulate on the next index.
2026-07-30 03:09:22 +05:30
Anish Sarkar
843cc607f5 refactor: update path resolution for flagged workspaces and unify document path handling in commit process 2026-07-30 00:37:06 +05:30
Anish Sarkar
89d0234a0f refactor: consolidate indexing functions and enhance document identity handling in derived index 2026-07-30 00:33:22 +05:30
Anish Sarkar
36140925f6 refactor: rename _ensure_folder_hierarchy to ensure_folder_hierarchy for clarity 2026-07-30 00:27:46 +05:30
Anish Sarkar
d4a55a4f9f test: update document store path in integration tests for consistency 2026-07-29 23:51:09 +05:30
CREDO23
4bee824def migration: fleet runner flips workspaces, only ever on passing parity
--yes --flip turns a workspace git-native strictly after its report is
ok; --unflip --workspace N is the per-workspace rollback. Verified end
to end on the dev database: seed, flip, column true, unflip. Plan work
item 4 marked shipped.
2026-07-29 20:17:36 +02:00
CREDO23
d8d88d0e9c agents: guard sites take the per-workspace verdict, resolved once per turn
The factory resolves knowledge_store_enabled_for once and the whole turn
inherits it (backend resolver, persistence middleware, compiled-graph
cache key - the flag must rotate cached graphs or a flipped workspace
would keep serving its pre-flip graph). The recorder and the disconnect
safety-net check per call; the janitor stays global, pruning is
workspace-agnostic.
2026-07-29 20:17:36 +02:00
CREDO23
58d5d596c6 knowledge_store: per-workspace flip flag behind the global kill switch
workspaces.knowledge_store_enabled (migration 175, default false) makes
the git-native rollout progressive: flip one workspace, watch it live,
continue. knowledge_store_enabled_for(workspace_id) owns the verdict -
global master switch read live (disaster lever acts immediately) AND the
workspace row, cached 30s per process.
2026-07-29 20:17:36 +02:00
Anish Sarkar
ffb2bf7fd9 test: add unit tests for to_store_path function in path_resolver 2026-07-29 23:45:14 +05:30
Anish Sarkar
7c100c5e44 refactor: use to_store_path function for storing document revisions 2026-07-29 23:44:59 +05:30
Anish Sarkar
7f33015b63 path_resolver: add to_store_path function to convert virtual paths to repo paths 2026-07-29 23:44:43 +05:30
CREDO23
05a4846515 migration: fleet runner - dry-run-first, resumable, JSONL reports
Loops workspaces through migrate_workspace with a fresh session each so
one failure cannot poison the pass; every report lands in an append-only
JSONL audit file. Dry run by default (--yes to seed), exits non-zero if
any workspace is not ok. Verified against the dev database: the piloted
workspace reports parity ok.
2026-07-29 18:32:02 +02:00
CREDO23
3cdf93f513 plan: documents/ root is deliberate - reserves top level for sibling roots
Ratified: the root stays so future trees (.cache/, artifacts/) can live
beside documents/ without ever moving existing paths.
2026-07-29 18:18:25 +02:00
CREDO23
3b9f00f1be plan: C1 layout keeps the documents/ root, as shipped
The Phase-3 recorder and Phase-5 seeder both record full virtual paths
(documents/...); the local pilot seed confirmed both sides agree. Amend
C1 so the contract describes what actually ships.
2026-07-29 18:11:13 +02:00
CREDO23
3ad609a0aa migration: phase 5 seeder - convergent seed, byte parity, contained failures
migrate_workspace maps documents through the live path rules and records
one migration-authored seed revision; re-seeding converges (orphans of
Postgres deletions are removed) so seed -> catch-up -> flip is safe.
Parity compares content addresses, no file reads. Neither entry point
raises: any failure lands in MigrationReport.error, so one broken
workspace cannot abort a fleet run.
2026-07-29 17:59:55 +02:00
CREDO23
ed15cf43ab knowledge_store: expired write-lock hold fails loudly
Release suppressed every LockError, so a hold that outlived the TTL -
exclusivity silently lost mid-write - left no trace. Expiry now raises
KnowledgeStoreLockError after a clean write; an error from the write
itself still wins and is never masked.
2026-07-29 17:59:55 +02:00
CREDO23
7b90099cda knowledge_store: batch index staging, per-file adds were O(n^2)
porcelain.add rewrites the whole index per call, so staging an n-file
revision cost n index rewrites - a 2000-doc seed took 53s and would
outlive the 30s write-lock TTL. One batched add/remove per revision
makes recording linear: the same seed now lands in 0.6s.
2026-07-29 17:59:55 +02:00
CREDO23
dda2560aea plan: migration adopts the index, spans converge lazily (C2/C5/C7)
Phase 5 redesigned after the 21-day-backfill lesson: seed commit +
byte parity replaces the reindex gate, and the seed revision is
adopted by the indexer, never incrementally indexed (new C7).

C2 amended: start_line/end_line stored at cut time for new chunks
(nullable, instant ALTER, no migration backfill); legacy chunks cite
at document level, enforced by a fail-closed normalizer strip; a
deadline-free daily fill job converges them most-used-first, matching
against the git blob all-or-nothing so no path yields wrong numbers.

C5 corrected: the embedding cache exists (indexing_pipeline/cache,
2026-06-12) and is the content-id reuse layer - extend it, never warm
it from legacy rows.
2026-07-29 16:39:49 +02:00
CREDO23
7cb82010fd plan: phase 3 complete - connector sync shipped via pipeline choke point 2026-07-29 14:57:21 +02:00
CREDO23
fb11c10924 indexing: record connector syncs at the prepare_for_indexing choke point
Every indexer converges there, so recording happens the moment markdown
becomes durable - one revision per sync batch, never blocked by later
chunking/embedding failures. Supersedes the per-upload recorder call.
2026-07-29 14:57:21 +02:00
CREDO23
b5ce9aeff6 documents: generalize revision recorder to batched markdown writes
record_markdown_files records many paths as one transaction; a save is
now a batch of one, and record_prepared_documents maps a sync batch to
a single revision. Unchanged content stays a natural no-op.
2026-07-29 14:57:13 +02:00
CREDO23
4c70728c37 plan: sync phases 2-4 status with shipped phase 3 2026-07-29 14:35:39 +02:00
CREDO23
058c3394ab knowledge_store: daily janitor prunes abandoned working copies 2026-07-28 22:05:07 +02:00
CREDO23
6db282aa61 documents: editor saves and upload markdown record store revisions 2026-07-28 22:05:07 +02:00
CREDO23
7050a6ea99 streaming: git-native safety-net commit on client disconnect 2026-07-28 22:05:07 +02:00
CREDO23
9f6cf82ebf middleware: wire knowledge store persistence into the main-agent stack 2026-07-28 22:05:07 +02:00
CREDO23
1dac877828 middleware: knowledge store persistence hook behind the flag 2026-07-28 22:05:07 +02:00
CREDO23
64cafcc885 middleware: end-of-turn commit body records one revision per turn 2026-07-28 22:05:07 +02:00
CREDO23
e4c0bd0733 middleware: model-generated commit subjects with deterministic fallback 2026-07-28 22:04:52 +02:00
CREDO23
0c863032cb middleware: single thread-to-working-copy-id convention 2026-07-28 22:04:52 +02:00
CREDO23
7d9e4759c6 knowledge_store: authorship conventions for recorded revisions 2026-07-28 22:04:52 +02:00
CREDO23
cca2b9480a knowledge_store: committer parameter on record and transaction 2026-07-28 22:04:52 +02:00
CREDO23
aa27c2fb47 plan: align phase 4 with transaction vocabulary and cut-time deletion 2026-07-28 21:26:36 +02:00
CREDO23
d399870dce plan: lock phase 3 commit path decisions 2026-07-28 21:25:22 +02:00
CREDO23
af40ba22a3 plans: system diagrams, engine vocabulary, and phase 2 status 2026-07-28 20:44:05 +02:00