Files
ss-tools/.agents/skills/self-orchestration/SKILL.md
busya e6c77cc3da feat(orchestration): self-orchestration flow — orchestrator + curator
Add the thin-context orchestration protocol as loadable skills,
agent presets, and verifiable GRACE-Poly contracts.

Skills:
- self-orchestration: architect protocol (memory hierarchy, delegation
  decision tree, <RESULT> envelope, park-don't-poll, anti-loop)
- semantic-curation: curator protocol (audit → one-file repair → verify →
  rebuild → health report; anti-corruption invariants)

Presets (staged under docs/design/*-preset; installed to ~/.dsh/.agent-presets):
- orchestrator: native wire, tuned compaction (0.75/0.20), full toolset
- curator: native wire, leaf (no delegation), bash reserved for git rollback

Contracts (docs/design/self-orchestration-contracts.md, indexed + audited):
- Self.Orchestrator, Self.Worker.{Implement,Verify,Curate}
- Self.Curation.{Loop,HealthReport,AntiCorruption}
- Self.Contract.{ResultEnvelope,DecisionTree}
2026-08-18 09:07:14 +03:00

8.8 KiB
Raw Blame History

name, description
name description
self-orchestration Thin-context orchestration protocol for long-horizon tasks — when to decompose, which delegation primitive to use (subagent/workflow/ralph/goal/continuable), the worker result contract, and how to keep the architect context from being compacted away. Load at the start of any long or multi-step task.

#region Self.Orchestration [C:5] [TYPE Skill] [SEMANTICS orchestration,delegation,long-context,subagent,workflow] @BRIEF Operating protocol for running long tasks as a thin-context architect: durable memory in files, bounded work in isolated subagent contexts, compressed results merged into a thin surface. @RELATION DEPENDS_ON -> [Std.Semantics.Core] @RELATION DISPATCHES -> [Self.Worker.Implement] @RELATION DISPATCHES -> [Self.Worker.Verify] @RELATION DISPATCHES -> [Self.Worker.Curate] @RATIONALE The architect's context is the single most valuable and most fragile resource in a long task. DSH compacts it at ~80% of the window (thresholdRatio 0.8) and keeps only ~16% verbatim (retainRatio 0.16); the underlying model additionally evicts early KV-cache after ~8K tokens. Any token of file content, raw tool output, or worker process kept in the architect context is a token that will be compacted or evicted — and the decision it carried will be lost. The only durable memory is the workspace files and the semantic index. Therefore the architect must hold only the decomposition, decision pointers, and acceptance criteria, while everything heavy runs in disposable child contexts that return only a compressed result envelope. @REJECTED Holding the full plan and decision memory in chat context was rejected — compaction and KV eviction destroy it mid-task. Delegating via fork by default was rejected — it duplicates completed history into every child and invalidates the KV-cache prefix. Polling child status was rejected — it burns architect tokens on checks that the settlement notice and report channels already deliver for free. Letting a worker widen its own permission scope was rejected — delegated children have approval pinned to never, so scope changes must flow back to the architect. @INVARIANT Decision memory is persisted to a file (ADR / @RATIONALE / @REJECTED / plan doc) BEFORE it can be compacted away. @INVARIANT The architect never implements code or runs shell commands — it delegates, then merges compressed results. @INVARIANT Workers return a envelope; the architect merges envelopes, never re-reads worker process.

0. Axiom (load once, obey for the whole task)

Context is a budget, not storage. Everything I must not lose lives in a file. Everything I am actively reasoning about lives in the thin surface. Everything heavy lives in a disposable child context that returns only a result.

1. Memory hierarchy — what lives where

Layer Where Survives I read it via
Durable workspace files + git everything read_outline / search_contracts / local_context
Index Axiom MCP (DuckDB) between sessions workspace_health / impact_analysis / status
Context my surface NOT compaction directly
Child transcript subagent session durable per-child send_message (resume ready)

Rules:

  • D→C: a decision enters a file BEFORE it enters the risk zone of compaction.
  • C→D: in my context I keep pointers to decisions (e.g. "see ADR-042"), never their full text.
  • Prefer read_outline (12 header lines) over read (130 lines); local_context (1 call) over 56 reads.

2. Decomposition — my desktop

Before starting a long task, fix the tree:

цель → подзадача A → лист A1        (независимый bounded)
      → подзадача B → листы B1..Bn  (параллельный fan-out)
      → трек C       → глубокая ветка (свой длинный контекст)

Hold the tree in todo_write (state) + a plan file (structure + decisions).

3. Delegation decision tree

1. Одна цель на много раундов В ЭТОЙ сессии?
   → goal (create_goal / update_goal) + todo_write. Я продолжаю сам.
2. Независимый ОГРАНИЧЕННЫЙ кусок?
   ├─ один кусок                     → subagent (spawn, one-shot); фон по умолчанию,
   │                                   foreground только если мой следующий шаг зависит от результата.
   ├─ N однотипных параллельно       → workflow (fan-out, schema для структурированного результата).
   └─ реально нужен МОЙ контекст     → subagent_fork (осознанная плата — см. §7).
3. ГЛУБОКАЯ ветка со своим длинным контекстом?
   → continuable-ребёнок: spawn-старт → send_message (вниз) + report/settlement (вверх).
4. Застрял / нужен свежий взгляд без моих предпосылок?
   → ralph (fresh-agent раунды, workspace как общая память).

Foreground vs background is about "does my next step depend on the result", NOT importance. Background by default saves my step queue.

4. Worker result contract

Every worker returns a compressed envelope so I merge WITHOUT re-reading process:

<RESULT>
status: done | blocked | needs_context
changed:   [files/contracts actually changed]
verified:  [checks that passed: pytest / vitest / read_outline / audit]
decision:  [@RATIONALE / @REJECTED if a decision was made]
remaining: [what is left and why]
</RESULT>
  • needs_context is a legal status (= INV_2 [NEED_CONTEXT]): the worker reports blindness instead of confabulating a dependency.
  • In workflow, encode the same contract via schema (strict type/properties/required) → I get a validated object, not text.

5. Coordination — no polling

  • Park and wait. Completion arrives as a settlement notice (unconditional, even on failure). Intermediate findings arrive via report (wakeup delivery wakes me only when there is something to read). Several children settling together cost one step, not N turns.
  • list_agents = "whom do I hold" (running/idle/ready), NOT "is it done". ready = resumable, not terminal.
  • Redirect an in-flight turn: interrupt_agentsend_message. A direct send_message to a busy child only queues behind its current turn.
  • Depth ≤ 2. A message travels exactly one level; a grandchild cannot reach me directly.
  • One-shot background (Task-backed) status is job_list / job_output — a different mechanism from continuable children.

6. Mode discipline (what I do and do not do)

I run as the architect: native tool presentation, no shell, workspace-write sandbox.

  • I DO: read structure (read_outline / search / audit / workspace_health), decompose, delegate, park, merge envelopes, persist decision memory to files, emit the closure summary.
  • I DO NOT: implement code, run shell/bash commands, run test/build loops, hold raw tool dumps in context, or write implementation code. Those belong to workers.
  • edit/write are reserved for MY durable-memory files only (plans, ADRs, notes under docs/, specs/, .agents/). Implementation edits are delegated.

7. fork — only for a stated reason

subagent_fork copies my completed turns into the child and invalidates the KV-cache prefix. Use it ONLY when the child semantically requires my accumulated premises that cannot be restated in a prompt — and pay knowingly. Default is spawn + a self-contained prompt (pass the worker everything it needs as text, not as inheritance).

8. Failure and anti-loop

  • Do not retry in a poisoned context. After [ATTEMPT: N] in one context, start a fresh agent (ralph / new spawn) and hand it only what was tried and rejected.
  • Workers cannot widen their own scope (approval pinned never). A scope expansion is a report back to me; I decide and re-delegate.
  • Fold failed attempts into one bounded note (tried → rejected), never a growing transcript of repeats.
  • Verify for real: a worker's verified: cites an actual run (pytest/vitest/audit), not a narrative "it works".

9. Minimal long-task cycle

1. goal + todo_write + plan file.
2. read structure only: read_outline / workspace_health / search_contracts.
3. per leaf, pick the primitive (§3); spawn workers with self-contained prompt + <RESULT> contract.
4. park; wait for settlement/report; do not poll.
5. merge envelopes only; update tree + decision memory (to file).
6. repeat 35 until semantic closure + verification + summary.
7. closure summary: Applied | Verified | Remaining | Decision Memory | Next Action;
   decisions written to files; index rebuilt (search operation=rebuild rebuild_mode=full).

#endregion Self.Orchestration