rollbridge 0.1.11 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/README.md +22 -2
  2. package/docs/cli.md +31 -0
  3. package/docs/config.md +22 -0
  4. package/package.json +1 -1
  5. package/src/cli.js +59 -1
  6. package/src/config.js +10 -1
  7. package/src/daemon.js +82 -28
  8. package/src/release-group.js +38 -2
  9. package/src/state-store.js +8 -0
  10. package/test/config-path.test.js +16 -1
  11. package/test/daemon-bootstrap.test.js +363 -0
  12. package/test/fixtures/dummy-app.js +24 -1
  13. package/test/rollbridge.test.js +92 -3
  14. package/tmp/worker-control/rollbridge-bootstrap/activity-3.jsonl +28 -0
  15. package/tmp/worker-control/rollbridge-bootstrap/current-head-review-activity.jsonl +13 -0
  16. package/tmp/worker-control/rollbridge-bootstrap/current-head-review-transcript.jsonl +1 -0
  17. package/tmp/worker-control/rollbridge-bootstrap/fs-probe-10.jsonl +1 -0
  18. package/tmp/worker-control/rollbridge-bootstrap/plan.md +9 -0
  19. package/tmp/worker-control/rollbridge-bootstrap/repair-activity.jsonl +3 -0
  20. package/tmp/worker-control/rollbridge-bootstrap/repair-fresh-activity.jsonl +25 -0
  21. package/tmp/worker-control/rollbridge-bootstrap/repair-fresh-transcript.jsonl +1 -0
  22. package/tmp/worker-control/rollbridge-bootstrap/repair-transcript.jsonl +1 -0
  23. package/tmp/worker-control/rollbridge-bootstrap/review-activity.jsonl +14 -0
  24. package/tmp/worker-control/rollbridge-bootstrap/review-transcript.jsonl +1 -0
  25. package/tmp/worker-control/rollbridge-bootstrap/terminal-repair-activity.jsonl +3 -0
  26. package/tmp/worker-control/rollbridge-bootstrap/terminal-repair-fresh-activity.jsonl +38 -0
  27. package/tmp/worker-control/rollbridge-bootstrap/terminal-repair-fresh-transcript.jsonl +1 -0
  28. package/tmp/worker-control/rollbridge-bootstrap/terminal-repair-transcript.jsonl +1 -0
  29. package/tmp/worker-control/rollbridge-bootstrap/transcript-2.jsonl +1 -0
  30. package/tmp/worker-control/rollbridge-bootstrap/transcript-3.jsonl +1 -0
  31. package/tmp/worker-control/rollbridge-bootstrap/transcript.jsonl +1 -0
@@ -0,0 +1,14 @@
1
+ {"type":"controller-started","pid":23,"at":1786619089604}
2
+ {"type":"provider-started","provider":"codex","pid":34,"at":1786619089609}
3
+ {"type":"session-available","provider":"codex","sessionId":"019ffacb-d3c0-7f93-affa-c472258a1b8b","at":1786619089955}
4
+ {"type":"activity","provider":"codex","kind":"lifecycle","at":1786619089955}
5
+ {"type":"activity","provider":"codex","kind":"tool","at":1786619096716}
6
+ {"type":"activity","provider":"codex","kind":"tool","at":1786619104649}
7
+ {"type":"activity","provider":"codex","kind":"tool","at":1786619110897}
8
+ {"type":"activity","provider":"codex","kind":"tool","at":1786619130819}
9
+ {"type":"activity","provider":"codex","kind":"delta","at":1786619140752}
10
+ {"type":"activity","provider":"codex","kind":"tool","at":1786619146978}
11
+ {"type":"activity","provider":"codex","kind":"tool","at":1786619159062}
12
+ {"type":"activity","provider":"codex","kind":"tool","at":1786619164311}
13
+ {"type":"activity","provider":"codex","kind":"delta","at":1786619179382}
14
+ {"type":"terminal","provider":"codex","state":"completed","exitCode":0,"at":1786619221045}
@@ -0,0 +1 @@
1
+ {"version":1,"type":"delegated_result","state":"completed","exitCode":0,"conclusion":"I’ll review the exact working-tree candidate read-only, first inventorying repository instructions and the complete diff, then tracing the affected daemon/deploy/state/recovery paths and targeted tests. I won’t modify anything or run the full suite.The candidate is small and localized, but its safety claims depend heavily on existing daemon startup and deploy cleanup behavior. I’m tracing those internals now, including persisted-state loading and signal/exit handling, and will run only focused tests relevant to this interface.Two lifecycle interactions warrant direct verification: interruption during a slow bootstrap, and what remains recoverable in `statePath` when live prior-daemon processes were only reported. I’m checking those against focused existing/new tests and source behavior; no repository files will be changed.- High — [src/cli.js](/home/dev/rollbridge/src/cli.js:42): SIGINT/SIGTERM handlers are installed only after `daemon.deploy()` completes at line 46. A service-manager stop or restart during process startup or a long health check therefore performs Node’s default termination instead of `daemon.shutdown()`. Managed children are detached ([src/managed-process.js](/home/dev/rollbridge/src/managed-process.js:86)), so they can survive while the proxy/control socket and state are left unclean. This contradicts the documented “normal signal behavior” and is not covered by the bootstrap tests.\n\n- High — [src/daemon.js](/home/dev/rollbridge/src/daemon.js:677): After prior-daemon processes are read into the in-memory orphan list, startup immediately persists a new snapshot that deliberately excludes those orphans (lines 691–700), overwriting their only durable PID records. A later clean shutdown also deletes `statePath` (lines 750–755). Thus a live prior-daemon process is not killed, but becomes unrecoverable through `rollbridge recover` once bootstrap starts—or immediately when failed activation invokes shutdown. The test at [test/daemon-bootstrap.test.js](/home/dev/rollbridge/test/daemon-bootstrap.test.js:108) checks only process liveness and in-memory status, never preservation of the persisted orphan records. This conflicts with the documentation that previous `statePath` entries remain advisory orphans.","continuationHandle":"019ffacb-d3c0-7f93-affa-c472258a1b8b"}
@@ -0,0 +1,3 @@
1
+ {"type":"controller-started","pid":23,"at":1786620029812}
2
+ {"type":"provider-started","provider":"codex","pid":34,"at":1786620029815}
3
+ {"type":"terminal","provider":"codex","state":"failed","exitCode":2,"at":1786620065194}
@@ -0,0 +1,38 @@
1
+ {"type":"controller-started","pid":23,"at":1786620086602}
2
+ {"type":"provider-started","provider":"codex","pid":34,"at":1786620086605}
3
+ {"type":"session-available","provider":"codex","sessionId":"019ffadb-09f5-7460-bcd7-0db1e74e9935","at":1786620086862}
4
+ {"type":"activity","provider":"codex","kind":"lifecycle","at":1786620086862}
5
+ {"type":"activity","provider":"codex","kind":"delta","at":1786620091884}
6
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620098162}
7
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620108101}
8
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620130450}
9
+ {"type":"activity","provider":"codex","kind":"delta","at":1786620181139}
10
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620214551}
11
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620233438}
12
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620296843}
13
+ {"type":"activity","provider":"codex","kind":"delta","at":1786620316811}
14
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620326537}
15
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620349522}
16
+ {"type":"activity","provider":"codex","kind":"delta","at":1786620369610}
17
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620386448}
18
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620401793}
19
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620419491}
20
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620428258}
21
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620467781}
22
+ {"type":"activity","provider":"codex","kind":"delta","at":1786620478524}
23
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620514191}
24
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620519855}
25
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620542628}
26
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620597146}
27
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620603744}
28
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620610390}
29
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620615895}
30
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620629789}
31
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620635487}
32
+ {"type":"activity","provider":"codex","kind":"delta","at":1786620645508}
33
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620651900}
34
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620657807}
35
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620663562}
36
+ {"type":"activity","provider":"codex","kind":"tool","at":1786620670250}
37
+ {"type":"activity","provider":"codex","kind":"delta","at":1786620682665}
38
+ {"type":"terminal","provider":"codex","state":"completed","exitCode":0,"at":1786620740752}
@@ -0,0 +1 @@
1
+ {"version":1,"type":"delegated_result","state":"completed","exitCode":0,"conclusion":"I’ll focus only on the SIGTERM/bootstrap lifecycle race, preserve the current candidate changes, and avoid commits, pushes, deploys, the full suite, and any independent review. I’ll first inspect the existing daemon lifecycle/tests, add a handshake-driven regression, and run it alone to capture the required RED before touching production code.The race boundary is in three sequential creation loops: daemon-wide services, release-owned process/replica startup, and singleton replacement. I’m adding the regression at the CLI boundary with the first service command explicitly recording a “shutdown trigger” event and sending SIGTERM to the daemon itself; later service/replica commands record their PIDs, and every managed child records graceful stop. This avoids health-wait timing and gives an event-ordered proof without sleeps or polling.The focused regression is now a genuine RED for the accepted race: after the shutdown event, both worker replicas start, the daemon exits with code 0, and neither replica records a graceful stop. I’m implementing the narrow coordination boundary now: shutdown will wait for already-admitted deploy ownership to settle, then perform a final ownership sweep; failed/interrupted deploy cleanup will also stop its release explicitly. Prior-daemon advisory orphans remain outside these owned collections.The first fix run exposed a test-handshake issue rather than a lifecycle result: the fixture’s “started” record was emitted before its SIGTERM handler was installed, so a correctly stopped child could die without writing the stop acknowledgment. I moved that readiness event to the server-listening callback. The rerun is still active, so I’m checking whether the FIFO release handshake itself is now blocked before changing any production logic further.The repaired regression is GREEN and now checks the exact two required properties for every post-shutdown-start PID: it appears in the daemon’s managed-process records, and it is no longer alive before the signal handler exits. The fix does not adopt or sweep persisted orphan PIDs; it waits only for deploy promises admitted by this daemon and re-sweeps only its service/singleton/release ownership maps. I’m running the focused bootstrap file, then the directly affected daemon/release lifecycle files only.The full focused bootstrap file revealed an important compatibility constraint: waiting for the entire deploy promise also waits out an existing 60-second health check, delaying SIGTERM shutdown. I’m narrowing the fix to cancellation at every creation boundary instead. Because JavaScript cannot interleave between the cancellation check and registering a new owned process, shutdown’s snapshot will either own the current start or the loop will abort before creating the next one; health waits may remain in flight, but cannot create anything afterward.All relevant focused files are passing: the bootstrap integration file, release-group unit file, and daemon lifecycle integration file. Normal deploy, replicas, services, singletons, failed startup cleanup, shutdown persistence, and prior-orphan reporting remain green. I’m running the requested static checks now, then I’ll inspect the exact diff and worktree status without any further review pass.`npm run lint` found one narrow JSDoc-only issue in the new handshake helper: this repository disallows `unknown` there and requires its `JsonValue` type. I’m correcting that annotation, then I’ll rerun the focused bootstrap file before repeating lint and the remaining requested checks.Implemented the terminal SIGTERM/bootstrap race repair without commit, push, deploy, full suite, or independent review.\n\nChanges:\n\n- Added cancellation checks before each service, release process/replica, and singleton creation boundary.\n- Registered in-progress releases as daemon-owned during bootstrap.\n- Interrupted deploy cleanup explicitly stops only its release and newly started services.\n- Prior-daemon advisory orphans remain untouched and recoverable.\n- Added a deterministic FIFO/event-handshake regression proving post-shutdown-start processes are recorded and dead before daemon exit.\n\nValidation:\n\n- Required RED confirmed: two worker replicas started after shutdown and survived unrecorded.\n- `node --test test/daemon-bootstrap.test.js` — 13 passed\n- `node --test test/release-group.test.js` — 3 passed\n- `node --test test/rollbridge.test.js` — 39 passed\n- `npm run lint` — passed\n- `npm run typecheck` — passed\n- `git diff --check` — passed\n\nThe first lint run found one test JSDoc type error; corrected and rerun successfully. Final status/diff inspected. Existing candidate changes and `tmp/` remain preserved and uncommitted.","continuationHandle":"019ffadb-09f5-7460-bcd7-0db1e74e9935"}
@@ -0,0 +1 @@
1
+ {"version":1,"type":"delegated_result","state":"failed","exitCode":2,"continuationHandle":"019ffad2-c71a-7522-9645-c45214c2ba90"}
@@ -0,0 +1 @@
1
+ {"version":1,"type":"delegated_result","state":"failed","exitCode":2}
@@ -0,0 +1 @@
1
+ {"version":1,"type":"delegated_result","state":"completed","exitCode":0,"conclusion":"I’ll inspect the repository guidance, daemon/CLI/control activation flow, and focused tests first. I’ll then create the feature branch and operational plan before making production edits, with the required RED test run recorded.The core path is clear: control-socket `deploy` already funnels through `RollbridgeDaemon.deploy()`, which owns service startup, release health, traffic switching, template refresh, singleton replacement, and failed-attempt cleanup. I’m narrowing the bootstrap work to CLI validation/orchestration around that same method, plus tests for early rejection, successful foreground activation, failure cleanup, and `statePath` orphan safety.I’ve created `feature/daemon-bootstrap-release` and written the scoped operational plan. The interface is intentionally all-or-nothing: bootstrap mode uses explicit `--config`, `--release-path`, `--release-id`, and `--revision`; it does not invoke orphan recovery or kill anything from persisted state. Next I’m adding the focused integration tests before touching production code.The first RED run failed before exercising the feature because dependencies are not installed (`ERR_MODULE_NOT_FOUND: commander`). I’m installing the locked dependencies, then I’ll rerun the same focused file to obtain a genuine missing-behavior RED before production edits.The focused bootstrap tests are now green after the minimal CLI orchestration change, including exact metadata activation, failed health-check cleanup/non-zero exit, and live orphan preservation. I’m adding the explicit plain-daemon regression case and documenting the new foreground interface; no changelog exists in this repository, so I’m following its README/CLI-reference convention.The focused file passes all eight assertions. The first lint run found only test-file style issues (four `no-useless-escape` errors plus JSDoc warnings); I’ve corrected those without changing behavior and am rerunning the focused test and required static checks.All required checks now pass. I’m doing the final diff/status audit for accidental generated or unrelated changes, confirming the branch and uncommitted state, and reviewing the bootstrap failure/shutdown path one last time against attempt ownership and orphan safety.Implemented on new branch `feature/daemon-bootstrap-release`; all changes remain uncommitted.\n\nKey changes:\n\n- Added all-or-nothing daemon bootstrap flags: `--config`, `--release-path`, `--release-id`, and `--revision`.\n- Validates inputs before listeners/processes start.\n- Uses the existing `RollbridgeDaemon.deploy()` activation path.\n- Emits structured bootstrap failure, cleans attempt-owned processes, and exits non-zero.\n- Preserves plain daemon behavior and does not kill `statePath` orphans.\n- Added focused integration coverage and updated README/CLI documentation.\n- Added the requested untracked [plan.md](/home/dev/rollbridge/tmp/worker-control/rollbridge-bootstrap/plan.md).\n\nValidation:\n\n- RED: `node --test test/daemon-bootstrap.test.js` — failed because daemon bootstrap options were unknown.\n- Final: `node --test test/daemon-bootstrap.test.js` — 10 passed, 0 failed.\n- `npm run lint` — passed.\n- `npm run typecheck` — passed.\n- `git diff --check` — passed.\n- Full test suite was not run, as requested.\n\nModified/untracked implementation files:\n\n- [src/cli.js](/home/dev/rollbridge/src/cli.js)\n- [test/daemon-bootstrap.test.js](/home/dev/rollbridge/test/daemon-bootstrap.test.js)\n- [README.md](/home/dev/rollbridge/README.md)\n- [docs/cli.md](/home/dev/rollbridge/docs/cli.md)\n\nNo commit, push, publish, deploy, or live-service modification was performed.","continuationHandle":"019ffac6-1176-7023-8f14-82bae745817f"}
@@ -0,0 +1 @@
1
+ {"version":1,"type":"delegated_result","state":"failed","exitCode":2}