Skip to content

feat(ext-api): phase infinite-loop endpoint (issue #1291)#1302

Merged
zbnerd merged 15 commits into
developfrom
feature/issue-1291-loop-spec
Jun 18, 2026
Merged

feat(ext-api): phase infinite-loop endpoint (issue #1291)#1302
zbnerd merged 15 commits into
developfrom
feature/issue-1291-loop-spec

Conversation

@zbnerd

@zbnerd zbnerd commented Jun 18, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add POST /api/internal/loop/phase/{phaseName} and POST /api/internal/stop/loop/phase/{phaseName} to module-external-api
  • Each loop iteration gets a fresh runId; iterations share a loopId recorded on each RunStatus for /run-status correlation
  • Stop semantics reuse existing PhaseStopSignal; iteration halts at next chunk boundary
  • /trigger/daily and /trigger/phase/{name} reject 409 with LOOP_ACTIVE if a loop is active for the same phase
  • /run-status decorates response with loopSummaries map per active loop
  • Add @Volatile to LoopState mutable fields for cross-thread visibility
  • startLoop allocates a fresh loopId even if a previous loop is still in STOPPING (rapid stop→start)

Loopable phases

  • ITEM_EQUIPMENT, CHARACTER_BASIC (OCID_LOOKUP excluded: runOcidPhase requires upstreamRunId and would throw IllegalArgumentException on first iteration; RANKING_FETCH was already excluded)

Test plan

  • ./gradlew :module-external-api:test — all tests pass
  • ./gradlew :module-external-api:compileKotlin :module-external-api:compileJava --continue — clean
  • Manual smoke test: bootRun + curl -X POST /api/internal/loop/phase/ITEM_EQUIPMENT + observe /run-status for ≥10 min (deferred to reviewer per project rules, no smoke performed)

Spec

docs/superpowers/specs/2026-06-19-issue-1291-loop-endpoint-design.md

🤖 Generated with Claude Code

zbnerd and others added 15 commits June 18, 2026 09:37
Companion to issue #1290 (single-phase stop). Adds:
- POST /api/internal/loop/phase/{phaseName} (start continuous loop)
- POST /api/internal/stop/loop/phase/{phaseName} (halt loop)
- PhaseLoopController component + dedicated virtual-thread executor
- RunStatus.loopId field; trigger 409 on loop-active

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… shutdown

Tests do not compile yet — triggerPhase 4-arg overload added in next commit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nal preservation

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…topPhase loop warning

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ture

Loop ID is loopId=null for single-shot runs; pre-existing tests now match the
default-arg production call.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cross-thread visibility for status/iterationCount/lastRunId/lastError.
Concurrency invariant: handleIterationEnd is single-threaded per phase;
stopLoop/shutdown only write status. iterationCount += 1 safe by construction.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Documents the known race between startLoop and concurrent external one-shot.
Spec §11: no retry on iteration failure.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…PING

Allow rapid stop→start. Old iteration still finalizes out-of-band; new
iteration's acquire may briefly race, falling to the slot-conflict path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@zbnerd zbnerd merged commit bad9315 into develop Jun 18, 2026
@zbnerd zbnerd deleted the feature/issue-1291-loop-spec branch June 18, 2026 09:10
@zbnerd

zbnerd commented Jun 19, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant