Repository navigation
Changed
- The CI test runtime budget checks each test, not the suite total
(specs/051-release-cut-green, FR-007 revision).- Why the total failed. The 465-second total had been raised three
times. Across 445 recent CI jobs, identical code ran 188–369 seconds: the
spread is one speed factor per runner, not the code. The total also missed
the class it exists for. Test files run about 2.8 at a time, so a test that
gains 165 seconds (PR #328) adds about 59 to the wall clock. Replayed on
all 445 jobs, the 465-second total caught none of those runaways. - The new check.
tools/suite-runtime-budget.mjsreads the suite's TAP.
It divides every top-level test by the run's speed factor, measured
againsttools/suite-runtime-reference.json, and fails any test over
TEST_CEILING_MS(100 seconds at reference speed). - Measured. It passes all 445 recorded jobs: the slowest normal test is
56.9 seconds at reference speed, 1.76× below the ceiling. It catches a
165-second runaway in one test in all 445, whether the runaway scales with
the runner or not. - Unaffected by growth. Adding tests does not change the check.
- Reported, not gated. The suite total goes to the log and the job
summary. - TAP artifact. Each leg uploads its TAP as
test-tap-node-<version>,
the input for refreshing the reference.
- Why the total failed. The 465-second total had been raised three
Fixed
-
Five validator defects reported against 0.45.0 (
specs/079-doc-validator-fidelity,
issues 584–588). Four remove false statements; one stops a blank template
from scoring as finished.- ENV001 and ENV002 match headings as STR003 does (FR-001).
## Setup steps
and## Environment variableswere "missing" although sentence case passed
STR003. Both validators now usedocHasSection: any case, section
numbers, synonyms (Getting Started,Env Vars). The generic synonyms
EnvironmentandConfigurationnow name a section only as the whole
heading (or followed byReference,Variables,(.env)…), for STR003 and
generatetoo:## Configuration Filesand## Production environment
no longer satisfy Environment Variables. - A brace pattern documents the files it expands to (FR-002).
`src/tests/{alpha,beta}.test.ts`and`foo.{test,spec}.ts`expand
one level (at most 64 paths) in DDF002 anddocguard diff; a missing
expansion is reported by its expanded path; spaces after the commas are
ignored. A brace glob (src/**/*.test.{js,jsx}) is one pattern matched as
a union; in a documented glob?is one character and**/also matches
no directory (src/**/*.test.jsdocumentssrc/a.test.js). - DDF001 reads negation over a list and removal verbs (FR-003–FR-005).
no CDK, Terraform or Pulumi stacks,We removed Terraform,migrated off,
was replaced byno longer count as documenting the technology, and a
Revision History, Changelog or Release Notes section is not read as a
Tech Stack claim (a#line in a code fence is not a heading).
replaced MySQL with PostgreSQLkeeps PostgreSQL live, and so do sentences
that only look negated:No Docker, Express serves the API,Removed all Redis keys,No changes to PostgreSQL, Redis or Express,No Docker or Redis caches sessions,We dropped Redis support. - An unedited scaffold is reported and not scored as readable
(FR-006–FR-009). New warning STR006: a canonical document that holds
nothing beyond the templateinitwrote it. Its docQuality checks all
fail, ALCOA+ Legible is a gap, and Machine markers does not count it. A
one-document project with a blank template scored docQuality 100%; it now
scores 0%. A placeholder owner or status alone is not reported
(generate --plan --writeleaves both); a reasoned
<!-- docguard:section … n/a — reason -->marker owns the document. A
documentdocs.rolesremaps is compared with its role's template. - The word
constructorno longer makes readabilityNaN(FR-012). The
syllable counter readObject.prototype.constructorfrom its exception
dictionary, so DQ004 and DQ005 fired on any document containing the word.
Every dictionary indexed by outside input is now null-prototype:
docguard explain constructor,docguard hooks --type constructorand
docguard agents --agent constructorno longer fail inside,init --with toStringis an unknown scaffolder, and an MCPtools/callnamed
constructoris an unknown tool. A Django REST Framework viewset whose base
is namedconstructorno longer crashesgenerate --plan.
- ENV001 and ENV002 match headings as STR003 does (FR-001).
-
A living spec reviewed long ago can complete its maintenance again
(specs/028-completion-revision-anchoring, FR-008–FR-010). Completion
reconciles from the spec's recorded revision, andreconcileread that
range's whole patch in one Git call capped at 5 MB. Spec 028's own
maintenance, recorded 83 commits before 0.45.0, was BLOCKED ("Patch exceeded
its byte budget") with no way forward. A range whose single read overflows
or times out is now read again in batches of changed paths, each under the
same 5 MB budget (a rename's two paths together, every path literal), keeping
only each file's derived links between batches. Coverage is complete and the
classifications match one unbounded read;range.batchesreports the reads.
The range from spec 028's recorded revision (763 files, 7.2 MB) now
reconciles in 4 batches. A range past every bound (one file's patch over
5 MB, 64 MB in total, two minutes, or the 5,000-file inventory) stays
BLOCKED and names the bound or the file. -
specs complete --sinceno longer skips reviewed history silently. With
a recorded revision,--sincereplaced it unconditionally, so a newer ref
dropped the commits in between from reconciliation and the outcome recorded
nothing about it;--helpdescribed the flag as used only when no revision
is recorded. The same or an older ref is accepted. A newer ref onHEAD's
history is accepted only when the recorded range is BLOCKED by a budget even
in batches, and the outcome then recordsnarrowedFrom(revision,
since,skippedCommits,reason) in the registry, and the spec's outcome
line saysNot reconciled: <revision>..<ref>. Any other--since— newer
over a reconcilable range, unrelated to the recorded revision, or with a
recorded revision that does not resolve (which namesspecs reanchor) —
blocks with SPC006 and writes nothing. A spec-text amendment alone still does
not qualify a living spec for maintenance; the source, test or canonical
change that implements it does.
Commits
- chore: re-anchor spec 079 to main after the squash merge of #590 (#591)
- chore: spec 079 implementation outcomes (verified) (#590)
- fix: validators agree on headings, braces, negation; blank templates not scored as finished (spec 079) (#589)
- [jules:test-gaps] cli/precision-evidence.mjs — two exports covered (#583)
- chore: maintenance outcomes for specs 028 and 051 (#580, #579) (#582)
- chore: review docs after specs 070-078; tag ci-reproducibility with its spec (#581)
- fix: reconcile over-budget ranges in batches; --since never skips silently (spec 028) (#580)
- fix: CI runtime budget is a per-test ceiling at reference speed (spec 051 FR-007) (#579)