Repository navigation
Commit 9a6f790
feat(scripts): dispatch-gates names check:durability-log-level for a file holding a catch and a declared durability-critical callee (#23612)
Fixes #23584
Clause-②: no
## What this does
`dispatch-gates --commands` now names `check:durability-log-level` for a
diff that touches a non-test TypeScript file holding a catch clause and
one of the callee names the guard declares in
`DURABILITY_CRITICAL_CALLEES`. PR #23567 ran every derived family (64 of
64, 0 unrun) and still went red on this guard, because the derivation
never named it for `packages/runtime/src/domains/automation.ts`.
## Why no path could name it (measured at `origin/main` 16abea8)
- The guard runs two rules. Its read-seam rule walks three package roots
it spells as literals, so cards touching those already reach it by path.
Its log-level rule walks `join(ROOT, 'packages')` and admits every
non-test `.ts` under it: 3206 tracked files, 34.8% of that root. Four
sibling gates walk that root the same way, and `bare-root-worklist.mjs`
records each of them REFUSE-WIDE in `CENSUS_REFUSE_WIDE`.
- The wide-population ruling (decision batch #43, 「同意」) keeps such a
root out of the matched column and out of `--commands`. So this PR does
not declare the bare root, or any spelling of it, as the guard's path
population.
- Correction to the card's mechanism note: the guard was `silent` for
`automation.ts` (it names the three read-seam roots, none of which cover
the file), not `undetermined`. The effect was the same: it was in no
block that reaches `--commands`.
## The freeze
`instrument-discipline.md:10`: 「工具位只有一个,先花在删除上;`dispatch-gates.mjs`
冻结,只在它喂的 workflow 坏了时碰。」 The triage grade (6183320441) found the
exception met: the derived list is the workflow it feeds, and it was
wrong. This PR does edit `dispatch-gates.mjs`, because no data-only
route exists:
- A `CHANGE_KIND_ROWS` row can only name a predicate the engine binds.
- The seven bound predicates are test-file, i18n-bundle-package,
metadata-form-module, gate-script, root-ts-program, error-code-literal
and http-status-emit. None of them reads a catch clause or the guard's
vocabulary.
So the frozen file gains one predicate, its vocabulary reader and one
binding line. This meets #23426's `Restart-when`, and #23426's docblock
paragraph rides this PR as a declared rider (see below).
## The change
| file | what |
|---|---|
| `scripts/pm/dispatch-gates.data.mjs` | One `CHANGE_KIND_ROWS` row
(`durability-seam` → `check:durability-log-level`), in the two content
precedents' voice: what the gate sweeps, why no path names it, the PR
#23567 round, no build, the repair direction and the WIDE trade. Also
its deletion criterion in the table docblock. |
| `scripts/pm/dispatch-gates.mjs` | `guardsADurabilityCriticalCall`, the
predicate. `declaredMapKeys` reads the keys of a `const NAME = new
Map([...])` table out of source: bracket depth is counted on the
comment-and-literal mask, and a non-identifier key THROWS.
`durabilityCriticalCallees` reads the guard's table through the guard's
discovered family, once per process, and throws loudly when the gate or
the table is gone. Plus the `'durability-seam'` binding and the
`maskCommentsAndLiterals` import. |
| `scripts/pm/dispatch-gates.self-test.mjs` | 43 cases: 7 for the
reader, 2 for the vocabulary refusals, 16 for the predicate limbs
through an injected vocabulary, 5 on the live tree (specimen, control,
discrimination held at a tenth), and 13 for the rendered section, table,
runnable union and STALE. |
| `scripts/check-durability-degradation-log-level.mjs` | Comment only: a
docblock section naming the second reader of
`DURABILITY_CRITICAL_CALLEES`. ⛔ Detection logic untouched. The guard is
not narrowed or weakened. |
**What the predicate matches.** A file matches when it is non-test
TypeScript (the precedents' extension set, without `.d.ts`), holds a
catch clause (a promise `.catch(` is not one), and spells one of the
guard's declared callee names as a whole word. All three are read from
the comment-masked source. The names are read from the guard's own
source and are never copied, so a callee added there lands in this net
on the next run.
## Measured: why this net and not the PM's catch-only guess (16abea8,
3441 non-test TS files)
| predicate | files | covers the 28 files holding the guard's 46
log-level seams | precision | fires on the last 300 first-parent commits
on main |
|---|---|---|---|---|
| catch clause alone | 705 (20.5%) | 28 of 28 | 4.0% | 169 (56.3%) |
| catch clause + declared callee (this PR) | 43 (1.2%) | 28 of 28 |
65.1% | 72 (24.0%) |
The commit column judges today's content of the paths each commit
touched. The catch-only net fires for 83% of the commits that touch
package TypeScript at all. That is the REFUSE-WIDE trade under another
name, so this PR declines it. The guard takes about 5.7 s of wall time
on this tree (two runs: 5.82 s and 5.69 s) and needs no build. That is
the price of a wasted run, against a CI round trip for a miss.
What it cannot see, and says so in its docblock:
- A file with no content on disk answers false, as with both precedents.
- A diff that deletes the last declared call from a function named in
`FAILURE_PROPAGATION_SITES` strands that entry. One such entry sits
outside the read-seam roots today.
## Before / after `--commands` (`--repo objectstack-ai/objectstack`)
- `packages/runtime/src/domains/automation.ts`: **47 at 16abea8 → 48
at 7195bc6 and at 67a8400**. The one added line is `pnpm
check:durability-log-level`; the control `route-envelope` stays at 1.
- Control `packages/services/service-storage/src/storage-routes.ts`
holds catch clauses and no declared callee: **51 → 51**, byte-identical,
`durability` 0.
## Reverse verification (one ablation, at head 7195bc6)
`node scripts/ablation-replace.mjs` swapped the binding
`'durability-seam': guardsADurabilityCriticalCall` for
`'durability-seam': () => false`. The anchor went 1 → 0 and the
replacement 0 → 1. Under that mutation:
- `--commands` on `automation.ts` printed 47 commands, with `durability`
0.
- `dispatch-gates --self-test --fast` exited 1, with **10 of 1884 cases
failed**. Among them: "through the whole table, the specimen derives the
durability guard" and "the runnable union carries the durability guard
for the specimen".
The restore was proven: blob after restore `c4656786dbae` equals the
HEAD blob, and `git diff HEAD` was empty. Unmutated, the same battery
reads 1884 of 1884.
## Population declaration (mechanism note A5): not added
The acceptance does not need it, and it would not hold:
- A `wide-population` marker moves a family into the declared column,
which is outside `--commands`.
- `widePopulationRefusal` refuses a marker on a gate that names paths
its reason does not account for, and this guard names its three
read-seam roots.
- `bare-root-worklist.mjs` cannot discover the `join(ROOT, 'packages')`
call spelling, so its self-test owes no row. It stayed green: 82 live
rows, 47 recorded verdicts, none stale or missing.
## Rider: #23426 (prose only; ⛔ the value line does not move)
The first paragraph of the `CONTRACT_REVIEW_TIER` docblock, **before**:
> The single source of truth for the model tier the PM lane's governance
reads — clause ②'s CONTRACT-REVIEW tier: the tier the clause-② REVIEW
runs at, both halves of it — the spec and skills lanes' review of every
round they deliver (a card that WIDENS a published accept set or the
public surface is spec-lane work, whichever seat found it; a card that
only NARROWS one is not, and owes one contract-review-tier review before
the queue while staying in its lane) and the `Served-tier:` line every
`## Contract review` record carries. The BUILD of such a card is at the
default judgment tier, so this constant is a review tier and never a
dispatch mandate.
**After**:
> The single source of truth for the model tier the PM lane's governance
reads — clause ②'s CONTRACT-REVIEW tier: the tier a contract review runs
at when the face that made it owed is a published schema or governed
rules text, and the `Served-tier:` line that review's `## Contract
review` record carries. The review is owed by SURFACE, never by lane,
and served at the tier of the face that made it owed (ruling record
6159870311, letter B′ with C): `reviewFace` in `record-recognisers.mjs`
holds the mapping, and a review owed ONLY by a `Clause-②: yes`
declaration is served at `TIER_DEFAULT` by the lane seat, as its own
review of record. No lane names this tier. As the `--tier` note spells
it, a card that WIDENS a published accept set or the public surface is
spec-lane work, whichever seat found it; a card that only NARROWS one is
`Clause-②: no`, stays in its lane, and owes one contract-review-tier
review before the queue. The BUILD of such a card is at the default
judgment tier, so this constant is a review tier and never a dispatch
mandate.
The rest of the docblock is unmoved: the retirement rule and the quoted
rulings. Rider acceptance, at head 7195bc6 (the fast tier and
`check:pm-dispatch-gates` re-read at 67a8400):
- `grep -c "spec and skills lanes" scripts/pm/dispatch-gates.mjs` prints
0.
- `node scripts/pm/record-recognisers.mjs --self-test` exits 0 (165
cases).
- The `dispatch-gates` self-test, fast tier, exits 0 (1884 cases).
- `pnpm check:pm-dispatch-gates` exits 0.
- Both tiers exit 0 at 7195bc6 (2144 cases), as required when the data
file is touched.
#23426 remains open; no keyword in this body acts on it. The seat
decides whether this landing discharges it.
## Gates (local, final head 67a8400: 7195bc6 merged with `origin/main`
8d05456, whose 4 incoming commits touch none of these files)
Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` from the merge base: 32 commands, the same
list at both heads. All 32 were run at 67a8400, each exit code captured
before any pipe. `--ran` reconciles: 32 derived, 32 run, 0 NOT-MEASURED.
- **31 exited 0:** `check:` `agent-test-spelling`, `bash32-floor`,
`cli-command-ids`, `cross-package-test-inputs`,
`declared-population-live`, `driver-memory-census`,
`durability-log-level`, `entry-guard`, `gitlink-declared`, `nul-bytes`,
`parse-guard`, `pnpm-filter-targets`, `ratchet-remedy-authority`,
`refd-timer-probe`, `swallow-census-controls` and `watch-hint-literal`,
plus `bare-root-worklist.mjs --self-test`, `check-ci-filter-parity`,
`check-comment-mask-corpus`, and the run and `--self-test` modes of
`check-closing-keyword-parity`, `check-declaration-mirrors`,
`check-scripts-symbol-anchors`, `check-self-test-wired`,
`check-self-test-workflow-commands` and `check-whole-set-label-write`.
- **`pnpm check:pm-dispatch-gates` exited 0** on its fast tier, the tier
CI runs on a PR: 1884 cases, 305 s at 67a8400. Both tiers (`--slow`)
also exited 0 at 7195bc6: 2144 cases, 1196 s. They were not re-run
after the merge, which moved none of these files.
`pnpm exec eslint --no-inline-config` on the four changed files exits 0.
The control-byte self-scan is empty. Every family CI runs is read from
this PR's check-runs.
## Acceptance notes
- **Out of scope, reported to the seat.** A diff to the guard's own
log-level baseline, `scripts/durability-degradation.baseline.json`,
still derives no `check:durability-log-level`; `--commands` on that path
prints 0. The guard spells that path as `join(ROOT, 'scripts',
'durability-degradation.baseline.json')`, which builds no hint, while
its sibling read-invention baseline has a whole-string constant and does
reach it.
- **Not fixed here.** The fix is a one-line whole-string constant in the
guard, which is outside this claim's surface (the guard is comment-only
here).
---
_Generated by [Claude
Code](https://claude.ai/code/session_01ESFcvW3staenyBCGq7kcDH)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent b1e9280 commit 9a6f790
4 files changed
Lines changed: 322 additions & 8 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
318 | 318 | | |
319 | 319 | | |
320 | 320 | | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
321 | 329 | | |
322 | 330 | | |
323 | 331 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
866 | 866 | | |
867 | 867 | | |
868 | 868 | | |
| 869 | + | |
| 870 | + | |
| 871 | + | |
| 872 | + | |
| 873 | + | |
| 874 | + | |
| 875 | + | |
| 876 | + | |
| 877 | + | |
869 | 878 | | |
870 | 879 | | |
871 | 880 | | |
| |||
990 | 999 | | |
991 | 1000 | | |
992 | 1001 | | |
| 1002 | + | |
| 1003 | + | |
| 1004 | + | |
| 1005 | + | |
| 1006 | + | |
| 1007 | + | |
| 1008 | + | |
| 1009 | + | |
| 1010 | + | |
| 1011 | + | |
993 | 1012 | | |
994 | 1013 | | |
995 | 1014 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
446 | 446 | | |
447 | 447 | | |
448 | 448 | | |
449 | | - | |
| 449 | + | |
450 | 450 | | |
451 | 451 | | |
452 | 452 | | |
| |||
10571 | 10571 | | |
10572 | 10572 | | |
10573 | 10573 | | |
| 10574 | + | |
| 10575 | + | |
| 10576 | + | |
| 10577 | + | |
| 10578 | + | |
| 10579 | + | |
| 10580 | + | |
| 10581 | + | |
| 10582 | + | |
| 10583 | + | |
| 10584 | + | |
| 10585 | + | |
| 10586 | + | |
| 10587 | + | |
| 10588 | + | |
| 10589 | + | |
| 10590 | + | |
| 10591 | + | |
| 10592 | + | |
| 10593 | + | |
| 10594 | + | |
| 10595 | + | |
| 10596 | + | |
| 10597 | + | |
| 10598 | + | |
| 10599 | + | |
| 10600 | + | |
| 10601 | + | |
| 10602 | + | |
| 10603 | + | |
| 10604 | + | |
| 10605 | + | |
| 10606 | + | |
| 10607 | + | |
| 10608 | + | |
| 10609 | + | |
| 10610 | + | |
| 10611 | + | |
| 10612 | + | |
| 10613 | + | |
| 10614 | + | |
| 10615 | + | |
| 10616 | + | |
| 10617 | + | |
| 10618 | + | |
| 10619 | + | |
| 10620 | + | |
| 10621 | + | |
| 10622 | + | |
| 10623 | + | |
| 10624 | + | |
| 10625 | + | |
| 10626 | + | |
| 10627 | + | |
| 10628 | + | |
| 10629 | + | |
| 10630 | + | |
| 10631 | + | |
| 10632 | + | |
| 10633 | + | |
| 10634 | + | |
| 10635 | + | |
| 10636 | + | |
| 10637 | + | |
| 10638 | + | |
| 10639 | + | |
| 10640 | + | |
| 10641 | + | |
| 10642 | + | |
| 10643 | + | |
| 10644 | + | |
| 10645 | + | |
| 10646 | + | |
| 10647 | + | |
| 10648 | + | |
| 10649 | + | |
| 10650 | + | |
| 10651 | + | |
| 10652 | + | |
| 10653 | + | |
| 10654 | + | |
| 10655 | + | |
| 10656 | + | |
| 10657 | + | |
| 10658 | + | |
| 10659 | + | |
| 10660 | + | |
| 10661 | + | |
| 10662 | + | |
| 10663 | + | |
| 10664 | + | |
| 10665 | + | |
| 10666 | + | |
| 10667 | + | |
| 10668 | + | |
| 10669 | + | |
| 10670 | + | |
| 10671 | + | |
| 10672 | + | |
| 10673 | + | |
| 10674 | + | |
| 10675 | + | |
| 10676 | + | |
| 10677 | + | |
| 10678 | + | |
| 10679 | + | |
| 10680 | + | |
| 10681 | + | |
| 10682 | + | |
| 10683 | + | |
| 10684 | + | |
| 10685 | + | |
| 10686 | + | |
| 10687 | + | |
| 10688 | + | |
| 10689 | + | |
| 10690 | + | |
| 10691 | + | |
| 10692 | + | |
| 10693 | + | |
| 10694 | + | |
| 10695 | + | |
| 10696 | + | |
| 10697 | + | |
| 10698 | + | |
| 10699 | + | |
| 10700 | + | |
| 10701 | + | |
| 10702 | + | |
| 10703 | + | |
| 10704 | + | |
| 10705 | + | |
| 10706 | + | |
| 10707 | + | |
| 10708 | + | |
| 10709 | + | |
| 10710 | + | |
| 10711 | + | |
| 10712 | + | |
| 10713 | + | |
| 10714 | + | |
| 10715 | + | |
| 10716 | + | |
| 10717 | + | |
| 10718 | + | |
| 10719 | + | |
| 10720 | + | |
| 10721 | + | |
| 10722 | + | |
| 10723 | + | |
| 10724 | + | |
| 10725 | + | |
| 10726 | + | |
| 10727 | + | |
| 10728 | + | |
| 10729 | + | |
| 10730 | + | |
| 10731 | + | |
| 10732 | + | |
| 10733 | + | |
| 10734 | + | |
| 10735 | + | |
| 10736 | + | |
| 10737 | + | |
| 10738 | + | |
| 10739 | + | |
10574 | 10740 | | |
10575 | 10741 | | |
10576 | 10742 | | |
| |||
10846 | 11012 | | |
10847 | 11013 | | |
10848 | 11014 | | |
| 11015 | + | |
10849 | 11016 | | |
10850 | 11017 | | |
10851 | 11018 | | |
| |||
11619 | 11786 | | |
11620 | 11787 | | |
11621 | 11788 | | |
11622 | | - | |
11623 | | - | |
11624 | | - | |
11625 | | - | |
11626 | | - | |
11627 | | - | |
11628 | | - | |
| 11789 | + | |
| 11790 | + | |
| 11791 | + | |
| 11792 | + | |
| 11793 | + | |
| 11794 | + | |
| 11795 | + | |
| 11796 | + | |
| 11797 | + | |
| 11798 | + | |
| 11799 | + | |
| 11800 | + | |
11629 | 11801 | | |
11630 | 11802 | | |
11631 | 11803 | | |
| |||
0 commit comments