Repository navigation
PR3.6: write provenance — every batch statement proves it won - #12
Conversation
|
@coderabbitai full review |
|
@greptileai review |
✅ Action performedFull review finished. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR adds per-statement write provenance through ChangesEngine provenance and conformance
Review gates and bot tooling
Estimated code review effort: 5 (Critical) | ~120 minutes Caution Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional.
❌ Failed checks (5 errors, 1 warning, 1 inconclusive)
✅ Passed checks (9 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai full review |
…jected on The first real review reported that .coderabbit.yaml has a parsing error -- eight custom-check names of 50 characters or more -- and that it therefore fell back to default settings. That is the worst shape a configuration failure can take: the app is installed, the bot posts a review, and not one of the eleven rules is running. Nothing local would have said so, because the constraint belongs to a hosted service. The names came from the rule TITLES, which are sentences. They are now derived from the rule FILENAME, which is short by construction and stable across edits to the prose: "durablerun: fence-gates-every-write", 35 characters, longest is 42. review-bot-lint.py now enforces the limit, with a self-test case proving it rejects. Verified: a 72-character name is refused, naming the length and what the fallback costs. Second finding from the same comment: auto review is disabled for pull requests whose target is not the default branch, so PR #12 was skipped outright -- this project stacks its pull requests (pr3.6 -> pr3.1 -> main), which means every PR but the last would be silently unreviewed. `auto_review.base_branches` now lists main and the pr.* stack. Claude-Session: https://claude.ai/code/session_01N36hPrFKWtw1FKzKfqL5Gf
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Actionable comments posted: 43
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/review-bot-rules/red-test-before-fix.md:
- Around line 24-29: The red-test-before-fix rule must reject combined
fix-and-test commits rather than allowing exceptions. Remove the combined-commit
allowance from .github/review-bot-rules/red-test-before-fix.md lines 24-29, then
regenerate the corresponding CodeRabbit rule at .coderabbit.yaml lines 113-116
and Greptile rule at .greptile/config.json lines 120-121 so all three
configurations enforce the mandatory separate red-then-green commits.
In @.github/workflows/ci.yml:
- Around line 82-86: Replace the hard-coded checker list in the base-gate loop
with the checker inventory derived by the base copy of scripts/gate-lint.py,
reusing its existing order output or a dedicated --list mode. Ensure the loop
covers additions and renames from package.json's verify chain without
maintaining a second manual list, while preserving the existing missing-file
skip behavior.
- Around line 89-101: Update the base-checker loop in the CI step so it fails
when no checker runs successfully: after processing all available base checker
files, check whether ran is zero while at least one base checker file existed,
and exit nonzero in that case. Preserve the existing skipped-checker behavior
and success reporting when at least one checker is applied.
In `@BUILD.md`:
- Around line 150-164: The Remaining section in BUILD.md must add a non-DONE
sub-bullet owning the generated key/column mismatch residual, specifically the
run_id/task_id pairing that compiles but selects nothing. Name the prevention
destination, such as typed key/column pairing or constructor/conformance
rejection, and state the residual behavior it must prevent.
- Around line 202-235: The unfinished mutation-probe arity mechanism is not
tracked under an active BUILD item. Add a live, non-DONE PR entry naming
scripts/mutation-probe.py and the checker responsible for distinguishing compile
failures from behavioral catches, documenting the needed prevention work without
marking it complete.
- Around line 148-150: Reconcile the defect count in the PR3.7 provenance
summary with the 44 findings reported nearby and in
postmortems/pr3.6-fence-provenance.md. Update the “0 of 38” metric to 44, or
explicitly define the narrower 38-item scope using the authoritative detection
ledger, ensuring the documentation matches the shipped diff.
In `@packages/conformance/src/invariants.ts`:
- Around line 240-268: The provenance-pair-broken and one-batch-two-instants
queries in engineInvariantViolations use non-portable string SQL. Replace their
SQL projections with portable fence_stamp and fence_at_ms columns from all four
tables, then perform seed splitting, validation, and violation-label
construction in TypeScript within engineInvariantViolations, preserving the
existing invariant results without dialect-specific functions or implicit
integer concatenation.
- Around line 214-239: Reorder the comments in the invariant definitions: move
the “Rule 8, as data” block directly above the `one-batch-two-instants` check,
and restore the `// TypeOK twin, generation/counter arm.` comment immediately
above `generation-or-counter-corrupt`. Keep the provenance-pair documentation
directly above `provenance-pair-broken`.
- Around line 252-268: Add raw-SQL corrupt-state fixtures for
attempt-accounting-drift, provenance-pair-broken, and one-batch-two-instants so
engineInvariantViolations reports each invariant name. Split
provenance-pair-broken coverage into separate rejection cases for half-pairs,
missing colons, and empty tails, following the existing fixture structure and
using the relevant tables and columns.
In `@packages/conformance/test/fence-provenance-regressions.test.ts`:
- Around line 412-417: Update the awaitEvent assertion in the affected
regression test to capture whether the call succeeds or throws instead of
swallowing errors. Assert that successful execution parks the run at NOW +
30_000, while a rejected call is explicitly accepted as the refusal path; do not
use the unchanged running state as evidence of correct behavior.
In `@packages/conformance/test/legacy-rows.test.ts`:
- Around line 33-43: Update columnsAddedAfterTheirTable to inspect every
migration statement containing ALTER TABLE case-insensitively, accepting
flexible whitespace and optional ADD COLUMN IF NOT EXISTS syntax. Require each
such statement to resolve to a table and column pair, and throw when parsing
fails instead of silently skipping it, while preserving the returned version
metadata.
In `@packages/conformance/test/replay-after-the-world-moved.test.ts`:
- Around line 467-471: Update the waits query setup around parkedTimeout to
require an existing row instead of defaulting a missing result to null; assert
or otherwise fail immediately when no row is returned. Remove the as number cast
at the wait insertion so the precondition is enforced by the test rather than
hiding the missing timeout.
In `@packages/core/src/fenced-batch.ts`:
- Around line 377-383: Update the `add()` flow in `fenced-batch.ts` to call
`blankComments(sql)` once before computing `head`, then use that comment-blanked
SQL for `beforeTopLevelWhere` and all related construction checks so
`assertWritesStamp`, `hasPositiveFence`, and `hasTopLevelOr` share the same
representation. Add the specified regression test in `fenced-batch.test.ts` to
verify a counter bump with a comment containing `WHERE` is rejected.
- Around line 348-360: Remove the unused generated?: boolean parameter and its
explanatory doc comment from add(), then remove generated: true from both
derived() branches. Keep the existing validation checks unchanged so derived SQL
continues through the same enforcement path as hand-written statements.
- Around line 468-471: Update the result-processing logic in the fenced batch
post-commit audit around the statements iteration to reject any result/statement
count mismatch before mapping results. Remove the per-item `if (!result) return`
skip, assert that the executor returned exactly one result for each statement,
and fail closed when the array is short or otherwise mismatched. Add executable
coverage in `fenced-batch.test.ts` using a `FakeDb` that returns a short result
array.
In `@packages/core/test/user-name.test.ts`:
- Around line 28-37: Update the invalid-input cases in UserName.parse tests to
use a deterministic matrix covering every non-string JavaScript type kind,
including boolean, bigint, and function values alongside null, undefined,
number, object, array, and symbol. Retain ordinary strings as an accepted nearby
case, and assert that every non-string entry throws FatalTaskError.
In `@packages/harness/src/ids.ts`:
- Around line 18-30: The seededIdSource implementation lacks a regression test
proving UUID generation is independent of interleaved token generation. Add a
test for seededIdSource that compares UUID sequences with and without token()
calls between uuidv7() calls, while preserving the existing deterministic and
conformance coverage.
In `@packages/sdk/src/context.ts`:
- Around line 207-208: Update the shared userJsonValue validator used by the
event payload path to parse and reserialize values with the project’s canonical
serializer before returning them, ensuring equivalent JSON has one wire
representation while already-canonical JSON remains unchanged. Add a red
regression/mutation test covering non-canonical whitespace or formatting through
the payload flow and verify canonical output is preserved.
In `@packages/store-libsql/src/fragments.ts`:
- Around line 82-91: Update successor.mine and successor.exists to read from one
shared predicate definition rather than duplicating the SQL expression, while
preserving both named views and their existing call sites in fail and
sweepClaimTimeout. Ensure future changes to the successor predicate
automatically apply to both views.
In `@packages/store-libsql/src/store.ts`:
- Around line 399-401: Remove the obsolete SQL helper locals in
packages/store-libsql/src/store.ts: delete claimedByThisBatch at lines 399-401,
failedRun and taskOfFailedRun at lines 1128-1130, successorWritten at line 1157,
and BY_TASK at line 913. Keep the existing live fence/where specifications in
task-book, task-retrying, task-terminal, task, and both derived specs as the
sole representations; make no other changes unless one of these locals is still
required, in which case fold its logic into the corresponding spec.
In `@packages/store-libsql/src/testing.ts`:
- Around line 8-14: Update the explanatory comment near the fixture duplication
discussion to remove the unsupported “twenty-two of them, across five packages”
count, unless it can be derived from a maintained source inventory; preserve the
point that duplicated fixtures drifted and caused a real failure.
In `@packages/store-libsql/test/generated-selection.test.ts`:
- Around line 133-136: Update the assertions in the generated-selection test
around row?.a and row?.ra to verify the pinned fake-now value directly, rather
than only asserting that both fields agree. Preserve the existing batch-instant
relationship while ensuring the assertion fails if either timestamp is NULL or
no longer stamped with NOW.
In `@packages/store-libsql/test/query-plans.test.ts`:
- Around line 45-51: Replace the hand-written meta table and MIGRATIONS
statement loop in the test setup with a minimal raw-client-to-SqlExecutor
adapter, such as rawAsExecutor, implementing batch via sequential client.execute
calls. Pass that adapter to LibsqlStoreAdmin and call its migrate method, remove
the now-unused MIGRATIONS import, and preserve the existing LibsqlExecutor
migration setup.
In `@packages/store-libsql/test/schema-gate.test.ts`:
- Around line 63-75: Update the schema-gate test around the missing-column probe
to assert the rejection is a SchemaMismatchError, importing that class and using
table-driven cases for SQL errors containing “no such table,” “no such column,”
“has no column named,” and “duplicate column name.” Preserve the closed-client
case as a StoreUnavailableError assertion, and ensure each case exercises the
database operation as a rejected promise rather than only inspecting a returned
error value.
In `@postmortems/pr3.6-batch-fence-plan.md`:
- Around line 150-151: Update the stale Postgres clock-rule reference in the
contract requirement section so it matches the shipped DESIGN specification: use
statement_timestamp() and explicitly reject clock_timestamp(), or mark the prior
reference as historical. Ensure the plan no longer describes this already-fixed
issue as a live defect.
- Around line 329-345: Update the documented wake-runs and waits-gone flow so
cleanup is derived from the stamped run IDs actually updated by wake-runs,
rather than deleting every waiting registration for the emitted event. Require
wake-runs to match wake_event, wake_step, and timeout_at_ms equal to
available_at_ms, preserving the fence and live-task checks. Add the
corrupt-row/mismatched-pair rejection case to the plan’s machine-checked
coverage, ensuring declined waits remain registered and cannot become lost
wakeups.
In `@postmortems/pr3.6-fence-provenance.md`:
- Around line 426-439: Reconcile the deferred data-level provenance audit entry
with the landed StampAudit mechanisms and the corresponding BUILD.md scenarios,
including one-batch-two-instants and provenance-pair-broken. Update this section
to describe only the remaining limitation, such as deep-fuzz sampling or
performance coverage, or remove the deferred item if no limitation remains; keep
the mechanism status and deferred-work description consistent.
- Around line 10-13: Reconcile the checker/gate defect count in the postmortem’s
opening and severity text with the findings table, which lists eight entries
(7–10, 13, and 17–19). Either update the count to match the ledger or explicitly
explain the intentionally excluded row, and ensure the related count at the
later referenced section remains consistent.
- Around line 273-276: Update the verification summary around the
checker-rewrite gate to separate the results of pnpm verify from verify:fuzz and
verify:tla, unless package.json is changed to invoke those scripts through
verify. Attribute the 32 fuzz shards and TLC result only to their actual
commands, and ensure all stated verify-chain and coverage claims match the
shipped package scripts.
In `@scripts/batch-lint.py`:
- Around line 89-101: The call_body bracket scan must ignore brackets inside
quoted or backticked strings and both line and block comments, while still
matching real delimiters and preserving the returned body. Update call_body’s
scanner with the necessary skipped-span handling, then add the provided
two-statement SQL fixture to the batch-lint group in lint-selftest.py and assert
it is rejected.
- Line 31: Update the root argument handling in the batch-lint entrypoint to
ignore dash-prefixed argv[1] values and fall back to the script’s
repository-root path, matching the behavior of fragment-lint and spec-ledger.
Preserve explicit non-flag path arguments and the existing root.glob checking
flow.
In `@scripts/clock-lint.py`:
- Around line 57-60: Update the exemption logic in the loops scanning store
source files so only each package’s exact top-level src/time.ts path is
exempted, not nested files sharing the same filename. Compare each path against
the package root’s explicit time.ts path or an equivalent allowlist, and add a
fixture proving nested generated time.ts files containing NOW() are still
checked.
- Around line 52-64: Replace the per-line comment handling in the clock-lint
scan with a stateful, string-aware scanner that tracks /* */ block-comment
state, quoted strings, and both // and SQL -- line comments without treating
standalone * lines as universally ignorable. Ensure clock tokens inside comments
or quoted strings are ignored while real SQL/code occurrences remain violations,
and add corresponding acceptance and rejection fixtures to the self-tests in
scripts/lint-selftest.py.
In `@scripts/deferral-lint.py`:
- Around line 35-40: The DEFERRED matcher in scripts/deferral-lint.py must
recognize both “TODO” and “requiring closure” as unfinished-work markers. Add
these phrases to its pattern, then add BAD_CASES fixtures in
scripts/lint-selftest.py covering each form so the self-test verifies DONE PR
entries are rejected when they contain them.
- Around line 45-69: In the deferral-lint loop, rename the ambiguous variable l
to line everywhere it is used, including the starts comprehension and sub-bullet
processing; also remove the unnecessary f-string prefix from the final
deferral-lint clean print message so Ruff passes.
In `@scripts/gate-lint.py`:
- Around line 37-45: Update the interface documentation above `_args`, `OWN`,
`ROOT`, and `BASE` to describe the actual positional arguments used by the
script: the optional first tree is the graded root, and the optional second tree
is the comparison base. Remove the undocumented `--base <tree>` wording and
preserve the existing invocation behavior.
In `@scripts/lint-selftest.py`:
- Around line 427-449: Replace the filename-based inventory loop in the
self-test with the actual checker set derived from the verify chain, reusing or
exposing the same gate-checker discovery mechanism as
gate-lint.py:gate_checkers. Require every discovered gate checker outside EXEMPT
to have a BAD_CASES entry, and update gate-lint.py:selftest_subjects to count
only BAD_CASES checker subjects rather than arbitrary filenames found in this
file.
- Around line 451-459: Update BAD_CASES and its validation loop around run so
each fixture includes an expected rejection marker and the assertion verifies
that marker in the checker’s output, not merely a nonzero return code. Treat
stderr containing Traceback or any missing expected marker as a self-test
failure, ensuring crashes are not reported as valid bad-input rejections. Keep
GOOD_CASES behavior unchanged.
In `@scripts/review-attest.sh`:
- Around line 114-132: Make the ledger reconciliation in review-attest.sh fail
closed when the required detection ledger cannot be parsed: remove the
empty-LEDGER bypass and emit the existing validation error before exiting
nonzero when parsing yields no valid table. Refactor the ROWS and SUM extraction
to use one explicitly declared ledger table shape and shared parsed data, so
both totals come from the same source rather than independent document-wide
greps; preserve successful reconciliation for valid ledgers.
In `@scripts/review-bot-lint.py`:
- Around line 160-172: Update the custom-check name scan in the linting function
to match the YAML name key structurally regardless of indentation, while
supporting double-quoted, single-quoted, and unquoted values; continue rejecting
names 50 characters or longer. Add single-quoted and unquoted overlong-name
fixtures to the relevant BAD_CASES group in lint-selftest.py to cover each new
parsing variant.
- Around line 67-69: Update the missing RULES_DIR branch in the corpus checker
so it fails when .coderabbit.yaml or .greptile/config.json still references rule
paths or IDs, while retaining the no-op success only when neither configuration
references rules. Add a corresponding BAD_CASES fixture in
scripts/lint-selftest.py covering a removed corpus directory with stale
references in both bot configurations, ensuring this failure path remains
tested.
In `@scripts/session-state.sh`:
- Around line 27-31: Make the session-state checks fail closed when their
ground-truth sources are unavailable: enable immediate failure and validate the
directory change around ROOT, require /proc before process enumeration, and
verify the ps invocation succeeds without masking unsupported options. Update
the ls/ps paths near the process scans to avoid silently treating unreadable or
unsupported sources as empty, while preserving found-based reporting for valid
inputs.
In `@specs/Scheduler.tla`:
- Around line 825-837: Revise the comments around the active-wait predicate to
retain the unresolved active-wait gap rather than claiming it is closed. In the
explanation of the wake_event/wake_step intersection, state that it narrows
matching but does not prove the row is the current registration, consistent with
the deferred wait_id/active_wait_id mechanism in BUILD.md and the postmortem;
alternatively, implement that mechanism in the model and its executable twin
before making the completeness claim.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 2c91d30d-24d5-49fd-ace1-18adba2eb593
📒 Files selected for processing (88)
.claude/skills/pr-gate/SKILL.md.coderabbit.yaml.github/review-bot-rules/README.md.github/review-bot-rules/checks-must-be-able-to-fail.md.github/review-bot-rules/dialect-portability.md.github/review-bot-rules/docs-track-behaviour.md.github/review-bot-rules/fence-gates-every-write.md.github/review-bot-rules/guard-needs-an-executable-twin.md.github/review-bot-rules/mechanism-not-point-fix.md.github/review-bot-rules/no-one-shot-flags.md.github/review-bot-rules/one-instant-per-batch.md.github/review-bot-rules/red-test-before-fix.md.github/review-bot-rules/single-representation.md.github/review-bot-rules/test-determinism.md.github/workflows/ci.yml.gitignore.greptile/config.json.greptile/rules.mdBUILD.mdCLAUDE.mdDESIGN.mdLICENSEbiome.jsonpackage.jsonpackages/conformance/package.jsonpackages/conformance/src/fault-matrix.tspackages/conformance/src/invariants.tspackages/conformance/src/suite.tspackages/conformance/test/clock-jitter.test.tspackages/conformance/test/fault-matrix.test.tspackages/conformance/test/fence-provenance-regressions.test.tspackages/conformance/test/fixture-libsql.tspackages/conformance/test/legacy-rows.test.tspackages/conformance/test/regressions.test.tspackages/conformance/test/replay-after-the-world-moved.test.tspackages/conformance/test/wake-witness-surface.test.tspackages/core/package.jsonpackages/core/src/contract.tspackages/core/src/errors.tspackages/core/src/fenced-batch.tspackages/core/src/index.tspackages/core/src/types.tspackages/core/src/validate.tspackages/core/test/fenced-batch.test.tspackages/core/test/retry.test.tspackages/core/test/user-name.test.tspackages/driver/package.jsonpackages/driver/test/chaos-process.test.tspackages/driver/test/e2e.test.tspackages/driver/test/http-hardening.test.tspackages/driver/test/loop.test.tspackages/driver/test/tick.test.tspackages/harness/package.jsonpackages/harness/src/ids.tspackages/harness/src/rng.tspackages/sdk/package.jsonpackages/sdk/src/context.tspackages/sdk/test/event-regressions.test.tspackages/sdk/test/review-regressions.test.tspackages/sdk/test/run-worker.test.tspackages/store-libsql/package.jsonpackages/store-libsql/src/admin.tspackages/store-libsql/src/executor.tspackages/store-libsql/src/fragments.tspackages/store-libsql/src/index.tspackages/store-libsql/src/schema.tspackages/store-libsql/src/store.tspackages/store-libsql/src/testing.tspackages/store-libsql/test/await-event-regressions.test.tspackages/store-libsql/test/generated-selection.test.tspackages/store-libsql/test/query-plans.test.tspackages/store-libsql/test/schema-gate.test.tspackages/store-libsql/test/schema.test.tspostmortems/TEMPLATE.mdpostmortems/pr3.6-batch-fence-plan.mdpostmortems/pr3.6-fence-provenance.mdscripts/batch-lint.pyscripts/clock-lint.pyscripts/deferral-lint.pyscripts/fragment-lint.pyscripts/gate-lint.pyscripts/lint-selftest.pyscripts/mutation-probe.pyscripts/review-attest.shscripts/review-bot-lint.pyscripts/session-state.shscripts/spec-ledger.pyspecs/Scheduler.tla
💤 Files with no reviewable changes (1)
- packages/store-libsql/src/index.ts
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
CLAUDE.md (1)
147-175: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winReject postmortems with an empty detection ledger.
The supplied
scripts/review-attest.shlogic validates ledger arithmetic only whenLEDGERis non-empty. A postmortem can therefore contain findings and an empty## Detection ledgersection while passing the gate, leaving the first required question unanswered. Add an executable rejection fixture and mutation-probe coverage for that exact case; otherwise, weaken the documentation claim. The missing mechanism is an attestation-level rejection, not a reviewer reminder.As per path instructions, the fix must name and land the mechanism that makes this defect machine-caught. Based on learnings, review findings require a durable mechanism rather than only a point fix.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@CLAUDE.md` around lines 147 - 175, Update the attestation validation in scripts/review-attest.sh so a postmortem with findings but an empty “## Detection ledger” is rejected, rather than skipping ledger arithmetic when LEDGER is empty. Add an executable rejection fixture and mutation-probe coverage for this exact case, and name the attestation-level mechanism in the documentation.Sources: Path instructions, Learnings
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@CLAUDE.md`:
- Around line 147-175: Update the attestation validation in
scripts/review-attest.sh so a postmortem with findings but an empty “##
Detection ledger” is rejected, rather than skipping ledger arithmetic when
LEDGER is empty. Add an executable rejection fixture and mutation-probe coverage
for this exact case, and name the attestation-level mechanism in the
documentation.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 9383f731-f48e-447d-bbf4-d6f465615fb4
📒 Files selected for processing (1)
CLAUDE.md
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/core/src/fenced-batch.ts (1)
604-655: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winHandle MySQL upserts in
assertWritesStamp
assertWritesStamponly matchesDO UPDATE, soON DUPLICATE KEY UPDATEslips past the provenance-preservation check. Add a MySQL branch for that spelling and a rejection fixture inpackages/core/test/fenced-batch.test.ts.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/core/src/fenced-batch.ts` around lines 604 - 655, Update assertWritesStamp to detect MySQL ON DUPLICATE KEY UPDATE clauses alongside PostgreSQL DO UPDATE and apply the same fence_stamp, fence_at_ms, and provenance-preservation validation; add a rejection fixture in fenced-batch.test.ts covering an invalid MySQL upsert.Source: Coding guidelines
♻️ Duplicate comments (2)
specs/Scheduler.tla (1)
831-840: 🗄️ Data Integrity & Integration | 🟠 MajorRetain the active-wait identity gap here.
Lines [831-840] claim the implementation has closed this gap, but
wake_event/wake_stepplus queue, event, status, and timeout matching only narrows candidates; it does not prove that the matched(run_id, step_name)row is the current registration. Thewake_step IS NULLlegacy arm is explicitly a wildcard. Keep this as a residual untilwait_id/runs.active_wait_id, the TLA model, and a conformance refusal case land; the current wake-witness surface does not catch this stale-row false negative.As per path instructions, specification completeness claims must remain true of the shipped implementation and identify the enforcing mechanism.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@specs/Scheduler.tla` around lines 831 - 840, Restore the active-wait identity gap in the specification commentary near the model/implementation comparison. Do not claim that wake_event/wake_step, queue, event, status, or timeout matching proves the matched wait row is current, especially because the wake_step-null legacy path remains a wildcard. Retain this as unresolved until wait_id/runs.active_wait_id, the corresponding TLA model support, and a conformance refusal case are implemented; identify that mechanism when the completeness claim is revisited.Source: Path instructions
scripts/lint-selftest.py (1)
811-818: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winThe new BAD_INVOCATIONS loop repeats the crash-counts-as-rejection hole.
result.returncode == 0is again the only discriminator, so a--run-basefixture that makesgate-lint.pydie (missing basepackage.json, unreadable tree, an unhandled exception after any refactor) is recorded as "bad invocation rejected" while the base-runner rule never ran. Same fix as the BAD_CASES loop: require the rejection's marker (or at minimum the absence ofTracebackon stderr) per case.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/lint-selftest.py` around lines 811 - 818, Update the BAD_INVOCATIONS validation loop around BAD_INVOCATIONS so a zero return code alone cannot count as rejection. Require each fixture’s expected rejection marker, or at minimum verify stderr does not contain “Traceback,” before accepting the result; classify runner crashes as failures while preserving the existing failure message context.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/review-bot-rules/test-determinism.md:
- Line 15: The detection-ledger wording in test-determinism.md conflicts with
the “nine checkers” wording in red-test-before-fix.md. Reconcile both rule files
by using one authoritative count derived from scripts/gate-lint.py, or replace
the numeric reference with “the linters” in both documents; do not retain
independently hard-coded counts.
In `@BUILD.md`:
- Line 37: Correct the misspelled Greptile name in the PR0.2 externally owned
review configuration entry, changing “Grepile” to “Greptile” while preserving
the rest of the ownership and policy text.
In `@packages/store-libsql/src/fragments.ts`:
- Around line 55-63: Update registeredWaitStep so it does not silently select
one row when multiple waits match the run correlation; remove the ORDER BY
w.step_name LIMIT 1 narrowing and make the scalar subquery reject ambiguous
matches while preserving the existing predicates.
In `@scripts/lint-selftest.py`:
- Around line 190-199: Make the fixtures controlled by in_coderabbit and
active_coderabbit structurally distinct in the corpus generation logic,
especially around path_instructions and the CodeRabbit check name. Ensure the
in_coderabbit=False case removes the rule reference while
active_coderabbit=False retains it but omits the active pre-merge check, so each
claimed rule reaches a different rejection path; otherwise remove the redundant
case and assert the specific rejection reason.
In `@scripts/mutation-probe.py`:
- Around line 96-114: The generated-update mutation entry combines independent
changes to the provenance assignment and target validation, so a caught result
cannot identify which guard was exercised. In the mutation definitions around
"generated-update-provenance", split this into separate entries: one changing
only fence_stamp = ${STAMP} to fence_stamp = fence_stamp for the runtime
stale-provenance check, and another changing only target: spec.target to target:
null for the construction check; preserve coverage for both guards.
- Around line 115-121: Update the `seal-intermediate-fence` mutation in the
mutation probe to target the predicate inside `seal()` that guards
intermediate-fence replay, rather than inserting `if (name) return this` before
`this.derived(...)`. Make the replacement alter only that seal guard so the
probe survives exclusively when the intermediate-fence replay check is absent.
In `@scripts/review-bot-lint.py`:
- Around line 615-657: Consolidate the README provenance checks into the
existing provenance_docs table and single audit loop, adding the README with its
required markers and applying FORBIDDEN_PROVENANCE there. Reuse the
already-loaded readme_text instead of rereading the file, remove the separate
README marker and false-claim loops, and retain only one appropriate
missing-README diagnostic.
- Around line 436-449: Add a BAD_CASES fixture covering tracked() when git
ls-files fails and when it returns no paths, ensuring both cases are rejected.
Follow the existing rejecting fixtures for path-instruction, Greptile-scope, and
provenance branches, and place the cases in the test fixture definitions used by
the scope audit.
---
Outside diff comments:
In `@packages/core/src/fenced-batch.ts`:
- Around line 604-655: Update assertWritesStamp to detect MySQL ON DUPLICATE KEY
UPDATE clauses alongside PostgreSQL DO UPDATE and apply the same fence_stamp,
fence_at_ms, and provenance-preservation validation; add a rejection fixture in
fenced-batch.test.ts covering an invalid MySQL upsert.
---
Duplicate comments:
In `@scripts/lint-selftest.py`:
- Around line 811-818: Update the BAD_INVOCATIONS validation loop around
BAD_INVOCATIONS so a zero return code alone cannot count as rejection. Require
each fixture’s expected rejection marker, or at minimum verify stderr does not
contain “Traceback,” before accepting the result; classify runner crashes as
failures while preserving the existing failure message context.
In `@specs/Scheduler.tla`:
- Around line 831-840: Restore the active-wait identity gap in the specification
commentary near the model/implementation comparison. Do not claim that
wake_event/wake_step, queue, event, status, or timeout matching proves the
matched wait row is current, especially because the wake_step-null legacy path
remains a wildcard. Retain this as unresolved until wait_id/runs.active_wait_id,
the corresponding TLA model support, and a conformance refusal case are
implemented; identify that mechanism when the completeness claim is revisited.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 0b8a986a-dba9-465f-b275-52050e00ed72
📒 Files selected for processing (43)
.coderabbit.yaml.github/review-bot-rules/README.md.github/review-bot-rules/checks-must-be-able-to-fail.md.github/review-bot-rules/dialect-portability.md.github/review-bot-rules/docs-track-behaviour.md.github/review-bot-rules/fence-gates-every-write.md.github/review-bot-rules/guard-needs-an-executable-twin.md.github/review-bot-rules/mechanism-not-point-fix.md.github/review-bot-rules/no-one-shot-flags.md.github/review-bot-rules/one-instant-per-batch.md.github/review-bot-rules/red-test-before-fix.md.github/review-bot-rules/single-representation.md.github/review-bot-rules/test-determinism.md.github/workflows/ci.yml.greptile/config.json.greptile/rules.mdBUILD.mdCLAUDE.mdDESIGN.mdpackages/conformance/src/invariants.tspackages/conformance/src/suite.tspackages/conformance/test/clock-jitter.test.tspackages/conformance/test/legacy-rows.test.tspackages/conformance/test/replay-after-the-world-moved.test.tspackages/conformance/test/wake-witness-surface.test.tspackages/core/src/contract.tspackages/core/src/fenced-batch.tspackages/core/test/fenced-batch.test.tspackages/sdk/src/context.tspackages/sdk/test/replay-equivalence.test.tspackages/store-libsql/src/fragments.tspackages/store-libsql/src/store.tspackages/store-libsql/src/testing.tspackages/store-libsql/test/await-event-regressions.test.tspackages/store-libsql/test/generated-selection.test.tspackages/store-libsql/test/query-plans.test.tspackages/store-libsql/test/testing.test.tspostmortems/pr3.6-final-defect-review.mdscripts/gate-lint.pyscripts/lint-selftest.pyscripts/mutation-probe.pyscripts/review-bot-lint.pyspecs/Scheduler.tla
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@CLAUDE.md`:
- Line 1: Update CLAUDE.md’s `@AGENTS.md` import shim so it satisfies markdownlint
MD041: add a concise top-level H1 before the import, or apply a narrowly scoped
MD041 suppression for this file while preserving the existing import.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 604c8606-f9ee-44f3-b3b6-369d41e9fbae
📒 Files selected for processing (2)
AGENTS.mdCLAUDE.md
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
BUILD.md (1)
145-157: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win"0 of 38" self-catch figure contradicts the "found seven of them" statement nine lines above it.
Lines 149-151 state the PR3.6 detection ledger shows machinery found seven of forty-four defects (three in round 6). Line 157 then says the same detection ledger showed 0 of 38 defects found by automated machinery. Even reading "38" as "44 minus the 6 round-6 findings," self-catch among those would be 7-3=4, not 0. This is the same unreconciled-count issue flagged in an earlier review pass and still not fixed.
As per coding guidelines, "exact counts of repository artifacts and gate-membership claims must remain accurate," and per path instructions, hand-maintained counts should be derived (e.g. via
review-attest.sh's ledger-total derivation) or deleted when unsupported.📝 Suggested reconciliation
-- **PR3.7 close the provenance residual** — MOSTLY DONE in PR3.6 after the - detection ledger showed the automated machinery had found 0 of 38 defects. +- **PR3.7 close the provenance residual** — MOSTLY DONE in PR3.6 after the + detection ledger showed the automated machinery had found 4 of 38 defects + found before round 6 (7 total, minus the 3 self-caught in round 6).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@BUILD.md` around lines 145 - 157, Reconcile the PR3.7 statement with the PR3.6 detection-ledger counts: remove the unsupported “0 of 38” claim and replace it with a count derived from the authoritative ledger-total mechanism, or omit the exact count if it cannot be verified. Keep the surrounding PR ownership and residual-status statements consistent with the corrected figures.Sources: Coding guidelines, Path instructions
packages/core/src/fenced-batch.ts (1)
559-610: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winTokenize against comment-blanked SQL in
compile()
compile()still scans raws.sql, so a?inside--or/* */comments is treated as a bind placeholder and can shift later arguments. UseblankComments(s.sql)for token matching, while keeping the original SQL for splicing; add a regression case with a comment containing?.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/core/src/fenced-batch.ts` around lines 559 - 610, Update compile() to run token matching against blankComments(s.sql) while continuing to slice and splice the original s.sql so output SQL remains unchanged. Preserve token positions and argument handling, and add a regression case covering a ? inside both line or block comment context as applicable.Source: Path instructions
♻️ Duplicate comments (1)
scripts/review-bot-lint.py (1)
641-679: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winREADME provenance is still audited by two separate loops and the file is read three times.
readme_textis loaded at Line 433, re-read at Line 642, and read a third time at Line 673; theFORBIDDEN_PROVENANCEloop at 674-679 is a second spelling of the one at 665-670. A marker class added to one loop and not the other leaves README silently unaudited — the drift shape this corpus's ownsingle-representationrule flags. Fold the README intoprovenance_docs(readme: PROVENANCE_MARKERS) so one table and one loop own both halves.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/review-bot-lint.py` around lines 641 - 679, Consolidate README provenance validation into the existing provenance_docs table and loop: add the README path with PROVENANCE_MARKERS, then apply both required-marker and FORBIDDEN_PROVENANCE checks there. Remove the separate README marker and false-claim loops, and reuse the existing readme_text content instead of rereading the file.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/batch-lint.py`:
- Around line 222-254: Optionally refactor inline_statement_spans to reduce its
nine early return points and satisfy Ruff PLR0911, while preserving the existing
fail-closed behavior and all validation checks for bounds, delimiters, element
objects, and SQL keys.
In `@scripts/source_lex.py`:
- Around line 258-270: Update _sql_quote_end to remove the backslash-escape
branch, retaining only doubled-quote handling when locating the closing quote.
Add the specified backslash-ending literal with NOW() to BAD_CASES in
lint-selftest.py so the lexer rejects the false-negative case.
---
Outside diff comments:
In `@BUILD.md`:
- Around line 145-157: Reconcile the PR3.7 statement with the PR3.6
detection-ledger counts: remove the unsupported “0 of 38” claim and replace it
with a count derived from the authoritative ledger-total mechanism, or omit the
exact count if it cannot be verified. Keep the surrounding PR ownership and
residual-status statements consistent with the corrected figures.
In `@packages/core/src/fenced-batch.ts`:
- Around line 559-610: Update compile() to run token matching against
blankComments(s.sql) while continuing to slice and splice the original s.sql so
output SQL remains unchanged. Preserve token positions and argument handling,
and add a regression case covering a ? inside both line or block comment context
as applicable.
---
Duplicate comments:
In `@scripts/review-bot-lint.py`:
- Around line 641-679: Consolidate README provenance validation into the
existing provenance_docs table and loop: add the README path with
PROVENANCE_MARKERS, then apply both required-marker and FORBIDDEN_PROVENANCE
checks there. Remove the separate README marker and false-claim loops, and reuse
the existing readme_text content instead of rereading the file.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: fc6dd7c1-007b-4bb6-a9d0-cbdb6dca9a2d
📒 Files selected for processing (36)
.coderabbit.yaml.github/review-bot-rules/red-test-before-fix.md.greptile/config.jsonBUILD.mdpackages/conformance/src/invariants.tspackages/conformance/test/fence-provenance-regressions.test.tspackages/conformance/test/invariant-checkers.test.tspackages/conformance/test/legacy-rows.test.tspackages/conformance/test/replay-after-the-world-moved.test.tspackages/conformance/test/wake-witness-surface.test.tspackages/core/src/fenced-batch.tspackages/core/src/launch.tspackages/core/src/validate.tspackages/core/test/fenced-batch.test.tspackages/core/test/user-name.test.tspackages/driver/test/http-hardening.test.tspackages/sdk/test/event-regressions.test.tspackages/store-libsql/src/fragments.tspackages/store-libsql/src/store.tspackages/store-libsql/test/generated-selection.test.tspackages/store-libsql/test/query-plans.test.tspackages/store-libsql/test/schema-gate.test.tspostmortems/pr3.6-fence-provenance.mdpostmortems/pr3.6-final-defect-review.mdscripts/batch-lint.pyscripts/clock-lint.pyscripts/deferral-lint.pyscripts/gate-lint.pyscripts/lint-selftest.pyscripts/mutation-probe.pyscripts/review-attest.shscripts/review-bot-lint.pyscripts/session-state.shscripts/source_lex.pyspecs/Scheduler.tlatsconfig.base.json
|
@coderabbitai full review |
|
@greptileai review |
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Actionable comments posted: 47
♻️ Duplicate comments (2)
scripts/deferral-lint.py (1)
45-69: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winThe previously reported Ruff errors are still present.
lat Lines 45 and 53 (E741) and the placeholder-freefprefix at Line 69 (F541) were flagged on an earlier commit and remain, so the Python lint gate fails before this checker ever runs.🔧 Proposed fix
-starts = [i for i, l in enumerate(lines) if re.match(r"^- \*\*PR[\d.]+", l)] +starts = [i for i, line in enumerate(lines) if re.match(r"^- \*\*PR[\d.]+", line)] @@ - for l in lines[i:end]: - if not re.match(r"^\s+- ", l): + for line in lines[i:end]: + if not re.match(r"^\s+- ", line): continue - if DEFERRED.search(l) and not EXCUSED.search(l): + if DEFERRED.search(line) and not EXCUSED.search(line): @@ - f" {l.strip()[:110]}\n" + f" {line.strip()[:110]}\n" @@ -print(f"deferral-lint: clean — no deferred work parked under a completed PR entry") +print("deferral-lint: clean — no deferred work parked under a completed PR entry")🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/deferral-lint.py` around lines 45 - 69, Fix the Ruff violations in the deferral-lint loop: rename the ambiguous loop variable l used in the enumerate and sub-bullet loops to a descriptive name, updating all references, and remove the unnecessary f-string prefix from the final clean-status print. Preserve the existing lint behavior and output.Source: Linters/SAST tools
scripts/source_lex.py (1)
258-270: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
_sql_quote_endstill treats\as a SQL escape, and that is the false-negative direction.Previously raised and still present. SQLite and Postgres standard strings terminate on the doubled quote only, so
'c:\'ends at the second quote; this loop consumes past it and blanks the executable SQL that follows, hiding a clock call fromclock-lint. MySQL's default does honour backslash escapes, so the two dialects disagree — but the two errors are not symmetric: ending the literal early can only expose more text to the checkers (a false positive someone will see and fix), while consuming past the terminator hides text (a false negative nobody sees). Prefer the doubled-quote-only rule, and pair the widening with theBAD_CASESfixture so the change is proven to reject:const SQL = `SELECT 'c:\\' AS p, NOW() AS t`🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/source_lex.py` around lines 258 - 270, Update _sql_quote_end to remove backslash escape handling and recognize only doubled quotes as SQL string escapes, allowing a quote after a backslash to terminate the literal. Add the provided backslash-and-NOW() scenario to BAD_CASES to verify executable SQL after the terminator is still checked.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.coderabbit.yaml:
- Around line 34-39: Update every custom check in .coderabbit.yaml to explicitly
set statusCheck: true alongside mode: error, then extend
coderabbit_custom_checks() in scripts/review-bot-lint.py to harvest and assert
that field for each check. Update the corresponding sentence in
.github/review-bot-rules/README.md to accurately describe the configured
statusCheck behavior.
In @.github/review-bot-rules/docs-track-behaviour.md:
- Around line 110-128: Update the reference validation logic in
scripts/review-bot-lint.py so every path:line citation also requires and
verifies a short anchor substring present at the referenced line. Alternatively,
revise the documented references in docs-track-behaviour.md to omit line numbers
and use derivable symbols or headings, but do not leave unvalidated pinned line
anchors.
In @.github/review-bot-rules/fence-gates-every-write.md:
- Line 10: The rule contains an unsupported exact “fourteen of forty-four” claim
that can become stale. Update the prose to either derive and validate both
counts from the postmortem findings table using the existing linting patterns,
or replace the exact count with the non-numeric ranged claim “the largest single
class,” preserving the surrounding provenance guidance.
In @.github/review-bot-rules/guard-needs-an-executable-twin.md:
- Around line 3-10: Widen the machine scope block and line 12 prose scope from
the single-dialect libsql pattern to the portable store wildcard so both store
dialects are covered. Update scripts/review-bot-lint.py to reject literal
packages/store-* dialect entries when the wildcard form is applicable, while
supporting an explicit exemption for rules intentionally limited to one dialect.
In @.github/review-bot-rules/mechanism-not-point-fix.md:
- Around line 151-155: Remove the hard-coded “5 of its 320 lines” claim from the
case-law prose in mechanism-not-point-fix.md, replacing it with non-numeric
wording such as “a handful of its lines.” Preserve the surrounding explanation
and historical figures, which are explicitly sourced from postmortems and should
remain unchanged.
In @.greptile/rules.md:
- Around line 11-21: Update check 6 in scripts/review-bot-lint.py to reconcile
rule files against both .github/review-bot-rules/README.md and
.greptile/rules.md within one validation loop, enforcing both missing and
dangling references. Extend corpus() in scripts/lint-selftest.py with a
parameter that can omit a rule stem from .greptile/rules.md, then add a
BAD_CASES fixture proving the widened check rejects that omission.
In `@DESIGN.md`:
- Around line 377-381: Update the Scheduler.tla activation model around the
Activate action to explicitly require the task’s run to be the sole live run.
Add a corrupt-live-sibling transition that can violate SingleActiveRunPerTask,
reject that state through the conformance property, and include the
corresponding activation mutation so TLC exercises and verifies the
sole-live-run refusal contract.
In `@packages/conformance/src/fault-matrix.ts`:
- Around line 200-214: Validate the seeded crossing in the preState ===
'attempt-cap-edge' branch instead of discarding the result from go(). After
store.fail, inspect EDGE_RUN and assert it is no longer running; for other
non-fresh seeded edges, also verify a successor exists or relaunch_count
increased before continuing to the ordinary workload. Fail the cell immediately
when these seeded-edge conditions are not met.
- Around line 120-143: Update the edge-state seeding around the `run` helper and
`statements` so each pre-state supplies an explicit `(claimGen, activatedGen)`
pair, including a re-claimed generation such as `claimGen = 3` with activated
values below and equal to it. Use that claim generation in the inserted
`claim_gen` value and preserve the existing cap and sweep-arm scenarios,
ensuring classification depends on comparing both generation fields rather than
a pinned literal.
In `@packages/conformance/src/invariants.ts`:
- Around line 170-174: Replace the throwing integer() validation with a
non-throwing counter storage check that reports invalid non-integer values as
counter findings and skips dependent arithmetic. Update the task, run, and
generation-counter call sites in engineInvariantFindings to handle the invalid
result consistently with validTemporal. Enroll matching non-integer counter
conditions in POISON_WITNESSES and add constructed-corruption coverage proving
each checker emits its finding without aborting the invariant run.
In `@packages/conformance/src/poison-matrix.ts`:
- Around line 905-920: Add a POISON_DRIVER constant alongside TRIGGER_DRIVER and
replace all three hardcoded 'poison-driver' values, including the
POISON_INVOCATION.driverId and the FrozenAuthority-related entries, with that
constant so every reference uses one authoritative identity.
- Around line 1284-1291: Remove the duplicated protocol definitions in
poison-matrix.ts by importing LIVE and TERMINAL from the authoritative
invariants.ts or contract.ts owner, and use them in liveRuns, terminalBarrier,
and inertLiveBarrier. Add and export parseFenceStamp(stamp) alongside
isFenceStatementName, then replace the local stamp-splitting logic around the
affected helpers with that parser so seed and separator handling has one
implementation.
In `@packages/conformance/test/clock-jitter.test.ts`:
- Around line 139-141: Add a 'sweep' scenario to SCENARIOS and extend the
scenario execution branch to expire a lease with admin.setFakeNowEpochMs before
invoking the sweep flow, covering both sweep:lost-launch and sweep:claim-timeout
deadline calculations while preserving existing scenarios.
In `@packages/conformance/test/fault-matrix.test.ts`:
- Around line 35-43: Replace the makeLibsqlFixture-only loop in the fault-matrix
tests with shared StoreFixtureFactory entries covering MySQL, Postgres, and
LibSQL, so every dialect runs the identical pre-state/replay and cap-boundary
cases. Add a dialect/cell inventory assertion that fails when any required
engine or matrix cell is missing, using the shared fixture suite rather than
dialect-specific forks.
In `@packages/conformance/test/fence-provenance-regressions.test.ts`:
- Around line 252-257: Add post-run assertions to the test around world.run so
run R is in the failed state and exactly one successor exists at attempt 2. Keep
the existing rejection and invariant assertions, and verify the successor count
and attempt value to prove the retry committed exactly once.
In `@packages/conformance/test/poison-matrix.test.ts`:
- Around line 31-54: Expose the poison-matrix tests as a single exported driver,
such as poisonMatrixConformance(makeFixture), alongside the existing conformance
drivers in suite.ts, and move the current label/witness test generation into it.
Update each dialect’s conformance suite to invoke this shared driver with its
StoreFixtureFactory, replacing the libsql-only makeLibsqlFixture binding; do not
create dialect-specific test forks.
In `@packages/conformance/test/poison-oracle-meta.test.ts`:
- Around line 239-286: Update the rejection assertions in the owner-laundering
case and the related separator-containing composite-key case to match their
distinct error-message details, using the offending row key for the keying
failure and the swapped owner for the authority failure. Inspect the messages
produced by the poison-matrix implementation and replace the broad /authority/
matcher so each test can only pass for its intended guard.
In `@packages/conformance/test/replay-after-the-world-moved.test.ts`:
- Around line 725-727: Replace the bare rejection assertions at
packages/conformance/test/replay-after-the-world-moved.test.ts:725-727 and :788
with the existing requireExpectedFailure unique-constraint matcher used around
Lines 766-773, applying it to colliding.fail and colliding.sweep respectively;
leave the subsequent state assertions unchanged.
In `@packages/conformance/test/wake-witness-surface.test.ts`:
- Around line 1-4: Move the singleCases and pairCases generated behavior tests
into conformance/src/suite.ts, parameterized through StoreFixtureFactory and
using only public fixture interfaces with shared-schema raw SQL so every dialect
executes the wake behavior. Keep only the StatementMutator probes in this
libSQL-specific test, retaining their openTestDb/LibsqlSchedulerStore setup. Add
a gate check preventing conformance test files from importing
`@durablerun/store-libsql` unless they are on an explicit store-local allow-list.
In `@packages/core/src/fenced-batch.ts`:
- Around line 878-891: Update negatedSpans to recognize NOT immediately followed
by a parenthesis and bare NOT predicates such as NOT fence_stamp = $FENCE:win$,
while preserving existing NOT EXISTS and NOT IN handling. Ensure each detected
span covers the full negated expression needed by fence detection, and add
rejection tests in the fenced-batch test suite for both spellings.
In `@packages/core/src/validate.ts`:
- Around line 166-170: Update the non-string validation branch in validate to
use the existing describe(json) classifier in the FatalTaskError message instead
of the inline undefined/typeof expression. Preserve the existing JSON.stringify
explanation and all other validation behavior.
In `@packages/core/test/fenced-batch.test.ts`:
- Around line 165-188: Extend the upsert coverage in the test named “rejects an
upsert whose DO UPDATE branch leaves provenance stale” with MySQL `ON DUPLICATE
KEY UPDATE` cases matching the existing stale-provenance rejection scenarios and
the valid `fenceSetAt('events')` case. Ensure `FencedBatch` construction
recognizes this MySQL form and rejects stale `fence_stamp`/`fence_at_ms`
assignments while accepting the valid provenance update; retain the existing `ON
CONFLICT ... DO UPDATE` assertions.
In `@packages/driver/test/loop.test.ts`:
- Line 63: Use openTestDb as the sole IdSource for both fixtures: in
packages/driver/test/loop.test.ts lines 63-63 and
packages/driver/test/http-hardening.test.ts lines 12-13, pass idNamespace: seed
and consume the returned ids instead of minting another source. Add or preserve
a type-level/test guard that prevents routine libSQL fixtures from constructing
a second IdSource.
In `@packages/store-libsql/src/executor.ts`:
- Line 19: The fresh-database classifier MISSING_META_TABLE is too restrictive
because LibsqlError messages may include prefixes before “no such table: meta”.
Remove the end-of-message restriction so it matches the meta table token in
prefixed messages, and add a regression covering schemaVersion() on an
uninitialized database to preserve the bootstrap behavior.
In `@packages/store-libsql/src/fragments.ts`:
- Around line 122-127: Update the cancelDue fragment to return its existing
`${col} IS NOT NULL AND ${col} <= ${at}` predicate wrapped in parentheses,
matching cancelNotDue’s self-contained grouping while preserving the predicate
logic.
In `@packages/store-libsql/src/store.ts`:
- Around line 765-781: Update the successor insert in the fail flow around
b.followOn to derive the successor attempt from the fenced row f.attempt + 1,
matching the sibling fail implementation and task-terminal behavior. Replace the
caller-supplied item.attempt + 1 values in both the INSERT attempt column and
successorOwned ordinal expression, and remove the corresponding parameter from
the bound argument list.
In `@packages/store-libsql/src/testing.ts`:
- Around line 31-38: Use openTestDb()’s single IdSource for every converted
fixture: route seed through idNamespace and consume the returned { ids, close }
without creating a second source. Update packages/store-libsql/src/testing.ts
lines 31-38 to preserve this contract, and update
packages/driver/test/tick.test.ts lines 12-17,
packages/sdk/test/event-regressions.test.ts lines 24-34,
packages/sdk/test/review-regressions.test.ts lines 32-42, and
packages/sdk/test/run-worker.test.ts lines 48-59 to use the returned ids and
close.
In `@packages/store-libsql/test/await-event-regressions.test.ts`:
- Around line 200-252: Move the cancellation-deadline suspension regression from
the libSQL-only describe block into shared schedulerConformance using
StoreFixtureFactory, preserving assertions that both reschedule and suspendRun
reject and leave the run running. Remove the redundant last_attempt_run
regression at packages/store-libsql/test/await-event-regressions.test.ts lines
254-277; it already has shared coverage and requires no replacement there.
In `@packages/store-libsql/test/generated-selection.test.ts`:
- Around line 110-138: Strengthen the test “never lets narrow widen the target
set” with a positive control: add a second derived() using a narrow condition
that matches the stamped key and sets it to cancelled. Update its expected state
accordingly, while retaining the untouched-key assertion, so the test verifies
both that narrowing does not widen the target and that a non-empty narrowed
result is actually written.
In `@packages/store-libsql/test/query-plans.test.ts`:
- Around line 88-93: Strengthen the shipped claim plan assertion in the test
case `the shipped claim seeks eligible candidates before its per-leg limits` so
it verifies the sibling probe’s required positive query-plan shape rather than
only excluding the `SCAN sibling` alias text. Alternatively, add a
correlated/scanning counter-example plan assertion like the existing sole-live
guard coverage, ensuring the test fails when the sibling guard is removed or
degraded even if its alias is renamed.
In `@packages/store-libsql/test/schema-gate.test.ts`:
- Around line 89-118: The test should exercise a committed migration whose
schema-version update affects zero rows, not the existing canonical-integer
validation. In the test “fails when the recorded version did not advance,” alter
the version-bump UPDATE used by admin.migrate (or intercept it) so its predicate
is guaranteed not to match, then assert rejection with SchemaMismatchError
specifically while preserving the migration DDL execution.
In `@postmortems/pr3.6-fence-provenance.md`:
- Around line 500-504: Update the bind-arity residual passage in the postmortem
so it no longer appears as an active “Still true” gap: preserve it as historical
context or mark it closed, and reference the canonical BUILD/audit identifier
for PR3.7’s classifier and 37/37 attributable audit. Ensure the final wording
does not claim that mechanisms fail to distinguish bind-arity failures.
In `@postmortems/pr3.6-final-defect-review.md`:
- Around line 483-495: Revise the verification summary to label the
restricted-environment pnpm verify run as incomplete because it had 11 failed
tests, and cite a separate successful unrestricted or CI run for the green
result. Update attestation to consume the verification command’s
machine-readable exit status and test totals instead of relying on prose in the
postmortem.
In `@postmortems/pr3.7-provenance-residual.md`:
- Around line 586-593: Reconcile the mutation-audit figures in the inventory
paragraph with the live mutation count and clean-tree audit recorded around the
referenced section. Update the verdict and attributable totals to the final
registry/attestation-derived count, or explicitly label the existing figures as
an interim milestone; ensure both sections use the same authoritative mutation
count.
In `@postmortems/TEMPLATE.md`:
- Around line 54-70: Update the “Mechanism audit” table in TEMPLATE.md to define
its evidence column as either an executed false-negative example or an exact
construction rejection for rung-1 mechanisms. Revise the surrounding
instructions and attestation requirements so each mechanism must provide one of
these two evidence forms, rejecting prose-only entries while preserving the
existing distinction between syntactic checks and genuine rung-1 mechanisms.
In `@scripts/clock-lint.py`:
- Around line 46-50: Extend the CALLS pattern in the clock-lint checker to
include MySQL’s curdate and curtime function names alongside the existing
dialect-specific clock functions. Preserve the current matching behavior and
formatting while ensuring both functions are recognized.
- Around line 61-81: Update the lint loop around CLOCKS.finditer to also detect
bare meta and fake_now_ms reads, not only raw clock calls. Extend the existing
violation matching and reporting so these identifiers are rejected in store SQL
while preserving the time.ts exemption and current source-lexing behavior.
In `@scripts/deferral-lint.py`:
- Around line 45-51: Make the harvesting logic in the deferral lint entry parser
account for every bullet matching ^\s+-: ensure each resolves to exactly one PR
entry, and flag deferral-bearing bullets with no matching entry instead of
silently skipping them; recognize alternate PR bullet markers such as `* **PR…`
consistently. Update `BAD_CASES` in `scripts/lint-selftest.py` with orphan and
alternate-marker fixtures, and add the promised `GOOD_CASES` near miss for
deferral prose inside a live entry.
In `@scripts/fragment-lint.py`:
- Around line 12-18: Replace the hand-rolled argv/root resolution in
fragment-lint.py with validated_root(args, default, 'fragment-lint'), and
replace the per-store traversal with store_typescript_sources(root,
'fragment-lint') so invalid roots, options, missing packages, and empty harvests
fail through the shared helpers. Add an invocation covering an empty harvest to
BAD_INVOCATIONS in lint-selftest.py.
In `@scripts/gate-lint.py`:
- Around line 98-102: Replace the whitespace-exact BASE_RUNNER_BODY comparison
used by has_base_runner with parsed workflow validation. Identify an active
base-gate step whose command list invokes gate-lint.py with --run-base and
passes the head and base tree operands, preserving the intended check without
duplicating the ci.yml text.
- Around line 44-64: Unify the CLI parsing in gate-lint.py around an
argparse-style definition covering the default [root] [base], --run-base HEAD
BASE, and --list-checkers ROOT modes, preserving their existing validation and
behavior. Stop silently discarding unknown dash-prefixed arguments so misspelled
options are rejected. Add an unknown-option case to BAD_INVOCATIONS in
lint-selftest.py to verify refusal of unrecognized flags.
- Line 501: The gate-lint rules contain undocumented exemptions. In
scripts/gate-lint.py lines 501-501, remove the inline Path(__file__).name
subtraction so gate-lint.py follows the normal NOT_IN_GATE handling; in
scripts/gate-lint.py lines 536-538, replace the hard-coded lint-selftest.py skip
with a declared EXEMPT/NOT_IN_GATE-style entry that includes its reason, and
update both checks to use that declaration.
In `@scripts/mutation-probe.py`:
- Around line 986-1003: The four fault-specific matcher assignments in the
matcher-selection logic violate Ruff E731. Replace each lambda assigned to
matcher for ignore-file, ignore-full-name, ignore-marker, and
match-marker-substring with a nested def that preserves the same parameters,
comparisons, and message checks.
- Around line 1128-1143: Extend self_test(check_live_inventory=True) to compare
the interpolated ? placeholder counts in each mutation’s find and replace
strings, failing mismatches by default while honoring an explicit entry-level
declaration for intentional differences. Add paired mutation fixtures covering a
deliberately failing arity change and a matching-arity replacement that passes,
and ensure the check runs in the existing live-inventory loop.
In `@scripts/review-attest.sh`:
- Around line 385-395: Update the completion check around the `grep -qx 'tokens
used'` condition to require `tokens used` as the log’s final relevant line, not
merely anywhere in `CODEX_LOG`. Strengthen the abort classification in the
adjacent `tail -5` scan to catch non-prefixed stream failures such as the
documented 429 abort. Extend `--check-postmortem` coverage with completed and
aborted log fixtures proving only genuinely completed reviews attest
successfully.
In `@scripts/review-bot-lint.py`:
- Around line 105-123: Update the caller of red_pair_policy to invoke it only
when rule_synopsis reports a well-formed synopsis, not merely when the returned
body is non-empty; preserve the existing invalid-synopsis error so malformed
red-test policies are refused without a traceback. In scripts/lint-selftest.py,
add a red_pair_rule BAD_CASES variant whose synopsis omits the “Pass for ” arm
and assert the arms error via refusal_problem.
In `@scripts/session-state.sh`:
- Around line 132-140: Update the NOT_IN_GATE exemption reason for
scripts/session-state.sh to state that it grades the live session rather than a
working tree, so pnpm verify cannot run it. Keep the script’s existing pass/fail
and unusable-input behavior unchanged, and modify only the recorded exemption
metadata used by gate-lint.py.
---
Duplicate comments:
In `@scripts/deferral-lint.py`:
- Around line 45-69: Fix the Ruff violations in the deferral-lint loop: rename
the ambiguous loop variable l used in the enumerate and sub-bullet loops to a
descriptive name, updating all references, and remove the unnecessary f-string
prefix from the final clean-status print. Preserve the existing lint behavior
and output.
In `@scripts/source_lex.py`:
- Around line 258-270: Update _sql_quote_end to remove backslash escape handling
and recognize only doubled quotes as SQL string escapes, allowing a quote after
a backslash to terminate the literal. Add the provided backslash-and-NOW()
scenario to BAD_CASES to verify executable SQL after the terminator is still
checked.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 22b86ab8-8faa-47ef-bb36-a8947e4ee822
📒 Files selected for processing (108)
.claude/skills/pr-gate/SKILL.md.coderabbit.yaml.github/review-bot-rules/README.md.github/review-bot-rules/checks-must-be-able-to-fail.md.github/review-bot-rules/dialect-portability.md.github/review-bot-rules/docs-track-behaviour.md.github/review-bot-rules/fence-gates-every-write.md.github/review-bot-rules/guard-needs-an-executable-twin.md.github/review-bot-rules/mechanism-not-point-fix.md.github/review-bot-rules/no-one-shot-flags.md.github/review-bot-rules/one-instant-per-batch.md.github/review-bot-rules/red-test-before-fix.md.github/review-bot-rules/single-representation.md.github/review-bot-rules/test-determinism.md.github/workflows/ci.yml.gitignore.greptile/config.json.greptile/rules.mdAGENTS.mdBUILD.mdCLAUDE.mdDESIGN.mdLICENSEbiome.jsonpackage.jsonpackages/conformance/package.jsonpackages/conformance/src/fault-matrix.tspackages/conformance/src/fixture.tspackages/conformance/src/index.tspackages/conformance/src/invariants.tspackages/conformance/src/poison-matrix.tspackages/conformance/src/suite.tspackages/conformance/test/clock-jitter.test.tspackages/conformance/test/fault-matrix.test.tspackages/conformance/test/fence-provenance-regressions.test.tspackages/conformance/test/fixture-libsql.tspackages/conformance/test/invariant-checkers.test.tspackages/conformance/test/legacy-rows.test.tspackages/conformance/test/mutation-verdict.tspackages/conformance/test/poison-matrix.test.tspackages/conformance/test/poison-oracle-meta.test.tspackages/conformance/test/regressions.test.tspackages/conformance/test/replay-after-the-world-moved.test.tspackages/conformance/test/wake-witness-surface.test.tspackages/core/package.jsonpackages/core/src/contract.tspackages/core/src/errors.tspackages/core/src/fenced-batch.tspackages/core/src/index.tspackages/core/src/launch.tspackages/core/src/ports.tspackages/core/src/primitives.tspackages/core/src/types.tspackages/core/src/validate.tspackages/core/test/fenced-batch.test.tspackages/core/test/retry.test.tspackages/core/test/user-name.test.tspackages/driver/package.jsonpackages/driver/src/http.tspackages/driver/src/loop.tspackages/driver/src/tick.tspackages/driver/test/chaos-process.test.tspackages/driver/test/e2e.test.tspackages/driver/test/http-hardening.test.tspackages/driver/test/loop.test.tspackages/driver/test/tick.test.tspackages/harness/package.jsonpackages/harness/src/ids.tspackages/harness/src/rng.tspackages/sdk/package.jsonpackages/sdk/src/context.tspackages/sdk/test/event-regressions.test.tspackages/sdk/test/replay-equivalence.test.tspackages/sdk/test/review-regressions.test.tspackages/sdk/test/run-worker.test.tspackages/store-libsql/package.jsonpackages/store-libsql/src/admin.tspackages/store-libsql/src/executor.tspackages/store-libsql/src/fragments.tspackages/store-libsql/src/index.tspackages/store-libsql/src/schema.tspackages/store-libsql/src/store.tspackages/store-libsql/src/testing.tspackages/store-libsql/test/await-event-regressions.test.tspackages/store-libsql/test/generated-selection.test.tspackages/store-libsql/test/query-plans.test.tspackages/store-libsql/test/schema-gate.test.tspackages/store-libsql/test/schema.test.tspackages/store-libsql/test/testing.test.tspostmortems/TEMPLATE.mdpostmortems/pr3.6-batch-fence-plan.mdpostmortems/pr3.6-fence-provenance.mdpostmortems/pr3.6-final-defect-review.mdpostmortems/pr3.7-provenance-residual.mdscripts/batch-lint.pyscripts/clock-lint.pyscripts/deferral-lint.pyscripts/fragment-lint.pyscripts/gate-lint.pyscripts/lint-selftest.pyscripts/mutation-probe.pyscripts/review-attest.shscripts/review-bot-lint.pyscripts/session-state.shscripts/source_lex.pyscripts/spec-ledger.pyspecs/Scheduler.tlatsconfig.base.json
💤 Files with no reviewable changes (1)
- packages/store-libsql/src/index.ts
Ports every scheduler write onto explicit post-transition provenance and closes the scheduler, SDK, task-realm, and verification gaps found while proving that each mutation reaches only its owning verdict.
review-findings: 430
What changed
fence_stampandfence_at_ms. Every follow-on is keyed to the winning post-transition row and its database-time instant.FencedBatchor a documented lease-fenced equivalent. Successor identity, activation, replay, cancellation, suspension, events, retries, and legacy rows now carry executable conformance coverage.rescheduleandsuspend, relative and absolute wakes now share one SQL statement inventory and bind arity. Bound mode data selects the wake representation instead of TypeScript choosing different SQL under one crash-injection address.Promise.reject(undefined)cannot be confused with fulfillment, and the healthy-progress oracle checks the invocation responsible for progress in both ambient and targeted modes.DESIGN.mdis the behavioral contract.BUILD.mdrecords shipped mechanisms and named deferrals. The postmortems added on this branch contain the incident catalogue, red/green evidence, recurrence analysis, and executed false-negative boundaries.Review record
The branch catalogue contains 593 findings: 430 review-caught and 163 self-caught. Repository machinery therefore found 27.5%; outside review found 72.5%. The final exact-attribution addendum contains 151 findings, 103 self-caught (68.2%) and 48 review-caught (31.8%). The cumulative fix-induced count is 200.
The final repair sequence includes:
3f5a487red /4e54becgreen — completion-origin, one-read timeout, own wake discrimination, bind-brand ownership, and the remaining collision/live-enrollment gaps.8b654ffred /4e54becgreen — terminal Linux process snapshots in session-state evidence.d87bc53red /5f420c0green — exact no-detail assertion classification, nested-symbol ownership, and decisive SDK marker placement.0a24790red /98c3deegreen — residual mutation-attribution, static-title, generated-syntax, and wrong-path gaps.be917fared /fafcd13green, followed bye21ffdbred /fc9171dgreen — lexical binding preflight, one routing authority, erased type-only imports, runtime class heritage, and proof that rejection occurs before checkpoint or worktree creation.a00fc27— final mutation-attribution closeout and the clean 419/419 exact audit checkpoint.67a5c0dred /cbbb70dgreen —Promise.reject(undefined)settlement ambiguity and multiple SQL/bind shapes behind one batch label.25f5849and2023def— isolate the two settlement owners and make the ambient mutation attack the undefined-rejection branch itself. The first two green checkpoints exposed wrong-path mutation credit;2023defis the self-caught repair.d6f3b22— refresh the pinned TLC v1.8.0 prerelease asset digest from GitHub's authoritative release metadata without weakening checksum enforcement.5cf87d5red audit /1d005degreen — preserve the fixed wake SQL signature inside the two exact-ceiling timestamp mutants, so each is killed only by its declared timestamp verdict.Every accepted correctness finding has a demonstrated red checkpoint, a green repair, a prevention mechanism, recurrence analysis, an executable false-negative boundary, and fix-induced accounting. Finding 270's product placement was already correct; its executed old-test false negative and the new artifact-order proof are the red/green evidence for the mechanism test itself. Findings 271 and 272 are the two final simplification findings; findings 273 and 274 record the mutation-attribution wrong paths those repairs exposed.
reviews-abandoned: this continuation used API subagent reviews and did not produce the canonical exact-head Codex CLI log or review-workflow journal; all accepted findings and review evidence are recorded in the added postmortem
Verification record
Candidate:
a5775d4defd080990166953c64bc368afa5c4b35Historical, source-bound receipts retained for auditability:
pnpm verifyatc029b31: 80 files / 3,548 tests green.TLA_SCOPE=ciatc029b31: all five vacuity probes fired; 1,812,645 states generated, 486,377 distinct, zero queued, no error.a00fc27, with only the refreshed official artifact digest applied, completed all five liveness groups and safety: 111,832,051 states generated, 22,093,378 distinct, zero queued. This is historical evidence, not a substitute for the final exact-head receipt below.pnpm verify:fuzzat source-equivalentc484d9b: 2,000 seeds × 100 steps; 44 files / 3,119 tests green.a00fc27caught 419/419 exact owners with no survivor, stale entry, wrong-head result, or wrong-path credit. The two later settlement owners raised the registry to 421; the final exact-head audit below covers the complete expanded inventory.rescheduleandsuspendRunwith relative and absolute wakes.TLC checksum provenance:
d6f3b22, the exact-head gate failed closed before model checking: the repository pinnede22f8ffb4bacdea0a871f444dd94fe5fb0d8013b3388ae39e82e26f852c735d5, while the currently published asset hashed toeabd140a70f49eb9305a3bd3f3df944eddf87e5a90d329789085f8953a80533a.sha256:eabd140a70f49eb9305a3bd3f3df944eddf87e5a90d329789085f8953a80533afortla2tools.jar, updated 2026-08-21.d6f3b22pins exactly that published digest; the download still fails closed on any mismatch.Final-head receipts:
a5775d4defd080990166953c64bc368afa5c4b35was committed with a clean worktree before and after every final gate.pnpm verify: exit 0; 81 files / 3,212 tests passed.pnpm verify:tlawith pinnedeabd140a70f49eb9305a3bd3f3df944eddf87e5a90d329789085f8953a80533a: all five vacuity probes witnessed; safety and all five liveness groups passed; 111,832,051 states generated, 22,093,378 distinct, zero queued; exit 0.pnpm verify:fuzz: exit 0; 2,000 seeds × 100 steps; 45 files / 2,826 tests passed.pnpm verify:mutations: exit 0 at the candidate SHA; 421/421 exact catches, zero survivors, wrong-path credits, or infrastructure failures; all seven workers completed.scripts/review-attest.sh --check-postmortem: exit 0; all 274 findings accounted for. The PR-body trailer checker also passes this final draft.scripts/session-state.sh: clean; no repository processes, wait loops, extra worktrees, stashes, or uncommitted files.a5775d4defd080990166953c64bc368afa5c4b35, equal to the candidate. Hostedbase-gatepassed in 7s,tlain 2m10s, andverifyin 5m48s; CodeRabbit passed with its manual-review-required skip notice; publicadversarial-reviewpassed with the explicitABANDONED (see PR body)status required by this continuation's evidence record.Simplification pass
Accepted:
{result?, error?}settlement state with one frozen discriminated union constructed only after settlement. The same object is returned by the case result, every consumer narrows onstatus, and the healthy oracle names the responsible invocation.CASEarm, while database time remains the source for relative deadlines.sleepandawaitEventoperations so optional fields cannot describe impossible suspension combinations.attributeReplacedFailurewith a named expectation object, preventing silent argument swaps.isPartOfTypeOnlyImportOrExportDeclarationAPI and added a type-only namespace control.reject(undefined)classification.Rejected, with reasons:
FencedBatchoverloads or heterogeneous checker fixtures would create unrelated churn in an already large, audited branch.Ending.kindremains because DESIGN defines it as wire-contract data even though inline reconciliation does not trust it.PromiseSettledResult: target identity is part of the oracle's responsibility proof, and the source must freeze the complete canonical representation.fail's inherited retry and terminal SQL topologies was rejected in this closing diff: the split predates these repairs, and changing it safely needs its own protocol/topology and generated fault-matrix work. PR3.9 must declare or split such label variants while generating the complete compiled-signature corpus.gate-changes: no checker was weakened;
scripts/tla.shrefreshes only the pinned v1.8.0 artifact SHA-256 to the digest published by GitHub's release API, and exact digest verification plus the full exact-head TLC run remain mandatoryNamed deferrals
EndingFeedheartbeat-cutoff reconciliation.Stack
This PR targets
pr3.1(PR #11). After this merges into the stack base, PR #11 will receive a fresh exact-head gate and then merge tomain.