Skip to content

Derive table mutation guards from capabilities - #2471

Closed
trissim wants to merge 9 commits into
mainfrom
unit-mi-1d/table-mutation-capabilities
Closed

trissim wants to merge 9 commits into
mainfrom
unit-mi-1d/table-mutation-capabilities

Conversation

@trissim

@trissim trissim commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

P429: mutation capabilities (draft; native qualification pending)

Replaced owners

  • Deleted all29 handwritten trigger-body hooks (29→0 over whole src). RowMutation renders guards; TypedTable collects capability implementations by MRO. ImmutableRows composes NoUpdate/NoDelete; AppendOnlyTables inherits that behavior.
  • Removed primitive raw UPDATE conditions entirely. Revision, ordering, accumulating bits, write-once fields, lifecycle edges/finality, ordinal rules, counter dependents, required references and cursor stability are declarations. Only approved cross-table membership conditions remain in GuardedUpdateMembership/ColumnGuard.
  • Python ExecutionState.accepts_previous and SQLite ordinal guards consume the same ordinal_rule value. Deleted the unused _sql_edges renderer and four context entries from coordination_schema.py.
  • OwnerRecord owns the repeated owner projection. ParticipantSnapshot retains its existing OwnerGenerations row; copied owner thread/generation fields are gone. ExecutionReference owns the three restrictive execution references.
  • TableSchema.require_installed replaces the three module-level installed-schema checks; families declare their error type.
  • carry_table_triggers is the sole stored-trigger writer. carry_declared_schema now handles tables/indexes/views, never triggers. Only SnapshotMeta.ddl_digest may change, transactionally after validation against the old stored schema; no application row changes. Unknown sidecar schemas are refused with their filename. Retire the cutover after installation.

Capability → tables

NoUpdate: awareness_claim_generations, bus, claim_batch_members, cohort_delivery_receipts, execution_claims, native_context_journal, native_runtime_triage_sources, participant_aliases, prompt_binding, publication_append_dispatches, publication_intents, publication_receipts, recovery_audit, snapshot_meta
NoDelete: attempts, awareness_claim_generations, bus, claim_batch_members, claim_batch_receipts, cohort_delivery_receipts, connectivity, current_executions, current_native_cursor, execution_claims, executions, native_context_journal, native_runtime_input, native_runtime_triage_sources, obligations, owner_generations, participant_aliases, participants, prompt_binding, publication_append_dispatches, publication_intents, publication_receipts, recovery_audit, replay_assessments, snapshot_meta, wake_claims
GuardedColumns: claim_batch_receipts, executions, obligations, participants
FrozenColumns: attempts, claim_batch_receipts, connectivity, current_executions, current_native_cursor, executions, native_runtime_input, obligations, owner_generations, replay_assessments, wake_claims
OneWayColumn: claim_batch_receipts
InitialOneWayColumn: claim_batch_receipts
IncrementingColumn: attempts, connectivity, current_executions, executions, obligations, replay_assessments, wake_claims
MonotoneColumns: attempts, connectivity, current_native_cursor, executions, obligations, participants, replay_assessments, wake_claims
AccumulatingBits: replay_assessments
WriteOnceColumns: native_runtime_input, wake_claims
RequiredUpdateColumns: native_runtime_input
FinalizedColumn: native_runtime_input
StableReferenceColumns: current_native_cursor
RequiredColumn: wake_claims
FirstValueState: wake_claims
LifecycleTransitions: attempts, executions, obligations, wake_claims
OrdinalTransitions: executions
LifecycleChanges: obligations, wake_claims
FinalizedLifecycle: attempts
CounterAdvance: owner_generations
GuardedUpdateMembership: obligations
GuardedInserts: attempts, awareness_claim_generations, claim_batch_members, cohort_delivery_receipts, current_executions, execution_claims, native_context_journal, native_runtime_triage_sources, obligations, publication_intents, publication_receipts
GuardedRelatedInserts: cohort_delivery_receipts
ValidatedInserts: publication_intents
GuardedAfterWrites: obligations, replay_assessments

RetryPartition shares the after-write partition check on obligations/replay assessments. Ordered column declarations own nondecreasing/nonincreasing/nullable-order SQL.

C: retained guard disposition

  • claim_batch_members and cohort_delivery_receipts: membership in an unsealed batch; receipt/claim cardinality, ordinal order, selected recipients and sealed observer exclusion cross tables. Initial sealed value and one-way UPDATE now derive from InitialOneWayColumn, not conditions.
  • awareness_claim_generations: its exact batch member, assignment and owner generation must agree.
  • current_executions: an owner-generation row must already exist.
  • attempts: active execution, current owner generation and initial active attempt must agree. The existing deferred FK is not the same immediate lease-acquisition rule.
  • execution_claims: assignment/claim belongs to the execution and its startable lifecycle.
  • executions: optional attempt references must name a matching attempt; lifecycle/ordinal/revision rules are separate capabilities.
  • obligations: wire acceptance, publication intent and publication receipt membership (including the approved UPDATE membership disposition). Lifecycle changes/edges, clocks and revision are no longer raw SQL rules.
  • publication_intents: pending obligation membership; ValidatedInserts owns invoking the existing declared validator.
  • publication_receipts: execution/obligation/intent membership and failed-execution exclusion.
  • native_context_journal/native_runtime_triage_sources: original native-input/context identity membership and permitted initial proof values.
  • The three computed/immutable row guards on response dispatches, prompt bindings and snapshot metadata are ImmutableRows (no copied trigger templates/messages). Existing CHECK/FK constraints remain unchanged; no DDL change was used to replace a trigger.

Source and SQL evidence

Refactor-audit parser census: before4,355 classes; after4,577; zero parse omissions. The after inventory includes the now-initialized audit skill gitlink, so this is not a production-class growth measurement. Explicit runtime declaration discovery checks membership; AST does not prove dynamic bindings. NRA's separate tree-sitter frontend was unavailable in the shared interpreter.

All75 table/index definitions remain byte-identical; 110 derived triggers. Command:

PYTHONPATH=src /home/ts/code/projects/agent-comms/.venv/bin/python /home/ts/.cache/agent-scratch/unit-mi-1d/snapshot.py /home/ts/.cache/agent-scratch/unit-mi-1d/after.txt
diff -u /home/ts/.cache/agent-scratch/unit-mi-1d/{before,after}.txt

Diff output: empty (0 bytes).

Verification actually run

  • SQLite-only batch: 28 passed in5.92s (27 repository tests in test_table_mutation_capabilities.py/test_table_trigger_carry.py, plus1 one-shot main-trigger carry proof). Used timeout300, -n0, -o faulthandler_timeout=60, owned persistent basetemp and --noconftest: these tests do not launch native and this is not native qualification.
  • Main-trigger proof built tables/indexes and old trigger text from the pre-edit main snapshot, copied the file, carried it, checked all family schemas, retained every row, second changed=0 and raw DELETE refused.
  • Copied live coordination DB: 148,599 application rows across25 tables unchanged, schema accepted, second changed=0 and raw DELETE refused. Copied live prompt-binding sidecar: 4,449 application rows retained, production read-only sidecar reader reopened it, repeat changed=0. Original live files were never written.
  • New tests also refuse unknown sidecar schema without changing its schema or metadata, and compose a table's own insert guard with a different declaration's related insert guard.
  • The first existing-test batch stopped before collection because its native preparation hook found an uninitialized skill gitlink; that is not a test pass. Gitlink now initialized. Existing affected files remain to run after native preparation.

Authorized reader edits

Schema-check consumers (15 production modules +1 test): cursor_owner.py, transcripts.py, optional_awareness_projection.py, selected_claim.py, attempt_recovery.py, native_source_cursor.py, cohort_foreground.py, proven_source_coverage.py, private_send_stage.py, historical_native_inputs.py, private_send_claim.py, native_prompt_binding.py, selected_participant.py, selected_tool_broker.py, coordination_cohort.py; tests/test_coordinated_runtime.py. Three old function-owning modules migrated in place.
Identity readers: attempt_start.py, attempt_store.py, input_drain.py, selected_participant.py, native_source_cursor.py, thread_management.py; associated tests/awareness construction; additionally execution_store.py as granted. Net lines per production file below.

2	2	src/agent_comms/attempt_recovery.py
2	2	src/agent_comms/attempt_start.py
1	1	src/agent_comms/attempt_store.py
2	2	src/agent_comms/cohort_foreground.py
74	278	src/agent_comms/cohort_schema.py
1	13	src/agent_comms/coordinated_runtime_schema.py
5	12	src/agent_comms/coordination_cohort.py
10	28	src/agent_comms/coordination_response.py
0	16	src/agent_comms/coordination_schema.py
20	0	src/agent_comms/coordination_tables/__init__.py
31	95	src/agent_comms/coordination_tables/assignments.py
45	138	src/agent_comms/coordination_tables/attempts.py
37	102	src/agent_comms/coordination_tables/executions.py
37	71	src/agent_comms/coordination_tables/participants.py
14	77	src/agent_comms/coordination_tables/publications.py
15	51	src/agent_comms/coordination_tables/recovery.py
34	141	src/agent_comms/coordination_tables/responses.py
2	2	src/agent_comms/cursor_owner.py
33	7	src/agent_comms/execution_states.py
1	1	src/agent_comms/execution_store.py
4	4	src/agent_comms/historical_native_inputs.py
1	1	src/agent_comms/input_drain.py
2	10	src/agent_comms/native_input_record.py
15	20	src/agent_comms/native_pi.py
13	16	src/agent_comms/native_prompt_binding.py
20	45	src/agent_comms/native_runtime_input.py
5	5	src/agent_comms/native_source_cursor.py
2	9	src/agent_comms/optional_awareness_projection.py
5	15	src/agent_comms/participant_store.py
2	2	src/agent_comms/private_send_claim.py
3	3	src/agent_comms/private_send_stage.py
2	11	src/agent_comms/private_sidecar.py
4	4	src/agent_comms/proven_source_coverage.py
2	2	src/agent_comms/selected_claim.py
10	10	src/agent_comms/selected_participant.py
2	2	src/agent_comms/selected_tool_broker.py
1	1	src/agent_comms/storage_rules.py
2	2	src/agent_comms/thread_management.py
4	4	src/agent_comms/transcripts.py
15	29	src/agent_comms/triage_native_sources.py
431	23	src/agent_comms/typed_table.py

Current source diff including EOF cleanup:40 files,+910/-1264, net−354. The meaningful implementation is pushed at89693f6e9 (remote matched); eight EOF/whitespace cleanups remain to join the next semantic/native-pin commit.

Remaining before ready

  • PR2479 must land first; merge origin/main, then regenerate native proof schema and stack/pi-native.sha256 using the build owners. Record before/after hashes; never hand-merge them.
  • Run the existing affected tests with the prepared checkout-native package; confirm the changed journal through the real native writer/reader path. Fresh-environment install and copied-agent/Toad DM acceptance remain the merger's installation proof, not this source/SQLite proof.
  • Preserve2450’s shared EngagedExecution.assignment_state and ExecutionState-owned next-ordinal reader on integration; fold the reader’s remaining literal advancement value onto the ordinal-rule owner.
  • Current source declarations were rechecked against the retained live copies: coordination and native-runtime family schemas accepted,148,599+4,449 application rows unchanged, second carries0, raw DELETE refused and production sidecar reader reopened. One-shot converters/proof script retired; concise SQL/census/results receipts retained. Fresh final native build remains unqualified.

Assumed:

  • Table/index bytes are immutable for this change; necessary cross-table membership checks therefore remain declared predicate capabilities.
  • Only sidecar metadata digest rewriting is authorized; application rows are immutable during carry.
  • The carry is retained only until installation, then deleted as ordered.

@trissim
trissim marked this pull request as ready for review October 21, 2026 17:05
Copilot AI balanced review requested due to automatic review settings October 21, 2026 17:06
@trissim
trissim enabled auto-merge October 21, 2026 17:06

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@trissim

trissim commented Oct 21, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #2510: this branch's head f251e02 is an ancestor of #2510, so its four commits (223b0ff, 7dfbfbd, 5d5b82c, 3781d75) are carried there. The branch is left in place.

@trissim trissim closed this Oct 21, 2026
auto-merge was automatically disabled October 21, 2026 17:50

Pull request was closed

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.

2 participants