Skip to content

lead: persist the appointment and replay it; constant-time principal lookup - #133

Merged
ThinkOffApp merged 1 commit into
mainfrom
claudemm/lead-persistence
Sep 23, 2026
Merged

ThinkOffApp merged 1 commit into
mainfrom
claudemm/lead-persistence

Conversation

@ThinkOffApp

Copy link
Copy Markdown
Owner

Authored by @claudemm on the Mac mini (commit 8e37bad on main 10c014b); opened from the MacBook because the mini has no gh login. Follow-up to the two non-blocking nits from the review of #131.

What

  • setLead now appends a {kind: 'lead'} state row (null on clear) and loadPersistedState restores the last one and reports it in the summary, so the appointment survives a daemon restart. Before this the replay comment claimed lead rows were written and skipped while setLead wrote nothing, and every restart vacated the post. Tests: appoint, restart, lead back with assignedBy; clear, restart, null.
  • resolvePrincipal no longer does a Map lookup (early exit on the first differing byte); it compares the bearer against every configured token with timingSafeEqual after an equal-length check and never returns early. Tests: a same-length near-miss is refused at the bearer gate (401); the exact token still proves the lead (200).

Suite: 806/806 on the mini per claudemm; re-run on the MacBook before merge.

🤖 Generated with Claude Code

…lookup

claudeMB's review of #131, the two nits that were not blockers:

- setLead only posted a receipt, so every daemon restart vacated the post,
  while the replay loop's comment claimed lead rows were written and
  skipped. Now setLead appends a {kind:'lead'} state row (null on clear),
  loadPersistedState restores the last one and reports it in the summary.
  Test: appoint, restart, lead back with assignedBy; clear, restart, null.
- resolvePrincipal looked the bearer up in a Map, a comparison that stops at
  the first differing byte. It now compares against every configured token
  with timingSafeEqual (equal length first) and never returns early.
  Test: a same-length near-miss is refused at the bearer gate (401), the
  exact token still proves the lead (200, decidedBy @Hermes).

Suite 806/806.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-22T23:20:40.941581Z 8e37bad PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8e37bad823

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/confirmations.mjs
Comment on lines +1160 to +1162
for (const [token, handle] of principalByToken) {
const t = Buffer.from(token);
if (t.length === g.length && timingSafeEqual(t, g)) found = handle;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use constant-time matching at the bearer gate

When authToken is configured, every per-agent bearer is checked by principalByToken.has(got) in the server's earlier authentication gate before this loop runs. Invalid guesses are therefore still rejected through a non-constant-time Map lookup, so the new timingSafeEqual scan does not remove the token-timing oracle it is intended to close. Reuse a constant-time principal-token result in the bearer gate as well.

Useful? React with 👍 / 👎.

@ThinkOffApp
ThinkOffApp merged commit 61fdcca into main Sep 23, 2026
2 of 3 checks passed
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