Skip to content

Slow lane: simlock token create sometimes runs without the admin credential after a daemon restart #609

Closed

Description

@V3RON

Seen twice on the slow lane while verifying PR #608, in two different tests of e2e/slow-agent-device.test.ts. Both times the failure came in setup, before any assertion:

Error: simlock token create failed: {"notice":"admin credential unavailable; connecting as agent (admin-only commands will fail with FORBIDDEN)"}
  • Run at 17:18 (log simlock-slow-e2e-20261015-171830.log): the test with agentDevice.command pointing at an agent-device that reports 0.9.2.
  • Run at 18:20 (log simlock-slow-e2e-20261015-182036.log): "with agentDevice.leaseTtlCapMs 20000, after a graceful simlock daemon restart an old simlock lease ... gets lease.expired".

Each test passes when run alone, and together with the test before it. It fails only in a full-file run, after many daemon restarts. token create ran as an agent because admin.token was missing at that moment. That points to a race in the e2e helpers (startDaemon / withConfig in e2e/helpers/env.ts) between a daemon restart and the admin credential being written. The code involved is the same on main.

Written by an agent.

Activity

  1. added
    bug:newReported. Nobody has looked yet.
    flaky-testNames a test that fails without a code change. Delivery skips its base-commit check.
    on Oct 15, 2026
  2. added
    bug:triageAn agent may reproduce it and write the triage report.
    and removed
    bug:newReported. Nobody has looked yet.
    on Oct 16, 2026
  3. self-assigned this
    on Oct 16, 2026
  4. V3RON commented on Oct 16, 2026

    @V3RON
    ContributorAuthor

    This was generated by AI during triage.

    Reproduction

    Confirmed a deterministic credential-deletion race without hardware. The slow-lane failure itself was not rerun.

    src/daemon/server.test.ts: “preserves the replacement daemon's admin credential when it starts as the old endpoint is released”. Two real endpoint hosts share credential storage. The replacement starts immediately after the old endpoint is released; its credential is verified before old shutdown resumes.

    pnpm exec vitest run --project unit src/daemon/server.test.ts -t 'preserves the replacement daemon'
    server.test.ts:982
    expect(filesystem.readFile("/admin.token")).resolves.toBe(replacementToken)
    AssertionError: promise rejected instead of resolving
    Caused by: ENOENT: no such file or directory, open '/admin.token'
    

    Reproduction: bug/609-repro, commit b92c940e (test only).

    Root cause

    Defect. src/daemon/server.ts:656–659 releases the endpoint through host.stop() before removing admin.token. A replacement can claim the released endpoint and persist its own credential while old shutdown is suspended; the old daemon then deletes the replacement's file. The helper's process-exit wait cannot guarantee protection: e2e/helpers/env.ts:288–301 tolerates its timeout, and its PID lookup returns an empty list when unavailable. This confirms a production race consistent with the report, beyond the helper's existence check.

    Simplest fix

    Remove the old credential before releasing the endpoint, keeping credential cleanup inside the endpoint ownership lifetime. Keep the reproduction as regression coverage.

    Alternatives rejected

    • Sleep longer in helpers: still schedule dependent and leaves production vulnerable.
    • Wait only for credential existence: another daemon can delete it afterwards.
    • Compare contents before deleting: a separate read/delete still races replacement.

    Risk

    • Preserve the losing-start instance's guarantee that it never touches the winner's credential.
    • Keep graceful shutdown and startup-failure paths covered.

    Written by an agent.

  5. removed their assignment
    on Oct 16, 2026
  6. added
    bug:readyAn agent may fix it.
    and removed
    bug:triageAn agent may reproduce it and write the triage report.
    on Oct 16, 2026
  7. self-assigned this
    on Oct 16, 2026
  8. added a commit that references this issue on Oct 16, 2026
  9. V3RON commented on Oct 16, 2026

    @V3RON
    ContributorAuthor

    Delivery run

    Merged: #625 (#609)
    Parked: none
    Waiting: none

    Written by an agent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bug:readyAn agent may fix it.flaky-testNames a test that fails without a code change. Delivery skips its base-commit check.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions