Skip to content

feat(orchestrator): Layer 1 deterministic per-turn progress signals (IDE-211) - #72

Open
mattias-ident wants to merge 1 commit into
mainfrom
mattias/ide-211-layer-1-deterministic-per-turn-progress-signals-ide-189
Open

feat(orchestrator): Layer 1 deterministic per-turn progress signals (IDE-211)#72
mattias-ident wants to merge 1 commit into
mainfrom
mattias/ide-211-layer-1-deterministic-per-turn-progress-signals-ide-189

Conversation

@mattias-ident

Copy link
Copy Markdown

Context

Layer 0 (IDE-210) can act on budget pressure but Symphony cannot yet tell, cheaply, whether a running issue is actually progressing. Layer 1 fills that gap with deterministic per-turn signals.

TL;DR

Per-turn git-derived progress signals that classify a running issue as progressing/stuck/oscillating/repeated-error — report-only.

Summary

  • New SymphonyElixir.ProgressSignal: pure classifier rolling per-issue streaks into one status plus an independent at_risk_no_commits flag.
  • New Git.working_tree_probe/4: one read-only sh probe (fingerprint + empty-tree bit + commits-since-dispatch) off the agent's critical path.
  • :stuck_state is empty-tree-gated, so a dirty-but-identical tree stays :progressing (fixes the IDE-189 misclassification).
  • Orchestrator assesses once per turn boundary, surfaces it via snapshot/0 + a per-turn log line; trigger?/2 is the Layer-2 hand-off.
  • Report-only: no session kills, Linear state moves, or continuation gating. Four agent.progress_signal_* knobs added.

Alternatives

  • Treating "identical fingerprint K turns" as stuck regardless of tree state — rejected: misclassifies in-progress dirty trees (the IDE-189 case).
  • Hashing untracked-file content — out of scope; matches the chosen porcelain+diff tree-hash method (documented gap).

Test Plan

  • make -C elixir all
  • mix test progress_signal_test.exs git_test.exs orchestrator_progress_signal_test.exs (30 tests, incl. IDE-189 replay regression)

…IDE-211)

Compute cheap, deterministic progress signals once per turn boundary: a
read-only git probe yields a working-tree fingerprint, empty-tree bit, and
commits-since-dispatch, which SymphonyElixir.ProgressSignal rolls into per-issue
streaks and classifies into one status (:progressing / :stuck_state /
:oscillating / :repeated_error) plus an independent at_risk_no_commits flag.

:stuck_state is gated on an empty working tree, so a dirty-but-identical tree
stays :progressing (the IDE-189 misclassification). Layer 1 only reports and
logs — no session kills, Linear state moves, or continuation gating. trigger?/2
exposes a single boolean for the future Layer-2 AI overseer; the assessment is
surfaced via Orchestrator.snapshot/0 and a per-turn log line.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@mattias-ident mattias-ident added the symphony Symphony orchestrator workflow / agent label Jun 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

symphony Symphony orchestrator workflow / agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant