Commit 43e928d
Fixes #21351
Clause-②: no
## What changes
`scripts/check-self-test-wired.mjs` gains the population source triage
directed (comment 5947041331): every root `package.json` alias whose
expansion carries `--self-test`. The existing gate is widened to its
stated purpose. No gate is added and no workflow is edited.
- **Membership** (`collectAliasDeclarations`). A root alias is a member
when its expansion self-tests a script. The expansion goes through the
same `expandAlias` the workflow half already uses, so `pnpm ALIAS`
chains count. A root alias is also a member when its own text has a
right-bounded `--self-test` that the anchor cannot attribute to a script
path. The roster is computed inside `collectPopulation` from the one
parse of `package.json` that the workflow extraction already does.
`package.json` is not read a second time.
- **Verdict** (`auditAliasPopulation`). For each member, every script
its expansion self-tests must be run with `--self-test` by some workflow
step or composite action. That can happen by path, through this alias,
or through any alias a step names. An existing `SELF_TEST_RUN_OTHERWISE`
row also counts. When neither holds, the gate reports
`[alias-self-test-not-run] pnpm ALIAS`, which names the alias and the
unrun script(s). A literal the anchor cannot attribute is reported as
`[alias-self-test-unattributed]`.
- **Allowlist** (`SELF_TEST_ALIASES_OUTSIDE_CI`, rows of `{ alias, why
}`, in the gate's own file). The list is **empty**: no alias qualifies,
because all 170 are wired. `auditAliasAllowlist` reports a row as red in
four cases:
- it has no reason;
- its alias no longer exists;
- its alias's expansion no longer carries `--self-test`;
- a workflow now runs every self-test the alias declares.
The remedy text refuses the allowlist as a way to clear a finding.
Judging whether a row is legitimate is marked ⛔ MAINTAINER-ONLY,
following the existing ledger's wording.
- **Floor.** `refusalFor` refuses a reading whose alias roster is empty
or absent ("the alias reader is broken"). This is the last arm, so the
sibling gate's refusal pins still hit the arms they hit before.
- ⛔ **`population` is unchanged.** That export means "the self-tests CI
runs", and `check-self-test-workflow-commands.mjs` spawns every member
of it. An alias that CI does not run has no place in that sweep. The
sibling's scope line still reads 232.
## Measured: objectstack `main` 23365ea (base) against this head
98d23b3
**Roster.** 170 root aliases carry `--self-test`, and for every one of
them each self-tested script is run with the flag by a workflow step:
- 153 aliases are named by a workflow directly.
- For the other 17, the script's self-test is run by path or through
another alias. For example, `check:adr-links` is not named, but
`check-links.yml` runs `node scripts/check-adr-links.mjs --self-test`.
- No alias is unwired and no literal is unattributable, so the allowlist
is empty.
- No current alias turned red, so no workflow edit is needed.
**Probes.** These are production runs of the gate on scratch copies of
`scripts/`, `.github/workflows`, `.github/actions` and `package.json`.
Only the gate file differs between the two columns: base blob c36931a
against head blob 89cf1f5.
| tree | base gate | this gate |
|---|---|---|
| unmodified | exit 0 | exit 0 |
| plus alias `check:pm-probe-unwired` = `node
scripts/pm/measurement-claim-triage.mjs --self-test`, named by no step |
exit 0 | exit 1, `[alias-self-test-not-run] pnpm check:pm-probe-unwired`
|
| `lint.yml` step `Issue-transfer door self-test` (`pnpm
check:pm-issue-transfer`) deleted | exit 0 | exit 1,
`[alias-self-test-not-run] pnpm check:pm-issue-transfer` |
## Pins
The new battery `declared alias population` has 22 cases. The battery
registry floor goes from 11 to 12.
- **Deleting the only step that runs an alias goes red and names the
alias.** This is pinned two ways:
- on pure inputs;
- end to end through `collectPopulation` on a fixture tree. That case
also asserts that the old named-population audit stays silent on the
same tree, so the hole and the repair are in one case.
- **An allowlisted alias stays green.** The row excuses only its own
alias: a second alias that declares the same script still goes red.
- **The current roster passes.** This is the production run on this
tree, which exits 0. `lint.yml` runs it on every PR. A self-test cannot
hold a tree verdict.
- **Stale allowlist rows go red:** a row for an alias that is gone, one
whose expansion lost `--self-test`, one whose self-tests a workflow now
runs, and one with no reason.
- **Crediting routes stay green:** an alias a step names, a chain alias
a step names, a script self-tested by path, and a script with a
`SELF_TEST_RUN_OTHERWISE` row.
- **Partial wiring still goes red.** A step running the script without
the flag goes red. A two-script alias with one script unrun names
exactly that one.
- **Membership:** chain aliases are members; `--self-test-extra` is not
the flag.
- **Unattributable literals go red:** `node scripts/l.mjs --json
--self-test` reports the alias as unattributed, while the attributed
spelling beside it does not.
- **`the exported population` battery:** it gains the empty and absent
roster refusal, and its floor goes from 8 to 9.
- **Composite-action fixture:** its `package.json` now carries one
self-test alias, because the shared reading refuses a tree that has
none. No step names that alias, so both of the battery's controls are
unchanged.
## Ablation
Both legs ran on the committed state 98d23b3 through
`scripts/ablation-replace.mjs`. For each leg:
- the anchor went from 1 hit to 0;
- the blob changed;
- the restore was proven: the blob equals the HEAD blob 89cf1f5 and
`git diff HEAD` is empty.
| leg | mutation | `--self-test` | production, this tree | production,
deleted-step tree |
|---|---|---|---|---|
| verdict | `const unrun = scripts.filter(...)` becomes `const unrun =
[]` | exit 1 (5 cases, including the deleted-step pin) | exit 0 | exit 0
|
| membership | the roster's membership condition becomes `false` | exit
1 (11 cases) | exit 1, refused: alias reader is broken | exit 1, refused
|
The first leg is the reason this matters. With the verdict ablated,
production on this tree and on the deleted-step tree are both green.
`--self-test` is therefore the only instrument for this rule, and
`lint.yml` runs it with the flag.
## Gates (head 98d23b3; patch round 2 at `03d397c714`: 57 derived, 57
run, all exit 0, reported in `5948256806`)
Derivation: `node scripts/pm/dispatch-gates.mjs --repo
objectstack-ai/objectstack --commands`, with no paths. It gives 29
commands, set-equal to the seat's lead. All 29 exit 0:
- `check-ci-filter-parity` (run only, not edited)
- `check-closing-keyword-parity`, production and `--self-test`
- `check-comment-mask-corpus`
- `check-declaration-mirrors`, both modes
- `check-scripts-symbol-anchors`, both modes
- `check-self-test-wired`, both modes
- `check-self-test-workflow-commands`, both modes, population 232
- `check-whole-set-label-write`, both modes
- `pm/bare-root-worklist --self-test`
- `pnpm check:` agent-test-spelling, bash32-floor, cli-command-ids,
cross-package-test-inputs, driver-memory-census, entry-guard,
gitlink-declared, nul-bytes, parse-guard, pm-dispatch-gates,
pnpm-filter-targets, ratchet-remedy-authority, refd-timer-probe,
watch-hint-literal
`check:ratchet-remedy-authority` still classifies this file as
`refused`, with no live offer. The counts are the same as on base: 15
marked, 5 refused.
No package is touched, so no build closure, package tests or typecheck
are owed. The changeset is skipped because the change is under the
repo-root `scripts/`: the root package is private and nothing is
published.
## Acceptance notes
- **Four passages this change made false are corrected in this PR**
(patch round 2, `03d397c714`, comments only; the seat's ruling on the
dev's open question, per `5948256806`). They are three `lint.yml`
comment blocks (the `Issue-transfer door self-test` step, the
stale-`finding` sweep step, and the import-prerequisite module step) and
the `scripts/check-system-context-census.mjs` header paragraph. Each now
states the declared-alias population. A probe backs each sentence:
deleting the stale-finding step, or both census invocations, now reds.
No step, `run:` line or code moved: `yaml.parse` of the two `lint.yml`
versions is deep-equal, and the census script's comment-masked code is
identical. (Seat edit.)
- **Scope is the root `package.json`, as the card set it.** An alias in
a package's own `package.json` is outside this population.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01UtnxvdiN376GF3sgXwAw4d)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 11905a4 commit 43e928d
3 files changed
Lines changed: 453 additions & 28 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
563 | 563 | | |
564 | 564 | | |
565 | 565 | | |
566 | | - | |
567 | | - | |
568 | | - | |
569 | | - | |
570 | | - | |
571 | | - | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
572 | 574 | | |
573 | 575 | | |
574 | 576 | | |
| |||
1545 | 1547 | | |
1546 | 1548 | | |
1547 | 1549 | | |
1548 | | - | |
1549 | | - | |
1550 | | - | |
1551 | | - | |
1552 | | - | |
| 1550 | + | |
| 1551 | + | |
| 1552 | + | |
| 1553 | + | |
| 1554 | + | |
| 1555 | + | |
1553 | 1556 | | |
1554 | 1557 | | |
1555 | 1558 | | |
| |||
1584 | 1587 | | |
1585 | 1588 | | |
1586 | 1589 | | |
1587 | | - | |
1588 | | - | |
1589 | | - | |
| 1590 | + | |
| 1591 | + | |
| 1592 | + | |
| 1593 | + | |
| 1594 | + | |
| 1595 | + | |
1590 | 1596 | | |
1591 | 1597 | | |
1592 | 1598 | | |
| |||
0 commit comments