Orchestrata Ultimate › Plans › workflow-improvements-plan

Workflow Improvements Plan — From Memory Export 2026-07-26

Source: plans/workflow-improvements-plan.md at 8a2cb42ad · last changed 2026-08-13 · first committed 2026-07-26 · 369 lines.

Prose pending.

Plan text

Workflow Improvements Plan — From Memory Export 2026-07-26

Source: memory export of 2026-07-26 (global + 4 project memory stores, SESSION_START.md, global CLAUDE.md, 645-prompt Kimi user-history). The prompt history shows the same rules being re-issued verbally for months before they were mechanically enforced. This plan converts the recurring failure patterns into permanent, machine-checked workflow gates.

Conventions: every step has a deterministic verification. No step is "done" until its verification passes and its wiring site is named (Hard Rule 8: built is not done — wired is done). Execute in phase order; steps within a phase are parallelizable where marked.


Phase 0 — Canonical rulings store (foundation; everything else references it)

Problem (evidence): rulings live in 5+ places (global CLAUDE.md, project MEMORY.md ×4, SESSION_START.md, AGENTS.md) and were re-taught per agent tool. The prompt history shows no-xdist, no-mocks, Incus-not-Docker, and .env-only each re-issued >10 times before enforcement.

Decision: the wiki (Wiki.js 172.16.0.26:3000, wiki CLI on PATH) is the single source of truth for rulings. Tool-specific memory files keep tool-specific lessons only.

Read path rule: gates and hooks read rulings from the git-backed markdown files (~/workspace/knowledge-wiki/rulings/*.md — the wiki's disk storage writes into that repo), NEVER via wiki get. A live Wiki.js server must never be a dependency of run_tests.py, health_check.py, or session start — a wiki outage breaking the test gates is a false-red class. wiki get is for humans and liveness checks only.

Step 0.1 — Rulings schema + seed

Step 0.2 — Point every bootstrap at the canon

Step 0.3 — Ruling-registration protocol


Phase 1 — session prime: one bootstrap command

Problem (evidence): startup context is fragmented across AGENTS.md's manual startup protocol, SESSION_START.md, context.md, wiki, AST refresh, infra check. Prompt history: "refresh yourself", "why do I have to remind you", "when I start kimi in this folder I want you to know what to do".

Step 1.1 — Implement session prime

Step 1.2 — Wire into session start (both agent tools)


Phase 2 — Rulings enforcement lint (close the prose-only loophole)

Problem: a ruling with no mechanism gets violated again (proven repeatedly in the history).

Step 2.1 — scripts/rulings_lint.py

Step 2.2 — Wire the lint


Phase 3 — Affected-test selection (kill the 30-minute spin)

Problem (evidence): prompt history is full of "too long, max wait 2 minutes", "spinning for 30 mins not an option", "run only the part that fails". The AST toolkit already has who-imports, refs, call-graph, and serialize — the dependency data exists, it's just not wired to the runner.

Step 3.1 — scripts/affected_tests.py

Step 3.2 — Wire into the runner

Step 3.3 — Per-test duration tracking


Phase 4 — Status from artifacts, not hand-maintained files

Problem (evidence): memory entry "Tracking files are stale & contradictory" — plan files, session tasks, context.md, wiki all hold overlapping status.

Step 4.1 — scripts/project_status.py

Step 4.2 — Convention: intent vs state


Phase 5 — Prompt-history mining (quarterly drift catch)

Problem: corrections repeat across sessions; the export showed the pattern. Catch new ones early.

Step 5.1 — scripts/mine_prompt_history.py

Step 5.2 — Cadence (mechanical, not prose)


Phase 6 — Pre-merge conformance gate for delegated work

Problem (evidence): the Claude-delegation loop failed on scope violations and forbidden patterns in returned code ("you must let claude know which files it can change, and check for those only"). The scripts/factory_* pipeline (dispatch/enforce/conformance/dor_procedure) is the current delegation machinery — audit it first, close gaps second.

Step 6.1 — Audit the factory pipeline

Step 6.2 — Close the gaps

Step 6.3 — Inject rulings into delegation briefs (prevent, don't just reject)


Execution order & effort

Phase Depends on Effort Value
0 Rulings canon — 0.5 day foundation
1 session prime 0 0.5 day kills daily friction
2 rulings lint 0 0.5 day closes prose loophole
3 affected tests — 1 day biggest time saver
4 status from artifacts 1 0.5 day kills stale-status confusion
5 history mining 0 0.5 day drift early-warning
6 delegation gate — 1 day (audit 0.5) removes user from rejection loop

Phases 0–2 first (one session), then 3, then 6; 4–5 fill gaps.

Per-phase checkpoint rule: every phase ends COMMITTED (scoped commit naming the phase) with its verification output shown, before the next phase starts. A mid-plan interruption must never leave half-wired gates — Hard Rule 8 applied to the plan itself.

Definition of done (whole plan)

  1. Every step's verification command passes — shown, not asserted.
  2. python scripts/run_tests.py full suite green (authoritative, kernel verified).
  3. python scripts/rulings_lint.py exits 0; every RUL has a mechanism or explicit judgment mark.
  4. AGENTS.md updated for every convention change (per repo rule: keep AGENTS.md current).
  5. session end with artifacts, choices, handoff; CHANGELOG + tag per session protocol.

Phase 6 audit findings (2026-07-26)

Audited: scripts/factory_dispatch.py, scripts/factory_enforce.py, scripts/factory_conformance.py, scripts/factory_dor_procedure.py, and the factory/ package modules they front (factory/dispatch/gates.py, factory/enforcement/enforce.py, factory/conformance/engine.py, factory/scheduler/{dag,queue,scheduler,worktrees}.py).

(a) Is returned code diffed against the assigned file scope automatically? No, before this change. factory/dispatch/gates.py:224-258 (staleness_gate) runs git diff --name-only base..HEAD and rejects on overlap with declared paths, but it diffs trunk against the base commit to detect concurrent edits (ADR-0033 §7 dispatch staleness) — it never looks at the worker's own worktree changes. Nothing in factory/ compared a returned diff to TaskSpec.declared_paths (factory/scheduler/dag.py:53-57, the brief's own file-scope declaration). The pipeline's only per-entry admission hook, regate: Callable[[MergeEntry], RegateVerdict] (factory/scheduler/queue.py:92-99, invoked from MergeQueue.drain, queue.py:107-147), was wired in scripts/factory_pipeline.py:140-144 (pre-change) to _default_regate, which checked only store.facts_in(entry.lease.namespace) — the CLI's own docstring called this "intentionally MINIMAL" and said to "swap _default_regate for a real gate once that lane lands" (pre-change factory_pipeline.py:41-47). GAP.

(b) Does it run code-review.py + test-review.py before integration? No. grep -rl "code-review\|test-review" src/orchestrata_ultimate/factory/ scripts/factory_*.py returned zero hits before this change. The nearest neighbor, factory/conformance/engine.py (check_conformance, engine.py:485-533, fronted by scripts/factory_conformance.py), is a separate, unwired structural AST≡design checker — module/symbol/edge existence only, explicitly not lint/type/mock discipline (ADR-0008 boundary, engine.py:1-13) — and nothing in factory/scheduler/ or factory/dispatch/ calls it. GAP.

(c) Is failure auto-rejected back to the builder with the violation list, no human step? The ROUTING mechanism already existed and worked: RegateVerdict(passed=False, reason=...) (queue.py:39-58) → MergeQueue.drain records MergeOutcome(promoted=False, ...) and leaves the namespace untouched as a GC candidate (queue.py:124-130) → run_pipeline turns that into TaskReport(outcome="regate_rejected", ..., detail=outcome.verdict.reason) (factory/scheduler/scheduler.py:253-258) — already proven by tests/factory/test_merge_queue.py:: test_regate_fail_rejects_and_leaves_namespace_intact and tests/factory/test_scheduler_pipeline.py:: test_pipeline_regate_rejection_is_recorded_and_namespace_intact. Not a gap in the mechanism — the gap was that _default_regate (per (a)/(b)) never had a real violation to feed it.

Gaps closed (6.2): src/orchestrata_ultimate/factory/dispatch/ conformance_gate.py (new) adds scope_gate (worktree git diff + git ls-files --others vs declared_paths, reusing gates._path_overlaps) and review_gate (real code-review.py/test-review.py subprocesses on every changed .py file), composed by conformance_regate — a Callable[[MergeEntry], RegateVerdict] dropped straight into the EXISTING (c) routing, no parallel mechanism. RegateVerdict gained one additive, backward-compatible field, violations: tuple[str, ...] = () (factory/scheduler/queue.py), for machine-readable detail alongside the existing reason string. scripts/factory_pipeline.py's _default_regate now calls conformance_regate (closing the CLI's own "swap for a real gate" TODO). Verified end-to-end via three synthetic-dispatch tests in tests/factory/test_conformance_gate.py (real git worktrees, real Redis, real Neo4j, run through the real run_pipeline): an out-of-scope file is rejected naming it, zero human step; a unittest.mock import in a test_*.py file is rejected by the test-review gate; a conforming change promotes. factory/conformance/engine.py (B2 AST≡design) remains a deliberately separate, not-yet-wired lane per ADR-0008 — this phase did not wire it in, since (b)'s brief scoped the gap to the two named review tools.