Skip to content

feat(cli): async create with a wait option, and purge --wait to 404 - the sync fallbacks, client side - #36

Merged
cherusk merged 1 commit into
mainfrom
feat/async-create-wait
Oct 10, 2026
Merged

cherusk merged 1 commit into
mainfrom
feat/async-create-wait

Conversation

@godon-robot

@godon-robot godon-robot Bot commented Oct 10, 2026

Copy link
Copy Markdown
Contributor

What

Rung 3 of the async-create ladder (designs/2026-10-10-async-create-contract.md, approved). Companions: godon-controller#93, godon-images#354.

  • create — async default: prints the accepted row (status creating, UUID greppable), exit 0. --wait --timeout N (default 60): sends ?wait=active&timeout=N with a per-request client budget of N+30 (the server bound always expires first — a timeout answers a row, never a dangling connection). Exit 0 when the row reads active/running/finished; exit 3 with state + creation_reason when unmet (create-failed, or still creating at the bound — the executor runs on).
  • purge — the 202 now prints the truth ("deletion requested, poll to 404") instead of "deleted". --wait --timeout N polls GET until 404 — the deletion-done receipt; exit 0 on 404, exit 4 on timeout with the state (+ deletion_reason) on stderr. No server-side wait on DELETE, by design — this poll IS the sync-delete fallback with timeout.
  • 409 on a taken name (any state incl. creating/create-failed): exit 2, the existing row's message on stderr.
  • Default client timeout 30s → 90s. ApiResponse carries the HTTP status; Systemtender carries deletion_reason + creation_reason.

Exit-code map (plain words in --help, numbers for scripts): 0 met · 1 transport error (unchanged) · 2 name taken · 3 create unmet · 4 purge unmet.

Tests

cargo test → 9 passed (5 new): wait/timeout arg parse for create + purge, async-default + timeout 60 defaults, exit-code distinctness, create-wait state-verdict map.

Work note: this branch was built in a worktree (target/wt-async-create) cut from origin/main — the main checkout stays on feat/wish-update-delete, untouched.

Co-authored-by: cherusk 10729954+cherusk@users.noreply.github.com

… the sync fallbacks, client side

Rung 3 of the ladder (designs/2026-10-10-async-create-contract.md),
over the controller (#93) and api (#354) rungs:

- create: async default prints the accepted row (status `creating`,
  UUID greppable) and exits 0. --wait --timeout N (default 60) sends
  ?wait=active&timeout=N with a client budget of N+30 (the server
  bound expires first); exit 0 when the row is active/running/
  finished, exit 3 with state + creation_reason when the expectation
  is unmet (create-failed, or still creating at the bound).
- purge: the 202 now prints the truth (deletion requested, poll to
  404) instead of "deleted". --wait --timeout N polls GET until 404 -
  the deletion-done receipt; exit 0 on 404, exit 4 on timeout with
  the state (+ deletion_reason) on stderr.
- 409 on a taken name (any state, incl. creating/create-failed):
  exit 2, the server's row message on stderr.
- Exit codes are the contract: 0 met, 1 transport error (unchanged),
  2 name taken, 3 create unmet, 4 purge unmet - plain words in help,
  numbers for scripts.
- Default client timeout 30s -> 90s. ApiResponse now carries the HTTP
  status; Systemtender carries deletion_reason + creation_reason.

cargo test: 9 passed (5 new: wait/timeout arg parse for create and
purge, defaults, exit-code distinctness, state-verdict map).

Co-authored-by: cherusk <10729954+cherusk@users.noreply.github.com>
@cherusk
cherusk merged commit 49c16e3 into main Oct 10, 2026
1 check passed
@cherusk
cherusk deleted the feat/async-create-wait branch October 10, 2026 13:03
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