Home / Projects / Orchestrata Ultimate / Decisions / ADR index / ADR-0104
ADR-0104: Git worktrees are not graph projects — orchkg holds one current, provenance-stamped copy per codebase
| field | value |
|---|---|
| Status | Accepted — Accepted — 2026-10-16, Mohamed: "do the cleanup now" (accepting recommendation D-1 of |
| Date | 2026-10-16 |
| Register | factory (docs/adr, 4-digit ids) |
| Source | docs/adr/0104-worktrees-are-not-graph-projects.md — recorded on branch architecture/domain-model at 1061f2d0a, not yet on master |
| Wiki register entry | ADR-0104 (wiki status: Accepted) |
The record
- Status: Accepted — 2026-10-16, Mohamed: "do the cleanup now" (accepting recommendation D-1 of
plans/kg-coverage-and-copies-plan.md) - Date: 2026-10-16
- Spec: graph coverage plan
plans/kg-coverage-and-copies-plan.md(6c1f9f60b; rulings recordedd545b980a)
Context
Measured 2026-10-16 on the test-fleet orchkg:
- 88% of the code nodes were worktree copies. About 545K of about 616K code nodes, in 14 projects. 11 of the projects
were
wt-*worktree copies of the same repo, plusorchestrata-ultimate-architecture, a second name for one worktree. - Copies never deduplicate. Every id is namespaced by project (
wt-X:module:…), so each sync run from a worktree wrote a full ~69K-node copy of the repo (~119K nodes with its Parameter nodes). - Nothing removed a copy when its worktree went. Two copies belonged to worktrees no longer on disk.
- The copies had no provenance. 13 of 14 Project nodes were bare
{id,name,slug}: no root path, commit, or sync time. - The canonical
orchestrata-ultimatewas itself stale. It had been synced from a branch ~528 commits behind master. - Meanwhile the code under active work was absent: the ADR-0103 component packages and the frozen source had 0 modules in the graph.
Every code query therefore had to filter by project or get seven answers. Workers could not use graph context for the code they were changing, and fell back to reading files.
Decision (Mohamed, 2026-10-16: "do the cleanup now")
A git worktree is not ingested into orchkg as its own code project. The graph holds one current copy per
codebase:
orchestrata-ultimate(master);orchestrata-components(the ADR-0103 component packages);orchestrata-frozen(the frozen source at its pinned commit);orchestrata.codetools.
Each Project node records root_path, commit and synced_at. Branch-local structure is served per worktree by that
worktree's AST daemon, not by the shared graph.
Alternatives rejected
- A branch overlay (
project+branch, changed modules only): correct, but it needs new sync code, and nothing queries branches today. - Keeping the per-worktree copies and filtering every query: an 88% node tax and seven-fold duplicate answers on any unfiltered query, with no way to tell a current copy from an orphan.
Consequences
- Executed 2026-10-16:
- The 12 copy projects were deleted with
kg_project_delete.py: 953,076 nodes including their project-less Parameter nodes, 0 left, orphan Parameters 0 → 0. orchestrata-ultimatewas re-synced from master ate57782ea4:verifyPASS with 3,452 modules (the serializer counted 3,453; the one-module gap is unexplained).- Components (352 modules) and frozen (913) were ingested with provenance.
- The 12 copy projects were deleted with
- Incident, same day. To re-sync
orchestrata-ultimate, the orchestrator ran the deleter on it WITHOUT a dry run. That project also tags non-code nodes, so 249 were deleted: 128 ArchitectureDecision, 46 Component, 66 Thread, 6 Constraint, 2 Artifact and 1 Architecture.- Restored from source: the architecture sync from master (
--adrs --repo-adrs: 76 repo ADRs, 0 body drift, 0 errors) brought ADR-0092..0102 back toOK in sync. - Not restored, by Mohamed's choice: the 66 Thread nodes, which are runtime data on the test fleet. The pre-delete
snapshots are preserved at
/home/mohamed/graph-recovery-20261016/; the orchkg database's is from 21:55 UTC. - The deleter now deletes code labels only, refuses a project holding any other label, and requires a dry run of
the same project set within the hour (
279751d6b).
- Restored from source: the architecture sync from master (
- Owed (plan steps):
- A1: name the command that wrote the
wt-*copies. - A2: a committed project registry that
GraphSyncerchecks, so a sync under an undeclared project id writes nothing. - D1/D2: every code query is project-scoped (
subgraph.py --project, plus a census of the existing readers). - C2/C3: incremental sync after component commits, and a dispatch pre-flight that refuses graph context for an absent or stale project.
- A1: name the command that wrote the
- Until A2 lands, a worktree sync can re-create a copy. The deleter removes it, and A1 identifies the writer.
Provenance
- Investigation and plan:
plans/kg-coverage-and-copies-plan.md(6c1f9f60b). Mohamed asked: "create a plan to fix the graph coverage gap and the queries to be filtered by project and investigate why there are identical copies". - Ruling: "do the cleanup now" (2026-10-16). Recorded the same turn in
d545b980a. When the execution was blocked by the permission classifier, Mohamed added: "I will not run anything you must run it not me". - Deleter:
wt-COMPONENTS/packages/design-scripts/dispatch/kg_project_delete.py(d48f054c8). Its dry run and apply logs show the 953,076-node footprint and the 0-left / 0-new-orphan verification.
Related ADRs
Rulings cited
None.
Specs cited
None (or no spec page exists for the ones named).