Skip to content

feat: add ataegina up --wait[=SECONDS] (readiness contract)#28

Merged
noahhyden merged 1 commit into
mainfrom
feat/up-wait
Jul 19, 2026
Merged

feat: add ataegina up --wait[=SECONDS] (readiness contract)#28
noahhyden merged 1 commit into
mainfrom
feat/up-wait

Conversation

@noahhyden

Copy link
Copy Markdown
Owner

What & why

Second of five agent-native additions (docs/design/agent-native.md). up already reported readiness (best-effort, always exit 0). --wait turns that into a contract:

  • Blocks until every server this invocation launched is accepting TCP connections, up to SECONDS (default 60, or ATE_UP_WAIT).
  • Exits 75 if any launched server isn't ready by the deadline; 0 when everything launched is ready (or nothing was launched).
  • Lets an agent gate cleanly: ataegina up --wait && curl "$BACKEND_URL/health" — no hand-rolled poll loop, no race against a not-yet-bound port.
  • Without the flag, up is unchanged (fire-and-forget report). restart --wait propagates the same exit code.

A non-integer --wait value is rejected up front (exit 2) — mutation testing showed that without the guard a bad value spins forever in the poll loop.

Discipline

  • Spec: docs/design/agent-native.md.
  • Tests-first: tests/up_wait.bats — 10 hermetic tests. Not-ready path under ATE_PORT_TOOL=none (no lingering process); ready path via a fake ss reporting the derived port LISTEN (no real socket); --wait=0, --scope none, ATE_UP_WAIT, arg validation (non-integer + negative), restart propagation, completion.
  • Live verification: drove the real binary with a real python backend that binds its derived port (→ ready, exit 0), a real backend that never binds (→ NOT ready, exit 75), and confirmed up --wait && … short-circuits on failure.
  • Mutation red-teaming: failure-returns-0 → caught (4 tests); remove-validation → caught (proven load-bearing via infinite-loop hang); drop-explicit-exit → behavior-equivalent under set -euo pipefail, exit codes independently live-verified.
  • Docs: README command table + env table, man page (command + ATE_UP_WAIT in ENVIRONMENT), CHANGELOG, bash+zsh completion.
  • Checksum regenerated. No new dependencies.

🤖 Generated with Claude Code

Turn `up`'s best-effort readiness report into a contract an agent can gate
on. With --wait, up blocks until every server it launched is accepting TCP
connections (up to SECONDS, default 60 or ATE_UP_WAIT) and exits 75 if any
is not ready by the deadline, so `ataegina up --wait && curl "$BACKEND_URL"`
works with no hand-rolled poll loop and no race against a not-yet-bound
port. Without the flag, up is unchanged (fire-and-forget, always exit 0).

New ate_wait_ready is strict and terse (poll-until-listening-or-timeout);
the rich crash-vs-slow diagnostic stays on the non-wait path. The up/restart
dispatch now captures cmd_up's exit code explicitly and still runs the
throttled version check. A non-integer --wait value is rejected up front
(exit 2) — without that guard a bad value spins forever in the poll loop.

Spec: docs/design/agent-native.md. Completion (bash+zsh), man page (+ the
ATE_UP_WAIT env var), README, and CHANGELOG updated. New hermetic suite
tests/up_wait.bats (10 tests): the not-ready path under ATE_PORT_TOOL=none,
the ready path via a fake `ss` reporting the port LISTEN, --wait=0, scope
none, ATE_UP_WAIT, arg validation, restart propagation, and completion.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@noahhyden
noahhyden merged commit 83cc1df into main Jul 19, 2026
8 checks passed
@noahhyden
noahhyden deleted the feat/up-wait branch July 19, 2026 23:37
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