Orchestrata Ultimate › Research › Hidden AST spawners
Hidden AST spawners and the editable-venv flip
| Question | Why did AST work run from a stale checkout, and why did the pre-push gate keep refusing with a message whose two paths were identical? |
| Method | A serialize capture (process tree plus parent systemd --user) taken 2026-10-22 23:38–23:44, three push logs, direct_url.json in each venv, and the config deploy's backup directory. Re-checked 2026-10-23 |
| Status | Partly acted on. The uv run --no-sync fix is committed locally as 8a2cb42ad but not pushed. The three deleted hooks were restored from backup. The spawners in sections 1 and 2 are open |
1. Three spawners nobody asked for
A Claude session starts AST work in the background without saying so. The capture found three such spawners.
ast-incremental-refresh.shruns on PostToolUse. It is both a plugin project-hook and a repo copy. On every edit it detaches two jobs undersystemd --user:/opt/orchestrata-tools/lib/ast_live_sync.py --once. This one is correct: it is the deployed tool.serialize --incremental, run with the primary checkout's.venv/bin/pythonandscripts/serialize_codebase_ast.py. That breaks the "use deployed tools" rule. The census recorded the primary checkout as 497 commits behind; counted against itsorigin/masterref on 2026-10-23, it is 1,102 behind. The capture at 23:38:47 was triggered by a codetools worker's edits inwt-CT-CODEMAP.
~/.venv/bin/ast-syncis the entry pointorchestrata_ultimate.tools.ast_pipeline:main.~/.venvholds an editable install of the primary checkout, which is a deploy-in-place. Itsdirect_url.jsonreads"url": "file:///home/mohamed/workspace/orchestrata-ultimate-architecture"with"editable": true(re-checked 2026-10-23). It ran--onceonwt-MAP-PRECOMMITat session start (23:43:58), withsystemd --useras its parent.start-architecture-sync.sh(SessionStart, lines 143 and 153) andscripts/hooks/pre-commit:166(ruffon each staged.py) call a plainuv run. That is the cause of section 2.
2. A plain uv run flips the venv to editable
Symptom. The pre-push gate refuses with "THE SUITE WOULD TEST THE WRONG SOURCE TREE", and the expected and actual source paths it prints are identical:
[source-provenance] ❌ THE SUITE WOULD TEST THE WRONG SOURCE TREE
[source-provenance] expected source : /home/mohamed/workspace/wt-MAP-PRECOMMIT/src
[source-provenance] actual source : /home/mohamed/workspace/wt-MAP-PRECOMMIT/src
Real cause. .venv/.../orchestrata_ultimate-*.dist-info/direct_url.json says "editable": true. A plain uv run re-syncs the project and installs it editable. The gate refuses an editable install of the repo under test, which is its job, but its message names the wrong problem. The flip was timestamped at session start, 23:43:43.
What it cost. The item-3 map push took four attempts (push-item3*.log):
| Attempt | Outcome | Cause |
|---|---|---|
| 1 | refused | Source-provenance gate. The venv had been flipped to editable |
| 2 | refused (96 s) | Source-provenance gate. PYTHONPATH=/opt/orchestrata-tools/shim from ~/.claude/settings.json was inherited |
| 3 | refused (222 s) | A real failure: test_hooks_pre_commit.py found the map hook did not create docs/. Fixed by a4cbc2bdf |
| 4 | pushed (349 s) | Bounded run green, source stamped as verified, 4ac0db570..a4cbc2bdf on master |
Fix. Commit 8a2cb42ad on feat/maps-via-codetools switches all three call sites, plus the plugin copy, to uv run --no-sync. The fix reaches sessions only after a push and a config deploy, and push approval has not been given. wt-MAP-PRECOMMIT's venv was non-editable on 2026-10-23.
Until it is deployed, before every push run:
env -u PYTHONPATH -u PYTEST_ADDOPTS uv sync --dev --no-editable --frozen
Then check direct_url.json. Never run a plain uv run in an orchestrata checkout; use .venv/bin/python or uv run --no-sync.
3. The config deploy deletes hand-installed hooks
On 2026-10-23 at 00:00, deploy/install-claude-config.sh --ref a4cbc2bdf ran rsync -a --delete from the repo's claude/hooks/ into ~/.claude/hooks/. It deleted three hooks that exist in no repo:
codemap_refresh.sh(SessionStart and SubagentStart);precommit_gate_subagent.sh(SubagentStop, the gate that blocks a worker untilprecommit-checkpasses);dispatch_ledger.py(SubagentStop, which writes the dispatch ledger).
The settings still registered them, so four hook registrations pointed at missing files. They were restored byte-identical from the backup that run took (~/.claude/.backup-20261023T000002/hooks), and both shell hooks passed pipe-tests. All three files were present on re-check. The installer keeps only the 3 most recent backups. The ~/bin launchers (precommit-check and the rest) sit outside the rsync and are safe.
Options and recommendation
| Problem | Options | Recommended |
|---|---|---|
| Editable flip | (a) Push and deploy 8a2cb42ad. (b) Also make the source-provenance message name direct_url.json when the paths match |
(a) now, then (b). This is not a ruling |
Stale serialize --incremental |
(a) Point the hook at /opt/orchestrata-tools. (b) Drop the job, because ast_live_sync --once already refreshes |
Not decided |
~/.venv editable ast-sync |
(a) Remove it and use the deployed tools. (b) Reinstall it non-editable from a pinned commit | Not decided |
| Hooks deleted by deploy | (a) Commit the three hooks to claude/hooks/ with their registrations, so the installer deploys them. (b) Keep restoring from backup after each deploy |
(a). It needs a worker and a push |