Skip to content

docs(adr): 0036 daemon state is a SQLite database, and each owner keeps its own tables - #755

Merged
V3RON merged 7 commits into
mainfrom
feature/754-adr
Oct 20, 2026
Merged

V3RON merged 7 commits into
mainfrom
feature/754-adr

Conversation

@V3RON

@V3RON V3RON commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

ADR 0036 for #754: the daemon's state (registry, tokens, drained workers) moves into a per-daemon state.db with real columns. Each owner keeps its own tables, drivers included. Old JSON files, damage and newer versions refuse to start.

Accepted — not yet implemented, approved at the end of the #754 spec session (2026-10-20). It stays open at the bottom of the feature's stack and merges with its last task.

Part of #754.

Review

Spec review: 6 blocking, 6 fixed, 1 notes. Code review: skipped. Claims review: skipped.
Rounds: 2. Tokens: 22.5M.
Runs: 8. Cost USD: 3.0736. Agent seconds: 1185.
Assessment: complete

Written by an agent.

@V3RON

V3RON commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

Decision taken

The ADR's spec review (round 1) left four questions open. Each one is decided as the reviewed code in stack #782 already does it, except R5, where that code had a bug.

  • R1: does a replayed lease answer give the device as it was recorded or as it is now? Options: as recorded (what ADR 0019 §4 says), or as it is now. Taken: as it is now, as the code does (src/core/registry.test.ts:2754). 0036 now says it narrows 0019 §4. A user sees the device's current state in a replayed answer. Reverting this means a new column for the recorded device and a change to the registry code.
  • R4: which table holds the fake driver's data? Taken: one fake_device_data table for both platforms, picked by device.spec.platform (src/core/registry-rows.ts:291). Tests only; no user sees this.
  • R5: is state.db opened and migrated before or after the daemon takes its socket? Options: before (today's code; a newer binary started beside a running daemon migrates the live file and then fails), or after. Taken: after. The socket is claimed first, so a second daemon never touches a live daemon's state.db. The fix goes to feat(state): the worker's registry lives in state.db #775. Reverting it means swapping two startup steps back.
  • R6: what happens to component records on upgrade? They are lost, so simlock component remove refuses components installed before the upgrade. Taken: say so in 0036 and in docs/CLI.md's upgrade section (feat(state): the worker's registry lives in state.db #775). Migrating the records instead would be a new task.

Each of these is pending the maintainer.

Written by an agent.

@V3RON

V3RON commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

Review ledger

Runs: 8. Cost USD: 3.0736. Agent seconds: 1185.
Tokens input 194, output 48739, cache read 5251430, cache write 356897.
- review 1 reviewer: claude-sonnet-5-5 398 s $0.1501
- review 1 spec: claude-opus-5-5 360 s $2.0065
- fix 1 implementer: claude-sonnet-5-5 119 s $0.2318
- fix 1 implementer: claude-sonnet-5-5 39 s $0.0689
- review 2 reviewer: claude-sonnet-5-5 114 s $0.1104
- review 2 spec: claude-opus-5-5 73 s $0.3306
- fix 2 implementer: claude-sonnet-5-5 49 s $0.0862
- review fix-check reviewer: claude-sonnet-5-5 33 s $0.0891
Finding outcomes: {"fixed":6}. Classes: {"adr-index 1":1,"contradicts accepted ADR":1,"false statement in Supersedes":1,"incomplete consequence":1,"undecided ordering":1,"undecided question":1}.
{
"findings": [
{
"id": "R1",
"role": "spec",
"class": "contradicts accepted ADR",
"outcome": "fixed",
"path": "docs/internal/adr/0036-daemon-state-is-a-sqlite-database-whose-tables-each-owner-keeps.md",
"fix": "f3826507"
},
{
"id": "R2",
"role": "spec",
"class": "adr-index 1",
"outcome": "fixed",
"path": "docs/internal/adr/README.md",
"fix": "e53d39c3"
},
{
"id": "R3",
"role": "spec",
"class": "false statement in Supersedes",
"outcome": "fixed",
"path": "docs/internal/adr/0036-daemon-state-is-a-sqlite-database-whose-tables-each-owner-keeps.md",
"fix": "38fd1fb5"
},
{
"id": "R4",
"role": "spec",
"class": "undecided question",
"outcome": "fixed",
"path": "docs/internal/adr/0036-daemon-state-is-a-sqlite-database-whose-tables-each-owner-keeps.md",
"fix": "f3826507"
},
{
"id": "R5",
"role": "spec",
"class": "undecided ordering",
"outcome": "fixed",
"path": "docs/internal/adr/0036-daemon-state-is-a-sqlite-database-whose-tables-each-owner-keeps.md",
"fix": "e53d39c3"
},
{
"id": "R6",
"role": "spec",
"class": "incomplete consequence",
"outcome": "fixed",
"path": "docs/internal/adr/0036-daemon-state-is-a-sqlite-database-whose-tables-each-owner-keeps.md",
"fix": "f3826507"
}
]
}```

_Written by an agent._

@V3RON

V3RON commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

Review notes

Not blocking, not verified. Each is one reviewer's claim.

  • spec: docs/internal/adr/0036-daemon-state-is-a-sqlite-database-whose-tables-each-owner-keeps.md §5 the second line of the Order bullet is not reflowed after the edit.

Written by an agent.

@V3RON
V3RON marked this pull request as ready for review October 20, 2026 17:34
@V3RON
V3RON merged commit d9e8fa7 into main Oct 20, 2026
56 checks passed
@V3RON
V3RON deleted the feature/754-adr branch October 20, 2026 18:19
V3RON added a commit that referenced this pull request Oct 20, 2026
Closes #759

### Status

Implement: done (4/4, audit probed 4/4) Review: round 1 + fix-check
passed Hardware: n/a Gate: waiting for the stack
Next: gate the stack (#755 → #775 → #783 → #784 → #785 → #786)

## Done when

- [x] `pnpm test:changed` passes.
- [x] `rg -n "workers\.json" src docs --glob '!docs/internal/adr/**'`
finds only the gateway's old-file list, its test and the `docs/CLI.md`
upgrade section.

## Feature completion (#754)

- [x] A worker restarted with fake drivers keeps devices, leases,
requests, components and tokens: restart tests in #775
(`src/daemon/main.test.ts`), real tables in #783, tokens in #784.
- [x] A gateway restarted keeps tokens and drains: #784 (join token
across restart) and the e2e restart test here.
- [x] A renew changes one row with 1,000 requests stored: test in #775.
- [x] Refusals for each old file, a damaged or newer `state.db`, printed
by `simlock status` at once with exit 1: #775, #784, this PR, and #785's
e2e (`e2e/start-refusal.test.ts`).
- [x] `docs/CLI.md` upgrade and downgrade steps, no live JSON file
named: #775's section plus each PR's `rg` Done when line.

## Assumptions

none

## Review

Spec review: 0 blocking, 0 fixed, 0 notes. Code review: 2 blocking, 2
fixed, 0 notes. Claims review: 0 blocking, 0 fixed, 0 notes.
Rounds: 1. Tokens: 20.4M.
Runs: 9. Cost USD: 2.3576. Agent seconds: 1557.
Assessment: complete

*Written by an agent.*
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