Rhizamonitor
live

Run

Deploy check on ship

done ship-change

Steps

  1. build/builddone1h 1m

    Nov 6 18:09 · 2 of 2 leaves passed

  2. build/renderdone5s

    Nov 6 18:09 · exit 0

  3. build/checkdone7s

    Nov 6 18:09 · exit 0

  4. review/codedone23s

    Nov 6 18:10 · exit 0

  5. review/reviewdone5m 57s

    Nov 6 18:16 · 5 of 5 checks passed

  6. review/renderdone8s

    Nov 6 18:16 · exit 0

  7. render-prdone3s

    Nov 6 18:16 · exit 0

  8. open-prdone9s

    Nov 6 18:16 · exit 0

  9. wait-prdone6m 45s

    Nov 6 18:23 · held after 14 checks

  10. pr-greendone1s

    Nov 6 18:23 · exit 0

  11. signoffdone0s

    Nov 6 18:23 · approved by rule autonomous

  12. rebasedone12s

    Nov 6 18:23 · exit 0

  13. wait-rebaseddone5m 48s

    Nov 6 18:29 · held after 12 checks

  14. rebased-greendone1s

    Nov 6 18:29 · exit 0

  15. landdone32s

    Nov 6 18:29 · exit 0

  16. wait-landeddone5m 15s

    Nov 6 18:35 · held after 11 checks

  17. landed-greendone1s

    Nov 6 18:35 · exit 0

  18. rebase-mergedone4s

    Nov 6 18:35 · exit 0

  19. wait-rebased-mergedone1s

    Nov 6 18:35 · held after 1 checks

  20. rebased-merge-greendone1s

    Nov 6 18:35 · exit 0

  21. mergedone7s

    Nov 6 18:35 · exit 0

  22. wait-maindone2s

    Nov 6 18:35 · held after 1 checks

  23. main-greendone2s

    Nov 6 18:35 · exit 0

  24. close-outdone12s

    Nov 6 18:35 · exit 0

  25. shipdone35s

    Nov 6 18:36 · exit 0

Review

compliance passed

  • minor Acceptance says the testscript gets exit 2 for a bad URL or timeout; the script uses `! exec`, which accepts any non-zero exit. The binary does exit 2 (checked by hand on a scratch build), so behaviour meets acceptance, but the script would not catch a regression to exit 1. cmd/rhiza/testdata/script/ship-deploy-settings.txtar:25

quality passed

  • minor The loop stops as soon as one more interval would reach the deadline, so with the default 10s interval the last poll can come up to ~10s before deployTimeout ends; the check gives up slightly early instead of sleeping the remainder and polling once at the deadline. internal/api/ship_deploy.go:95
  • nit deployProbe closes the response body without draining it, so the keep-alive connection is not reused between polls; harmless at a 10s interval. internal/api/ship_deploy.go:118

qa passed

  • nit ship deploy --dry-run is refused with refuseShipDryRun's 'it runs git and gh', but the deploy check runs neither; it polls an HTTP URL. internal/api/ship_deploy.go:63
  • nit When the URL is unreachable the human line reads 'still answered Get "http://...": dial tcp ...: connection refused', since Last holds the raw error; 'answered' fits only HTTP statuses. internal/api/ship_deploy.go:58

scope passed

No findings.

model passed

  • nit The leaf says the deploy check runs 'after a ship-change run merges'; the code runs it as the last step after close-out and the repo's ship command, so a failing ship command skips it. Not wrong, but the statement could name the ship step as the point it follows. internal/workflow/builtin/ship-change.toml:181
  • nit The daemon-settings capability's statement lists the settings it covers (paused, max runs, minimum free disk, permission mode, autonomy) and now omits rhiza.ship.deployUrl and deployTimeout, which rhiza daemon settings lists and rhiza daemon set validates. The list was already missing the web and usage keys, so this is pre-existing drift the new leaf ship-deploy-settings covers in its own statement. internal/api/daemon_settings.go:92

Log

log · tail
- Workflow: ship-change
- Change set: 01M6J375CH04RMRS4NN372NCN2: Deploy check on ship
- Worktree: /home/rhiza/code/rhiza.deploy-check-on-ship
- Autonomous: yes
- Started: 2026-11-06T17:07:49Z

## Steps

- build/build (visit 1): pass, then build/render: 2 of 2 leaves passed
- build/render (visit 1): pass, then build/check: exit 0
- build/check (visit 1): pass, then review/code: exit 0
- review/code (visit 1): pass, then review/review: exit 0
- review/review (visit 1): pass, then review/render: 5 of 5 checks passed
- review/render (visit 1): pass, then render-pr: exit 0
- render-pr (visit 1): pass, then open-pr: exit 0
- open-pr (visit 1): pass, then wait-pr: exit 0
- wait-pr (visit 1): pass, then pr-green: held after 14 checks
- pr-green (visit 1): pass, then signoff: exit 0
- signoff (visit 1): pass, then rebase: approved by rule autonomous
- rebase (visit 1): pass, then wait-rebased: exit 0
- wait-rebased (visit 1): pass, then rebased-green: held after 12 checks
- rebased-green (visit 1): pass, then land: exit 0
- land (visit 1): pass, then wait-landed: exit 0
- wait-landed (visit 1): pass, then landed-green: held after 11 checks
- landed-green (visit 1): pass, then rebase-merge: exit 0
- rebase-merge (visit 1): pass, then wait-rebased-merge: exit 0
- wait-rebased-merge (visit 1): pass, then rebased-merge-green: held after 1 checks
- rebased-merge-green (visit 1): pass, then merge: exit 0
- merge (visit 1): pass, then wait-main: exit 0
- wait-main (visit 1): pass, then main-green: held after 1 checks
- main-green (visit 1): pass, then close-out: exit 0
- close-out (visit 1): pass, then ship: exit 0
- ship (visit 1): pass, then end: exit 0

## Leaves

- ship-deploy-settings (step build/build): passed: attempt 2: verifier passed
  - attempt 1 builder, session 84dd1f11-ef6e-41b9-9246-01a1b1d4e586: pass (said done)
  - attempt 1 verifier, session 08787c68-706f-4d6a-a769-01a1b1e16a13: fail (verifier found 1 problem(s))
  - attempt 2 builder, session acac7005-2888-49f4-8b32-01a1b1efc16c: pass (said done)
  - attempt 2 verifier, session 410c2f37-6d08-4c96-be22-01a1b1f0e455: pass (Evidence written by the verifier)
  - attempt 1 finding f1: internal/api/daemon_settings.go is not gofmt-clean: `gofmt -l internal/api` lists it, because the new "net/url" import sits after "strconv" instead of sorted before "reflect". CI's make check runs fmt-check and would fail. Fix: run gofmt -w internal/api/daemon_settings.go. The behaviour itself is right: on a scratch build, `rhiza daemon set rhiza.ship.deployUrl ftp://x` and `rhiza daemon set rhiza.ship.deployTimeout soon` each exit 2 and print `next: rhiza daemon settings`.
- ship-deploy-check (step build/build): passed: attempt 2: verifier passed
  - attempt 1 builder, session 5da47b5e-20f1-4363-a6cc-01a1b1e1b663: pass (said done)
  - attempt 1 verifier, session d1ececb3-cc20-477c-9c33-01a1b1eae1cd: fail (verifier found 2 problem(s))
  - attempt 2 builder, session 8e626fd8-05f0-431f-aac5-01a1b1ec990d: pass (said done)
  - attempt 2 verifier, session b5c2adfd-82bd-4d07-b8ab-01a1b1ef9959: pass (Evidence written by the verifier)
  - attempt 1 finding f1: Acceptance asks for workflow tests where a fake health server answering 503, 503, then 200 ends the run done. At a5a10eeb only internal/api/ship_deploy_test.go TestShipDeployRecovers covers this, and it calls runShipDeploy directly and checks the response. No ship-change run (testscript or internal/api run test) points rhiza.ship.deployUrl at a fake server and checks that the run ends done after the deploy-check step polls. I checked with git show HEAD and grep -rl deploy cmd/rhiza/testdata/script internal. The only workflow-level coverage is run-ship-change*.txtar, where no URL is set.
  - attempt 1 finding f2: Acceptance asks that when the server answers 503 until the timeout, the run fails with the last status in its journal and in rhiza inbox. No test checks this. TestShipDeployTimesOut only checks the op response, its Human text and stderr. No test runs the ship-change workflow to deploy-check with a 503 server and then asserts that the run ends failed, that its journal's finished entry detail holds 'HTTP 503' and that rhiza inbox (--json or human) shows a failed item with that status. The plumbing looks right (stepRunner.Command tail goes to the detail, inbox uses failedDetail), but the acceptance requires a workflow test showing it.

## Checks

- compliance (step review/review): passed after 1 cycle
  - cycle 1: passed, check session 282bbd7e-202f-42db-aa0e-01a1b20df3d5 pass (said done)
  - round 1 (cycle 1): 1 finding, 0 confirmed
    - f1 minor at cmd/rhiza/testdata/script/ship-deploy-settings.txtar:25 on ship-deploy-settings: Acceptance says the testscript gets exit 2 for a bad URL or timeout; the script uses `! exec`, which accepts any non-zero exit. The binary does exit 2 (checked by hand on a scratch build), so behaviour meets acceptance, but the script would not catch a regression to exit 1.
- quality (step review/review): passed after 1 cycle
  - cycle 1: passed, check session d0220f91-0566-4f8f-8f7c-01a1b20e3cef pass (said done)
  - round 1 (cycle 1): 2 findings, 0 confirmed
    - f1 minor at internal/api/ship_deploy.go:95: The loop stops as soon as one more interval would reach the deadline, so with the default 10s interval the last poll can come up to ~10s before deployTimeout ends; the check gives up slightly early instead of sleeping the remainder and polling once at the deadline.
    - f2 nit at internal/api/ship_deploy.go:118: deployProbe closes the response body without draining it, so the keep-alive connection is not reused between polls; harmless at a 10s interval.
- qa (step review/review): passed after 1 cycle
  - cycle 1: passed, check session 4f092051-4950-4fed-a6d2-01a1b20eb4ff pass (said done)
  - round 1 (cycle 1): 2 findings, 0 confirmed
    - f1 nit at internal/api/ship_deploy.go:63 on ship-deploy-check: ship deploy --dry-run is refused with refuseShipDryRun's 'it runs git and gh', but the deploy check runs neither; it polls an HTTP URL.
    - f2 nit at internal/api/ship_deploy.go:58 on ship-deploy-check: When the URL is unreachable the human line reads 'still answered Get "http://...": dial tcp ...: connection refused', since Last holds the raw error; 'answered' fits only HTTP statuses.
- scope (step review/review): passed after 1 cycle
  - cycle 1: passed, check session 31163b1e-e87f-4297-90ab-01a1b20f1a81 pass (said done)
  - round 1 (cycle 1): no findings
- model (step review/review): passed after 1 cycle
  - cycle 1: passed, check session 734a067c-37ab-481e-a822-01a1b20fbd17 pass (said done)
  - round 1 (cycle 1): 2 findings, 0 confirmed
    - f1 nit at internal/workflow/builtin/ship-change.toml:181 on ship-deploy-check: The leaf says the deploy check runs 'after a ship-change run merges'; the code runs it as the last step after close-out and the repo's ship command, so a failing ship command skips it. Not wrong, but the statement could name the ship step as the point it follows.
    - f2 nit at internal/api/daemon_settings.go:92: The daemon-settings capability's statement lists the settings it covers (paused, max runs, minimum free disk, permission mode, autonomy) and now omits rhiza.ship.deployUrl and deployTimeout, which rhiza daemon settings lists and rhiza daemon set validates. The list was already missing the web and usage keys, so this is pre-existing drift the new leaf ship-deploy-settings covers in its own statement.

## Code checks

- step review/code: pass

## Sign-offs

- signoff (visit 1): approved by rule autonomous

## Sessions

- build/build, session 84dd1f11-ef6e-41b9-9246-01a1b1d4e586: tokens input 50, output 7023, cache creation 45080, cache read 1512535; helper tokens input 0, output 0, cache creation 0, cache read 0
- build/build, session 08787c68-706f-4d6a-a769-01a1b1e16a13: tokens input 18, output 3115, cache creation 29510, cache read 460284; helper tokens input 0, output 0, cache creation 0, cache read 0
- build/build, session 5da47b5e-20f1-4363-a6cc-01a1b1e1b663: tokens input 40, output 9983, cache creation 59360, cache read 1386316; helper tokens input 0, output 0, cache creation 0, cache read 0
- build/build, session d1ececb3-cc20-477c-9c33-01a1b1eae1cd: tokens input 24, output 3645, cache creation 37266, cache read 674049; helper tokens input 0, output 0, cache creation 0, cache read 0
- build/build, session 8e626fd8-05f0-431f-aac5-01a1b1ec990d: tokens input 34, output 11047, cache creation 59727, cache read 1230288; helper tokens input 0, output 0, cache creation 0, cache read 0
- build/build, session b5c2adfd-82bd-4d07-b8ab-01a1b1ef9959: tokens input 14, output 2720, cache creation 40577, cache read 386702; helper tokens input 0, output 0, cache creation 0, cache read 0
- build/build, session acac7005-2888-49f4-8b32-01a1b1efc16c: tokens input 16, output 1747, cache creation 24236, cache read 390037; helper tokens input 0, output 0, cache creation 0, cache read 0
- build/build, session 410c2f37-6d08-4c96-be22-01a1b1f0e455: tokens input 32, output 5759, cache creation 38753, cache read 882498; helper tokens input 0, output 0, cache creation 0, cache read 0
- review/review, session 282bbd7e-202f-42db-aa0e-01a1b20df3d5: tokens input 16, output 2695, cache creation 43423, cache read 472339; helper tokens input 0, output 0, cache creation 0, cache read 0
- review/review, session d0220f91-0566-4f8f-8f7c-01a1b20e3cef: tokens input 18, output 3373, cache creation 43370, cache read 527366; helper tokens input 0, output 0, cache creation 0, cache read 0
- review/review, session 4f092051-4950-4fed-a6d2-01a1b20eb4ff: tokens input 18, output 4880, cache creation 45333, cache read 534711; helper tokens input 0, output 0, cache creation 0, cache read 0
- review/review, session 31163b1e-e87f-4297-90ab-01a1b20f1a81: tokens input 14, output 1304, cache creation 40307, cache read 363136; helper tokens input 0, output 0, cache creation 0, cache read 0
- review/review, session 734a067c-37ab-481e-a822-01a1b20fbd17: tokens input 22, output 4018, cache creation 47914, cache read 682297; helper tokens input 0, output 0, cache creation 0, cache read 0

Totals: tokens input 316, output 61309, cache creation 554856, cache read 9502558; helper tokens input 0, output 0, cache creation 0, cache read 0