@@ -2096,22 +2096,17 @@ describe('objectui#7896 — every package README is inside the scan surface', ()
20962096 } ) ;
20972097} ) ;
20982098
2099- describe ( 'wiring — the gate is reachable and a docs-only PR starts it' , ( ) => {
2100- const workflowDir = path . join ( repoRoot , '.github/workflows' ) ;
2101- const workflowPath = path . join ( workflowDir , 'repo-gates.yml' ) ;
2102- const workflowFiles = fs . readdirSync ( workflowDir ) . filter ( ( f ) => f . endsWith ( '.yml' ) ) ;
2103-
2104- /**
2105- * A workflow's YAML with whole-line comments removed — these headers name each
2106- * other's scripts in prose, and a scan that counted comments would report
2107- * duplicate homes that no file has.
2108- */
2109- const yamlOf = ( file : string ) =>
2110- fs
2111- . readFileSync ( path . join ( workflowDir , file ) , 'utf8' )
2112- . split ( '\n' )
2113- . filter ( ( line ) => ! / ^ \s * # / . test ( line ) )
2114- . join ( '\n' ) ;
2099+ describe ( 'wiring — the gate is reachable by name, and needs no install' , ( ) => {
2100+ // Retired with objectstack#25712: `has a workflow that gates pull requests,
2101+ // not just pushes`, `runs it in NO path-filtered workflow — the change that
2102+ // breaks it is docs-only`, `has exactly one home`, the install ORDER half of
2103+ // `needs no install`, and the header-count pin further down. Each read
2104+ // objectui's `repo-gates.yml`, this gate's only home, and that file runs
2105+ // nowhere under the monorepo: GitHub runs the root `.github/workflows/`
2106+ // alone, and no workflow there runs this gate. objectstack#25880 ports the
2107+ // `repo-gates.yml` gates (row 24 of the objectstack#25697 workflow roster)
2108+ // into the root `Lint UI` job and brings these pins back against that job, by
2109+ // path.
21152110
21162111 it ( 'is exposed as a root package script' , ( ) => {
21172112 const pkg = JSON . parse ( fs . readFileSync ( path . join ( repoRoot , 'package.json' ) , 'utf8' ) ) as {
@@ -2120,46 +2115,9 @@ describe('wiring — the gate is reachable and a docs-only PR starts it', () =>
21202115 expect ( pkg . scripts [ 'check:doc-types' ] ) . toBe ( `node ${ SCRIPT } ` ) ;
21212116 } ) ;
21222117
2123- it ( 'has a workflow that gates pull requests, not just pushes' , ( ) => {
2124- expect ( fs . existsSync ( workflowPath ) , 'a check nothing runs is not a gate' ) . toBe ( true ) ;
2125- const yaml = yamlOf ( 'repo-gates.yml' ) ;
2126- expect ( yaml ) . toMatch ( new RegExp ( `run:\\s*node\\s+${ SCRIPT . replace ( / [ . ] / g, '\\.' ) } ` ) ) ;
2127- expect ( yaml ) . toMatch ( / ^ \s * p u l l _ r e q u e s t : / m) ;
2128- expect ( yaml ) . toMatch ( / ^ \s * p u s h : / m) ;
2129- expect ( yaml ) . toMatch ( / ^ \s * m e r g e _ g r o u p : / m) ;
2130- } ) ;
2131-
2132- it ( 'runs it in NO path-filtered workflow — the change that breaks it is docs-only' , ( ) => {
2133- // The whole reason this is its own workflow. `ci.yml`'s type-check job
2134- // excludes `content/**` from the diff that decides whether its gates run, so
2135- // a PR editing only `content/docs/**` would start this gate nowhere.
2136- expect ( workflowFiles . length , 'the workflow directory scan returned implausibly few files' ) . toBeGreaterThan ( 5 ) ;
2137- for ( const file of workflowFiles ) {
2138- const yaml = yamlOf ( file ) ;
2139- if ( ! yaml . includes ( SCRIPT ) ) continue ;
2140- expect ( yaml , `${ file } runs ${ SCRIPT } behind a paths-ignore — a docs-only change would not start it` ) . not . toMatch (
2141- / p a t h s - i g n o r e : / ,
2142- ) ;
2143- expect ( yaml , `${ file } runs ${ SCRIPT } behind a paths filter — see objectui#3448` ) . not . toMatch ( / ^ \s + p a t h s : / m) ;
2144- }
2145- } ) ;
2146-
2147- it ( 'has exactly one home' , ( ) => {
2148- expect ( workflowFiles . filter ( ( f ) => yamlOf ( f ) . includes ( SCRIPT ) ) ) . toEqual ( [ 'repo-gates.yml' ] ) ;
2149- } ) ;
2150-
2151- it ( 'needs no install, so it can afford to run unfiltered' , ( ) => {
2118+ it ( 'needs no install: its import graph reaches no package' , ( ) => {
21522119 // The moment this needs `pnpm install` it stops being cheap enough to run on
21532120 // every PR shape, and the filter that follows is the hole.
2154- // Since objectui#12214 the home is `repo-gates.yml`, ONE job that installs
2155- // after its install-free gates: the property is now an ORDER -- this gate's
2156- // step sits before the job's `pnpm install` -- and no longer an absence.
2157- const yaml = yamlOf ( 'repo-gates.yml' ) ;
2158- const gateAt = yaml . indexOf ( `run: node ${ SCRIPT } ` ) ;
2159- const installAt = yaml . indexOf ( 'pnpm install' ) ;
2160- expect ( gateAt ) . toBeGreaterThan ( - 1 ) ;
2161- expect ( installAt === - 1 || gateAt < installAt , 'the gate step moved below the install step' ) . toBe ( true ) ;
2162-
21632121 // Walk the WHOLE static import graph, not just the gate's own first line.
21642122 // objectui#6092 converted this gate's entry guard to `./invoked-as.mjs`, a
21652123 // relative import — install-free, but not spelled `node:`. Asserting on the
@@ -2190,77 +2148,12 @@ describe('wiring — the gate is reachable and a docs-only PR starts it', () =>
21902148 expect ( external , `the gate's import graph reaches a package, so it needs an install: ${ external } ` ) . toEqual ( [ ] ) ;
21912149 } ) ;
21922150
2193- /**
2194- * objectui#7448. The header of this workflow described its scan surface as
2195- * "184 pages (144 `.mdx` + 40 `.md`)". Every part of that had drifted by the
2196- * time the card was worked — the gate's own verdict line reported 188 doc
2197- * files, and the `.md` half of the split was four short — and NO check went
2198- * red over the whole distance, because nothing fails on a stale number written
2199- * in a comment. That is the same lesson `UNGATED_DOCS`'s header in
2200- * `check-doc-snippet-types.mjs` records after both halves of its own copied
2201- * count went stale ("a pointer to the list now rather than a copy of its
2202- * length").
2203- *
2204- * Changing 184 to 188 would only have restarted that clock. This is what makes
2205- * the class fail loudly instead: the header may state the population — which
2206- * trees, which extensions — but never count it. `doc-fence-languages.yml`
2207- * carries the twin of this pin in its own test file; one gate, one home, so
2208- * each workflow's header is asserted beside its own gate rather than in a
2209- * shared sweep that would own neither.
2210- *
2211- * Deliberately narrow, and narrow in the same place as the other two copies:
2212- * a numeral qualifying a document-population noun, with at most two words
2213- * allowed to sit between the two. Issue references (ruled out at the pattern
2214- * level by the negative lookbehind, not by luck), `node-version`,
2215- * `timeout-minutes` and "the fifth instance of the shape" are all numbers
2216- * this header legitimately carries, and
2217- * none of them rots when a page is added or deleted. It also means the header
2218- * must not quote another header's stale literal verbatim — this pin cannot
2219- * tell a quotation from a claim, and refusing both is the safe direction for a
2220- * check on prose accuracy.
2221- *
2222- * ⭐ Those two intervening words are objectui#7888, and they are the sentence
2223- * above implemented rather than a new rule. This pin and its twin in
2224- * `check-doc-fence-languages.test.ts` both said "a numeral DIRECTLY
2225- * qualifying" and both coded it as strict adjacency, so a single adjective
2226- * defeated them. Measured: run verbatim over `check-links.yml`'s header as it
2227- * stood on `origin/main` at `83fe6e741` — a header carrying TWO live drifted
2228- * counts — the adjacent-only pattern reported ONE of them. It found the
2229- * sentence about the files the published site is built from, and scored the
2230- * one reading "holds 15 INTERNAL documents" clean — which was the count that
2231- * had drifted furthest (15 against a measured 17), because an adjective sat
2232- * between the numeral and the noun. The pattern below is the third copy's,
2233- * carried here verbatim (objectui#7825, PR objectui#7885,
2234- * `check-links-workflow.test.ts`), with the noun set unchanged; the word
2235- * DIRECTLY is gone from the sentence above because keeping it would only have
2236- * inverted the same gap between what this pin claims and what it does.
2237- *
2238- * Both twin headers were clean under BOTH patterns when this was carried
2239- * across, so this closes a proven hole rather than a live violation.
2240- */
2241- it ( 'its header states the population and never counts it — no count can rot here' , ( ) => {
2242- const header = headerComments ( fs . readFileSync ( workflowPath , 'utf8' ) ) ;
2243-
2244- // objectui#7901 — the floor first, or the assertion below is vacuous. The
2245- // count half cannot distinguish a header that carries no counts from a
2246- // header this pin has stopped reading; both score `[]`. Measured when this
2247- // was added, so it is latent rather than live: the extraction returned 4312
2248- // characters from this header, 10.8 times the floor. It read 4514 at 11.3
2249- // before objectui#7967 made this extraction strip the `#` markers: 202 of
2250- // those characters were markers, and none of them were prose.
2251- expect (
2252- header . length ,
2253- 'doc-component-types.yml: the header prose this pin reads came back empty or near-empty, so it asserted over nothing' ,
2254- ) . toBeGreaterThan ( MIN_HEADER_PROSE ) ;
2255-
2256- const counts = documentCounts ( header ) ;
2257- expect (
2258- counts ,
2259- `doc-component-types.yml's header states a page count (${ counts . join ( ', ' ) } ). Nothing fails when ` +
2260- 'it drifts, so it will. State the population — or point at the gate\u2019s own verdict line, which ' +
2261- 'prints the live figure on every run — instead of copying a number into a comment (objectui#7448).' ,
2262- ) . toEqual ( [ ] ) ;
2263- } ) ;
2151+ // The header-count pin (objectui#7448, widened by objectui#7888, floored by
2152+ // objectui#7901) retired with the pins above: it read `repo-gates.yml`'s
2153+ // header. The three controls below stay. They exercise `documentCounts` and
2154+ // `headerComments` on synthetic text and read no workflow, and once
2155+ // objectstack#25880 gives this gate a root home they are the controls of the
2156+ // pin that comes back against that file's header.
22642157
22652158 /**
22662159 * The positive control for the pin above — objectui#7914.
0 commit comments