Skip to content

Android: after a reset the self-claim uses the previous boot's PIN from latest.log (401 pin_invalid) — read <home>/claim_pin, the log is not a reliable source #49

Description

@emooreatx

Android (0.5.212): after a factory reset the setup self-claim uses the PREVIOUS boot's one-time PIN — captured from latest.log — and the node answers 401 auth.claim.pin_invalid, so the with-AI pass ends with the node unclaimed and announce refused 409 node is not owner-bound. Gate run https://github.com/CIRISAI/CIRISAgent/actions/runs/34272658734 (CIRISAgent release/2.11.0 @ 67404f6c0, ciris-server 0.5.203), android-logcat.txt, verbatim with timestamps:

20:29:04.380 python.stdout: Node fold: OWNERSHIP UNCLAIMED — one-time CLAIM PIN: D8NG-N3YE   (no-AI setup; claim OK)
…factory reset, app restarts…
20:31:05.107 PythonRuntime:  Captured one-time CLAIM PIN from node ownership banner.
20:31:06.111 MainActivity:   Ownership CLAIM PIN captured — stopping node-log tail
20:31:07.043 python.stdout: Node fold: OWNERSHIP UNCLAIMED — one-time CLAIM PIN: VP9G-E6X7   (this boot's PIN — printed AFTER the capture)
…the gate's with-AI --launch restarts the app…
20:32:04.594 PythonRuntime:  Captured one-time CLAIM PIN from node ownership banner.
20:32:05.859 MainActivity:   Ownership CLAIM PIN captured — stopping node-log tail
20:32:19.144 python.stdout: Node fold: OWNERSHIP UNCLAIMED — one-time CLAIM PIN: YY7A-B66Q   (this boot's PIN — 15 s after the capture)
20:32:56.373 CIRISApiClient: [claimRemote] POST http://127.0.0.1:4243/v1/setup/claim-remote node_code=CIRIS-V1-AHG6-7V7L-D… cohort=self owner_session=password
20:32:56.409 CIRISApiClient: [claimRemote] Exception: RuntimeException: status=401 Unauthorized body={"error":"claim-remote failed: target rejected the claim (HTTP 401): {\"error\":\"invalid one-time claim PIN\",\"reason_id\":\"auth.claim.pin_invalid\"}"}
20:32:56.420 SetupViewModel: [ORDER] claim_settled claimed=false (exception, session=setup): claim-remote failed: 401 …

Twice in a row the capture lands before the running node prints its banner: MainActivity.tailNodeLogsForOwnership lists latest.log (and siblings) sorted by lastModified and parses the first CLAIM PIN line it meets — after a restart that file still carries the previous boot's banner, _localClaimPin latches it (if (_localClaimPin.value == null)), the tail stops, and CIRISApp.kt's source order (1: banner snapshot, 2: <home>/claim_pin, 3: await banner) never reaches the file because a value is already there.

The PIN is in a file on disk; the log is not a reliable source for it. The node writes the current PIN to the durable <CIRIS_HOME>/claim_pin (0600, JSON {"pin": …}), names that path as claim_pin_file in its setup status, and rotates it per boot; the desktop and iOS runtimes already read it (readClaimPinFromFileIfMissing). Ask: on Android, read <home>/claim_pin at claim time (the node writes it a few seconds after health answers, so on demand at COMPLETE, not at boot) and stop latching a log-derived PIN ahead of it — or drop the log tail entirely on Android now that the file exists there too. A real user reproduces this with one reset + re-setup on a phone (the 20:31:05 capture is exactly that path).

Consequence in the same run: announce bundle: error -- announce returned 409: {"error":"announce (promote owner-binding) failed: owner-binding validation: node is not owner-bound — claim ownership before announcing …"}, i.e. the node was never claimed, so the with-AI setup ends 6/7.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions