Repository navigation
feat(keys): safe-to-repeat messaging and calendar key issue, operation ID, check mode (ANYM-495) - #282
Open
egerev wants to merge 11 commits into
Open
feat(keys): safe-to-repeat messaging and calendar key issue, operation ID, check mode (ANYM-495)#282egerev wants to merge 11 commits into
egerev wants to merge 11 commits into
Conversation
egerev
marked this pull request as ready for review
October 24, 2026 09:02
…sue-key and calendar agent-key; schema 44 and calendar migration 3 (ANYM-495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: egerev <egor@gosync.ai>
…play/conflict/crash/check/migration (ANYM-495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: egerev <egor@gosync.ai>
…schema 44 and calendar migration 3 (ANYM-495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: egerev <egor@gosync.ai>
…check runs the issue validation, bounded calendar key read, timed migration locks, named principal columns survive migration 3 (ANYM-495) Astra r1 findings 1-7 and the CI cached-plan failure: ON CONFLICT DO NOTHING with a read-back instead of a unique violation; issue-key/agent-key --check run the issue's own validation read-only, key-info/agent-info --check read and bound the key file; calendar read_key opens nonblocking with no symlink, checks a regular owner-only file and reads at most 4097 bytes; both migrations get a statement timeout and the messaging header; the calendar principal lookup names its columns so a prepared plan survives the new columns. Tests: real schema-43 shape, race, omitted conflict fields, parent-operation recovery, check negatives, FIFO/symlink/size. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: egerev <egor@gosync.ai>
…out, check validates arguments on N-1, calendar group/calendar-list conflicts and identical concurrent replay tests (ANYM-495) Sol r2 recheck: finding 1 (total lock hold) and 5 (calendar test gaps), new minor (N-1 check). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: egerev <egor@gosync.ai>
…hold; race tests prove the second issue waits on the winner's lock (ANYM-495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: egerev <egor@gosync.ai>
…MMIT; the commit's WAL flush is outside it (ANYM-495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: egerev <egor@gosync.ai>
…he pool holders, migrate, start, verify; abort restarts them (ANYM-495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: egerev <egor@gosync.ai>
… migrations 044 and calendar 3 take no lock on api_keys or principals and need no outage; 044 is expand (ANYM-495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: egerev <egor@gosync.ai>
…epeated calendar); production.md states the bootstrap share locks of every migrate; table pins 70→71 (ANYM-495) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: egerev <egor@gosync.ai>
…en shape, piped stdin, replay fields, rerun days (ANYM-495) Fable r1 F1, F4, F5, F7, F8. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: egerev <egor@gosync.ai>
egerev
force-pushed
the
feat/admin-cli-issue
branch
from
October 24, 2026 09:59
4ce0777 to
7115766
Compare
egerev
enabled auto-merge
October 24, 2026 09:59
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Safe-to-repeat key issue (ANYM-495). Stacked on #281 (ANYM-494): review the commits after b0a237d; merge after #281.
issue-key --token-file FILE --operation-id ID(both or neither): stores only the digest of a caller-written token, never writes or prints it. Same ID + same request = existing record's public fields with"replayed": true; another request =operation_conflict; token held by another key =token_in_use.key-info --operation-idreads it back.agent-keythe same (--token-file/--operation-idinstead of--output), plus--days 1-183(default 90 unchanged);agent-info --operation-id.--checkon messagingissue-key,extend-key,revoke-key,list-keys,key-infoand calendaragent-key,extend-agent,revoke-agent,list-agents,agent-info: validates arguments, writes nothing, answersokorschema_not_ready.044_key_operation_id.sql(-- rollout: expand): new tableapi_key_operations(operation ID primary key, request sha256, key ID unique), no foreign key, so it takes no lock onapi_keys(the migrate transaction still rerunsschema.sql, whose existingCREATE INDEX IF NOT EXISTSholds share locks onmessages/deliveries/download_grantsuntil commit, as every migrate does; production.md says so); runtime ceiling, backup/restore range and backup manifest (V44_TABLES, table count 70→71) to 44; calendarschema_v3.sql:principal_operations, same shape, no lock onprincipals..claude/rules/migrations.md.Deployed-version compatibility: expand-only. Deployed schema-43 messaging and version-2 calendar code never read the new tables; a schema-43 runtime refuses schema 44, so 044 ships with its release (pinned backup/restore runtimes first). Deployed images: c4a7285; migrations are applied by hand (production.py stops autodeploy when the SQL inventory changes). Invocations without the new options behave as before. Data: the new tables hold operation IDs, request digests and key/principal IDs, never a token, key or key hash; they enter the backup manifest; calendar
db-roles(SELECT ON ALL TABLES) would give the gateway/worker roles read access toprincipal_operationson its next run, no more than they already read inprincipals.Tests:
tests/test_key_operation.py(messaging: two keys of one parent operation, replay after either commit, first call, replay, conflict, crash after commit then replay, check on current and N-1 = schema 43) andservices/calendar/tests/service/test_agent_operation.py(same +--daysbounds/default, N-1 = migrate(through=2)). Race tests prove the overlap: they poll pg_stat_activity until the second issue waits on the winner's lock. The migration tests assert that applying 044 / calendar 3 holds no lock onapi_keys/principals(pg_locks) and adds no foreign key. Touched messaging, backup and calendar tests pass locally on PostgreSQL 18.Spec impact
No acceptance criterion changes. The card's Boundary/Expected paths said "nullable column, unique index"; the operation ID now lives in a new additive table with a unique key (no lock on the authentication tables); settled on the Tiden branch below. The idempotency contract (same ID + same request = replay, other request =
operation_conflict, token held =token_in_use) is unchanged.Release step
Migrations by hand after merge, under production.md's backup gate: messaging
migrate(044 isexpand; production.py still pauses on the SQL inventory change) and calendarmigrateto 3, Order: back up; apply messaging 044 before activating the new messaging generation (a new managed generation needs schema 44 at activation, release.py:29; the running schema-43 generation keeps serving, since it does not recheck); calendar 3 in either order. Upgrade the pinned backup/restore runtimes first (they reject schema 44). Installed host production.py, gateway and backup pins are read on the host at release time, not inferred from source.Spec
Spec: ANYM-495
Delivers: ANYM-495
Tiden branch: review/2026-10-24-anym-495-storage
Settle text: ANYM-495 Expected paths, Boundary and History name the side tables (
api_key_operations,principal_operations, no lock onapi_keys/principals) instead of "one nullable column with a unique index"; acceptance criteria unchanged.Owner note: nothing changes in daily use; the migrations add two empty tables. The admin CLI (ANYM-496/497) will use these commands so a crashed key issue can be rerun without a second key.
Change path: OWNER (section 2: new migration 044 and calendar migration 3; additive only, no destructive SQL, no role SQL)
Reviews
--check okmeans; errors and connection failures neverschema_not_ready), F4, F5, F7, F8 answered in ACCESS.md and SERVICE.md (5051acd, docs only; the code already behaves so, tests cited in the commit); F9 settled on the Tiden branch above. F2 (calendar issue ceiling 183 vs extend 365), F3 (conflict names the differing fields), F6 (align calendar error names with messaging) and awould: create|replayfield in check answers are left to ANYM-496/497 (card candidates; outside ANYM-495's criteria).Model: claude-opus-5-5 high
🤖 Generated with Claude Code