Uh oh!
There was an error while loading. Please reload this page.
docs(audits): append a dated erratum to the 2026-07 strictness ledger's flow-function row - #13170
Merged
Merged
Conversation
…'s flow-function row The row's closing sentence carries two defects measured since it was written: it teaches the broken-sweep predicate as a detector rather than a first filter (#12685), and it states the misspelled-`effect` causal direction backwards (#13096) — a dropped `effect: 'writes'` folds the run to `selected > 0, acted 0, unmeasured 0`, which SATISFIES the filter and lands the run INSIDE the candidate set rather than escaping it. This is a dated audit record, so the sentence is left byte-identical and a dated erratum note is appended beside the row instead (route B), following the `docs/audits/` correction-blockquote convention. Part of #13101 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LpRNHxWZgSUgVnFT9mQQo4
os-trump
marked this pull request as ready for review
August 29, 2026 07:14
os-trump
enabled auto-merge
August 29, 2026 07:14
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#13101
Route
The triage grading fixed the route at B — keep the dated record's sentence as written, append a dated erratum beside it. Verbatim, untranslated, from that grading (comment 5460587677):
Route A (rewriting the sentence in place) was therefore never attempted: it would leave a dated audit record no longer stating what the 2026-07 audit actually concluded, with nothing marking that it changed. Route C was rejected by the grading on the family's own severity argument — the claim propagates through the sentences the next author reads, and an audit ledger is exactly such a sentence.
The original sentence is byte-identical. The diff is 29 insertions / 0 deletions, verified by
git diff --numstatand by comparing the row's bytes against its HEAD blob.What the erratum corrects — both defects, not one
The grading warned that fixing only the vocabulary would leave a more authoritative wrong sentence behind, so the note covers both. Both were re-verified against the cited evidence on this ref rather than transcribed from the card.
1. The predicate is a FIRST FILTER, not a detector (#12685).
selected > 0 AND acted = 0 AND unmeasured = 0cannot separate a broken sweep from a healthy idempotent one — a sweep that re-selects the same records and gates each on "already handled" satisfies it on every run while that work stands. The discriminator is the per-node fold,FlowRunSummary.nodes[]/gates[]. Confirmed as the live vocabulary inpackages/spec/src/automation/execution.zod.ts, which now reads "is the FIRST FILTER for a broken sweep, not a verdict (#12685) ... What separates them is the per-node fold below".2. The causal direction is backwards (#13096). The ledger says a misspelled
effectis "precisely what keeps ... the broken-sweep query silent on the one run that needed it" — i.e. the run escapes the query. The measurement says the opposite:packages/services/service-automation/src/builtin/screen-nodes.tscomputesconst unmeasured = registration.effect === 'writes'and emitsmetrics: { unmeasuredEffect: true }only when that holds. A dropped declaration therefore emits no metrics at all, so the run folds toselected > 0, acted 0, unmeasured 0— which satisfies the filter.@moduleblock andpackages/spec/src/automation/flow-function.zod.ts's@moduleblock already carry the corrected reading: the run "lands INSIDE Surface flow run summaries (selected / acted / skipped) — a scheduled flow that does nothing is currently indistinguishable from one with nothing to do #4354's broken-sweep first filter, reading exactly like the broken sweep that filter exists to detect".packages/qa/dogfood/test/flow-function-effect.dogfood.test.tspins it end to end. Its header states the undeclared case "reportsacted: 0, unmeasured: 0on a run that wrote, which is indistinguishable from a dead sweep", and its pure-function case assertsunmeasured === 0with the comment that the broken-sweep query "is free to fire on this run".So the failure surfaces as a false positive inside the candidate set, not as a silence.
Placement — why beside the row rather than at the file head
docs/audits/has an existing correction convention, and it has two shapes, both head blockquotes: aCORRECTION (2026-06-16)heading in2026-06-dead-surface-disposition-plan.mdand a boldedSUPERSEDED — 2026-07-25.lead in2026-06-security-identity-property-liveness.md. Both invalidate a whole file. This is one clause in one row of a 1805-line ledger whose other 59 rows are unaffected, so a head note would overstate the correction.The file's own structure settles it: the
automation/triage table is already followed by a prose paragraph annotating a row (thetrigger-registry.zod.tsnote). The erratum takes that same position, directly under the table whose last row it corrects, in the blockquote form the directory's convention uses.This placement is also inert to the gate.
parseLedgerinpackages/spec/scripts/lib/strictness-ledger-doc.tsonly collects lines matchingline.startsWith('|')inside a triage or strip section, so a blockquote cannot become a phantom row or disturb coverage.Verification — union run at
c904f1f1e(the final commit)Gate family derived mechanically with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(no hand-fed paths; the script took its own change set from the merge base and confirmed the repo assertion against this checkout'sorigin). It derived 12 families. Exit codes were captured before any pipe; verdict lines are the gates' own.11 green. The one the card asked for specifically:
That third line is the proof the card asked for: the
.counts.mdcompanion is still current, so the prose erratum disturbed nothing the gate owns. Also green:check:cross-package-test-inputs,check:doc-authoring,check:empty-state,check:liveness,check:merge-driver,check:variant-docs,check-ci-filter-parity,check-cross-package-test-inputs,check-shard-attestation, andcheck:doc-formula-expressions(green only after building its prerequisites — it first reportedPREREQUISITE NOT METfor@objectstack/formulaand then@objectstack/lint, which is NOT MEASURED rather than red; afterturbo run buildfor both it reported✓ check:doc-formula-expressions self-test: 57 cases passedand three further clean verdict lines).1 not measurable locally.
scripts/check-test-completeness.mjsexits 1 printing its own usage line: it requires a turbo test log PATH as its first argument, plus optional--scheduledand--package-listfiles — all of them produced and supplied by the CI job. A local invocation without them measured nothing, so this is recorded as NOT MEASURED rather than as a failure.Repo-wide
pnpm lintwas not run; it is CI's, and this diff is a single markdown file underdocs/audits/with no ESLint population.Changeset
None, per the changeset gate's own text in
.github/workflows/pr-automation.yml, which names this case explicitly:The diff is one file under
docs/, publishes from no package, and releases nothing. Theskip-changesetlabel is applied to this PR.Scope
One file, no code change, no
content/docs/releases/touch. The row'sauthorableverdict, its "strict as of" claim and every generated count are untouched.Authored in session
session_01LpRNHxWZgSUgVnFT9mQQo4(durable copy, since a body edit normalises the footer below to its bare form).