Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
177 commits
Select commit Hold shift + click to select a range
58f9c6e
fonts: self-host Inter, Cascadia Mono and Source Serif 4
KubaO Sep 20, 2026
6170e07
diagrams: redraw the Monaco pair as DOT and fix label sizing
KubaO Sep 20, 2026
a9d7638
docs: ban "keeping it honest" and rewrite its three uses
KubaO Sep 20, 2026
340b770
source: write the cache-key separators as \0 rather than raw NUL bytes
KubaO Sep 20, 2026
be5c9de
fixture: add the stub fonts the template now preloads
KubaO Sep 20, 2026
057315c
docs: bring Pipeline-Stages back in step with the task graph
KubaO Sep 20, 2026
b637305
docs: stop Extending.md teaching the pattern 33624df banned
KubaO Sep 20, 2026
f385b31
docs: Building.md -- four gates, not three, and the Graphviz patch ex…
KubaO Sep 20, 2026
d6849c3
docs: complete the tool catalogue, which covered 7 of 15 scripts
KubaO Sep 20, 2026
c6ecc5f
docs: name the check subsystem, and fix four stale figures
KubaO Sep 20, 2026
705ccfe
WIP: repair the package paths, and four claims that contradict the tree
KubaO Sep 20, 2026
2edb0ce
builder: close out the plan docs and repair the README's stale facts
KubaO Sep 20, 2026
999597b
scripts: document the flags the headers omitted, and two stale figures
KubaO Sep 20, 2026
32c8135
test: document the fixtures and the invariant that just fired
KubaO Sep 20, 2026
1d5b8a0
README: say how to build the site
KubaO Sep 20, 2026
a1118ac
docs: review of the developer documentation over c9f2dfe0..a9d7638
KubaO Sep 20, 2026
0f2a438
discover: strip a leading BOM before parsing frontmatter
KubaO Sep 20, 2026
07bb679
config: scope the underscore exclude to _Images, not every _* directory
KubaO Sep 20, 2026
3e5575c
docs: publish AppGlobalClassObject at its conventional URL
KubaO Sep 20, 2026
56fa2d2
nav: require every page to declare its own permalink
KubaO Sep 20, 2026
c50ffec
docs: record the permalink rule and the AppGlobalClassObject fix
KubaO Sep 20, 2026
3310b7f
docs: record the authoring-only frontmatter keys and what they are for
KubaO Sep 20, 2026
e4bfc74
build: refuse to publish file types that are not on the allowlist
KubaO Sep 20, 2026
ab8e1ae
serve: print a failed build's cause chain, not just the top message
KubaO Sep 20, 2026
874896e
docs: cover the build's publish allowlist and three undocumented aborts
KubaO Sep 20, 2026
88c7c16
docs: correct stale counts and misattributed gates across the develop…
KubaO Sep 20, 2026
94c3450
docs: give the two worked example pages the heading levels the guide …
KubaO Sep 20, 2026
4e66554
docs: point local preview at serve.bat and explain the file:// trap
KubaO Sep 20, 2026
15ff547
docs: link Extending.md and the orphaned test/README.md from the entr…
KubaO Sep 20, 2026
b643013
ci: gate the deploy on the DOT diagram fit check, not just PRs
KubaO Sep 20, 2026
10e656e
docs: document check_links_diff's cases, sides and the invocations CI…
KubaO Sep 20, 2026
ca8b27e
docs: document where project styling lives and the dark-compilation s…
KubaO Sep 20, 2026
11b5eba
docs: publish the full axe-core upgrade sequence, not just the equiva…
KubaO Sep 20, 2026
3f2f852
docs: say what to change when the diagram-fit check fails
KubaO Sep 20, 2026
026610f
docs: replace generic and duplicated image alt text with real descrip…
KubaO Sep 20, 2026
eb4802b
docs: make the scheduler plan's fan-out samples obey the barrier rule…
KubaO Sep 20, 2026
66b3c48
docs: document what CI runs that a local build does not, and name the…
KubaO Sep 20, 2026
ae86cdb
docs: state one rule for rewriting a barrier's expected, and flag the…
KubaO Sep 20, 2026
b0653cb
docs: cover the heading-normalizer disarm trap, index registration, a…
KubaO Sep 20, 2026
1569e31
docs: point Extending at project styling and the a11y sample, and tab…
KubaO Sep 20, 2026
04ab4bf
docs: give the pull-request and screenshot images real alt text
KubaO Sep 20, 2026
5ab3c9c
docs: say precisely which stylesheet the project SCSS compiles into
KubaO Sep 20, 2026
d433cae
docs: note the copied alt text has since been corrected, so readers d…
KubaO Sep 20, 2026
d74c75f
fix stale case and category counts in check_links_diff comments
KubaO Sep 20, 2026
3c46379
docs: stop the scheduler plan claiming FIFO ordering makes merges com…
KubaO Sep 20, 2026
2c0c22c
move the DOT diagram fit comment above the step it explains
KubaO Sep 20, 2026
c1d4877
docs: checkChunks is an unindexed append, not an indexed write, and s…
KubaO Sep 20, 2026
d3c5f96
docs: name bundle_extra as the third publish-allowlist remedy, and wh…
KubaO Sep 20, 2026
4ffb67d
docs: add the name-the-fault-directly rule and fix the windup phrasin…
KubaO Sep 20, 2026
7c6a9f3
docs: fix a detached no_toc IAL, a skipped heading level, and seven d…
KubaO Sep 20, 2026
955fe8a
name bundle_extra as the third remedy in the publish refusal, and dem…
KubaO Sep 20, 2026
771c068
docs: reattach four detached no_toc IALs, one of which was leaking a …
KubaO Sep 20, 2026
025692b
docs: apply the directness rule and record the 'bites' substitution
KubaO Sep 20, 2026
245e989
notes: record the Wisdom exception and two prose rules
KubaO Sep 20, 2026
6a79600
review: use-case audit of the developer documentation
KubaO Sep 20, 2026
85185eb
eval: retain the documentation use-case harness
KubaO Sep 20, 2026
4d87460
docs: correct the list of highlighted fence languages
KubaO Sep 20, 2026
2e74de2
docs: link the use-case harness from the developer entry points
KubaO Sep 20, 2026
f0cc6f6
review: round-2 use-case audit, recovery and the URL contract
KubaO Sep 20, 2026
342824b
docs: teach the shipped table-wrapper rule instead of a duplicate plugin
KubaO Sep 20, 2026
abd5659
docs: document the root-only scope of the underscore exclusion rule
KubaO Sep 20, 2026
c7fb3b8
docs: correct Builder.md's claim that the vendored theme is pristine
KubaO Sep 20, 2026
0192b64
docs: give the four batch wrappers their real POSIX equivalents
KubaO Sep 20, 2026
071c1d6
docs: correct four entry points on check.bat, build.bat and the sched…
KubaO Sep 20, 2026
e1c38e7
docs: add book.bat failure triage to the PDF generation page
KubaO Sep 20, 2026
d4f7f63
vendor: correct the just-the-docs README's file counts, step numberin…
KubaO Sep 20, 2026
2bb915c
docs: mark BOOKPLAN.md as a Jekyll-era design record and map it to th…
KubaO Sep 20, 2026
673c68b
docs: fix gate order, wrapper location, the clone step, and the build…
KubaO Sep 20, 2026
75c86b0
docs: name the missing _pdf directory as the cause of a failed write …
KubaO Sep 20, 2026
ac2282c
docs: describe the page-count guard as the collapse floor it is
KubaO Sep 20, 2026
c8d6006
docs: add AppGlobalClassObject to the /tB/ URL contract
KubaO Sep 20, 2026
4ed8ac4
docs: document how to rename a heading without breaking its anchor
KubaO Sep 20, 2026
7764645
docs: replace Building.md's duplicated publish-allowlist remedies wit…
KubaO Sep 20, 2026
1b8e4db
docs: point the publish-allowlist remedies at the build-side enforcement
KubaO Sep 20, 2026
41839fa
docs: state what a builder change obliges in the documentation
KubaO Sep 20, 2026
d4e4458
docs: write down the bullet dash, capitalisation and parenthesis conv…
KubaO Sep 20, 2026
407dfe4
docs: document render.mjs's renderer overrides and the automatic tabl…
KubaO Sep 20, 2026
9d04724
docs: add a tables section covering the wrapper, pipe escaping and th…
KubaO Sep 20, 2026
acc3a2c
docs: document folder-style pages, the permalink trailing slash, and …
KubaO Sep 20, 2026
3d1c76d
docs: point perf/README.md's pdf-lib shim paths at book/ after the Ph…
KubaO Sep 20, 2026
46efbf0
docs: state the VBA/package URL depth asymmetry with both directions …
KubaO Sep 20, 2026
30d2c39
vendor: add the upstream just-the-docs MIT licence
KubaO Sep 20, 2026
cada12e
docs: add a changer's path and verification gates to Extending
KubaO Sep 20, 2026
c2a0023
docs: replace three figurative phrases in the new Extending sections
KubaO Sep 20, 2026
ec0c378
review: record the corrections the fix pass produced
KubaO Sep 20, 2026
edd2949
docs: remove the nonexistent [Documentation(...)] attribute from eigh…
KubaO Sep 20, 2026
4a68649
docs: document the Markdown formatting convention for [Description(...)]
KubaO Sep 20, 2026
dd8e774
docs: add AppGlobalClassObject to the book, register two fence langua…
KubaO Sep 20, 2026
ef41570
docs: ConstantFoldable is module-scoped, not any function
KubaO Sep 20, 2026
e3b8449
docs: say why ConstantFoldable stops at module functions
KubaO Sep 20, 2026
ec43bab
docs: describe what each screenshot and diagram actually shows in its…
KubaO Sep 20, 2026
946697f
docs: describe the two Project Settings screenshots instead of naming…
KubaO Sep 20, 2026
b2f8026
docs: describe what each IDE screenshot shows instead of repeating it…
KubaO Sep 20, 2026
0541d83
notes: the typographer does not reach alt text
KubaO Sep 20, 2026
e05ff57
docs: describe what each menu screenshot shows instead of repeating i…
KubaO Sep 20, 2026
14acc20
docs: describe what the IDE panel screenshots show and drop their dup…
KubaO Sep 20, 2026
10c4e79
review: record what remains open
KubaO Sep 20, 2026
2d1d02e
fix: book.bat now preserves the PDF renderer's exit code
KubaO Sep 20, 2026
69386e2
docs: fix toolchain-overview diagram to match the current check.bat
KubaO Sep 20, 2026
449da90
docs: add missing vendorAssets, Check-section, and data-dep edges to …
KubaO Sep 20, 2026
53ea962
eval: warn against backgrounding a build in a fix pass
KubaO Sep 20, 2026
23ee348
fix: stop VOID_TAGS_RE backtracking exponentially on a slash in a lon…
KubaO Sep 20, 2026
00adc8b
fix: make page order deterministic so search-data.json is reproducible
KubaO Sep 20, 2026
6a18f7f
feat: stall watchdog reports the stuck task and its pages, then fails…
KubaO Sep 20, 2026
b5d9d61
fix: remove the two remaining exponential regexes in the render path
KubaO Sep 20, 2026
eb93889
feat: gate on exponentially backtracking regex literals
KubaO Sep 20, 2026
eb891f8
refactor: split toolchain tests out of check.bat into test.bat
KubaO Sep 20, 2026
37c8559
docs: document the stall watchdog, the regex gate, and the check/test…
KubaO Sep 20, 2026
00ca609
docs: correct four menu shortcuts and two typos against their screens…
KubaO Sep 20, 2026
5063293
docs: document the compiler executable's own export/import command line
KubaO Sep 20, 2026
36b397c
docs: cover the four command-line verbs the usage message omits
KubaO Sep 20, 2026
7faefe7
review: record the shortcut fixes, an overstated finding, and that no…
KubaO Sep 20, 2026
7879b00
review: record attributes missing from the reference and the probe-pr…
KubaO Sep 20, 2026
78b377a
tooling: generate an attribute-placement probe project from Attribute…
KubaO Sep 21, 2026
41562f6
docs: COMExtensible is not accepted on an interface member; note RunA…
KubaO Sep 21, 2026
b430994
docs: DllExport applies to constants, not variables, as its own examp…
KubaO Sep 21, 2026
5badd52
review: correct the probed-vs-confirmed counts
KubaO Sep 21, 2026
54d4fed
tooling: port convert_em_dash_separators and gen_attribute_probes fro…
KubaO Sep 21, 2026
f513645
notes: split font subsetting into WIP.Fonts.md; record the harfbuzzjs…
KubaO Sep 21, 2026
0768245
docs: normalize literal dashes to ASCII source form
KubaO Sep 21, 2026
2135891
docs: drop the inert Jekyll raw tags from SendKeys
KubaO Sep 21, 2026
e63750f
docs: reconcile nine IDE pages with what their screenshots actually show
KubaO Sep 21, 2026
6b17bd4
docs: pin three fragile attribute anchors and close two gaps in the U…
KubaO Sep 21, 2026
2cef18f
docs: mark book page counts as measurement conditions; describe the p…
KubaO Sep 21, 2026
895f24c
builder: drop stripLiquidRawTags, which ate Liquid tags inside code f…
KubaO Sep 21, 2026
4523869
notes: design build-time counts as named values in prose
KubaO Sep 21, 2026
888ae91
builder: guard the book's attribute rewrites against inline code spans
KubaO Sep 21, 2026
4d6e9fc
builder: stop admonition unwrapping from eating code indentation and …
KubaO Sep 21, 2026
dee4adb
builder: mask code regions before the kramdown-parity source rewrites
KubaO Sep 21, 2026
427f77a
tooling: recognise indented, tilde and long fences in the dash normal…
KubaO Sep 21, 2026
873d154
test: gate that no pre-render rewrite alters a code region
KubaO Sep 21, 2026
b382d41
notes: record the code-region hazard class and its gate
KubaO Sep 21, 2026
b897f0d
test: record the html_block blind spot in the code-region gate
KubaO Sep 21, 2026
1e55c9f
builder: preserve whitespace inside inline code, which is content not…
KubaO Sep 21, 2026
8ee72cc
notes: record the inline-code whitespace fix and the trim-boundary trap
KubaO Sep 21, 2026
df61726
review: close the round-2 queue items this session fixed
KubaO Sep 21, 2026
02a4ff0
tooling: make book.bat refuse a stale _site-pdf instead of rendering it
KubaO Sep 21, 2026
e6c634e
notes: record the book freshness gate and close its queue item
KubaO Sep 21, 2026
0eb2aab
docs: document eleven undocumented attributes; ConstantFoldableNumeri…
KubaO Sep 21, 2026
c7e4243
tooling: probe the five attributes that had no synthesisable argument…
KubaO Sep 21, 2026
a34a36c
review: close the IDE-dependent queue; notes: how to get at the packa…
KubaO Sep 21, 2026
10cc88a
tooling: probe the new attribute lines faithfully, and ask six more e…
KubaO Sep 21, 2026
a2d84a1
docs: quote the real CurrentProjectName declaration, which is a Decla…
KubaO Sep 21, 2026
b33342c
docs: RedirectToStaticImplementation is Interface-only; ComExport tak…
KubaO Sep 21, 2026
3240812
docs: give the five placement-less attributes a line; WindowsControl …
KubaO Sep 21, 2026
49dd239
docs: move attribute provenance into HTML comments and round the counts
KubaO Sep 21, 2026
32973db
tooling, review: use applicability throughout, matching Attributes.md
KubaO Sep 21, 2026
fee2885
tooling: compile twinBASIC projects headlessly; settle the last two a…
KubaO Sep 21, 2026
b2516f3
tooling: let tbbuild find the IDE itself rather than naming an instal…
KubaO Sep 21, 2026
aad335d
review: name the right file for the command-line bug, and a cmd repro…
KubaO Sep 21, 2026
f8b2c27
review: reduce the command-line repro to two cmd lines and no project…
KubaO Sep 21, 2026
cc48b88
review: the command-line repro is one pasted cmd line, not a batch file
KubaO Sep 21, 2026
fd97fe6
tooling: add --show/--hide and TBBUILD_SHOW; record what the proxy sp…
KubaO Sep 21, 2026
3e8e23d
review: give the --buildAndExit32 hang a verified five-line repro
KubaO Sep 21, 2026
d9868a9
review: the queue was not empty; correct four stale entries and surfa…
KubaO Sep 21, 2026
b2c7c2a
builder: replace the 836-page floor with a committed baseline the bui…
KubaO Sep 21, 2026
90a1092
docs: document LibraryId and Version; fix the fence pairing that sile…
KubaO Sep 21, 2026
852d286
review: close the LibraryId entry; it was two attributes, not one
KubaO Sep 21, 2026
ef8b842
builder: substitute {{tbdocs:name}} counts in prose, derived on every…
KubaO Sep 21, 2026
31cc9dd
review: record the counts mechanism against the stale-figures findings
KubaO Sep 21, 2026
555b975
review, eval: write round 3's cases and what to do next
KubaO Sep 21, 2026
cb9bfb1
review, eval: run round 3 -- 8 cases, 13 findings; round 2's fixes me…
KubaO Sep 21, 2026
bb3ca8a
docs, builder: fix round 3's findings; add check_gate_lists to stop t…
KubaO Sep 21, 2026
8f18f62
builder: recognise tilde fences in the admonition stasher; a ~~~ bloc…
KubaO Sep 21, 2026
6f9d0c4
review: record round 3's outcome -- all thirteen findings closed, plu…
KubaO Sep 21, 2026
e62b571
review, eval: run round 4 -- 8 cases, 14 findings; six are round 3's …
KubaO Sep 21, 2026
98cae35
docs, builder: fix round 4's findings; widen check_gate_lists past th…
KubaO Sep 21, 2026
4f9c9e9
builder, scripts: check constructed regexes too -- fold new RegExp(..…
KubaO Sep 21, 2026
2ac5f15
review, eval: run round 5 -- 8 cases, 15 findings; no hazard walked i…
KubaO Sep 21, 2026
122539e
docs, builder: fix round 5's findings; make script names searchable, …
KubaO Sep 21, 2026
e68c4d8
review, eval: run round 6 -- 8 cases, 14 findings; add the site-entry…
KubaO Sep 21, 2026
7ddf84d
docs: fix round 6's findings; repair three broken samples, give WithE…
KubaO Sep 21, 2026
b3c733a
docs: revert the form code-behind unwrapping -- a form's .twin file i…
KubaO Sep 21, 2026
1c8ea02
docs: document the intrinsic Debug object -- Print, TracePrint, Cls a…
KubaO Sep 21, 2026
f336005
docs: drop the print-zone note from the Debug page -- it addressed do…
KubaO Sep 21, 2026
da2516e
scripts: add tbrun.mjs -- build a probe and capture its Debug Console…
KubaO Sep 21, 2026
4ab817d
docs, scripts: guard the Assert example with IsArrayInitialized and s…
KubaO Sep 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 84 additions & 1 deletion .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,89 @@ jobs:
# the point, and the deploy workflow has a site to ship.
- name: Verify the build's own link checker (check_links_diff.mjs)
run: node scripts/check_links_diff.mjs --case fixture-built --case fixture-built-offline --a script --b fused
# The publish allowlist (builder/publish-policy.mjs) is enforced
# inside the build above, so a green build already says nothing
# unpublishable is in docs/. It does NOT say the allowlist still
# refuses anything: one widened until it refuses nothing reports the
# same clean pass. This asserts the refusals against named probes --
# a stray .bak, a .pem, a scratch .md with no frontmatter. No
# browser, no built tree, ~40 ms.
- name: Verify the publish allowlist (check_publish_policy.mjs)
run: node scripts/check_publish_policy.mjs
# The two gate lists on Tools.md against the wrappers that run
# them, plus every gate count stated in prose in README.md or
# under docs/Documentation/. Documented gate counts have rotted
# three times; the third was round 3's own fix pass, on the two
# pages the first version of this gate did not read. Pure text,
# ~50 ms.
- name: Verify the documented gate lists (check_gate_lists.mjs)
run: node scripts/check_gate_lists.mjs
# A regex that backtracks exponentially does not fail a build, it
# stops one: the corpus passes until a page happens to contain the
# trigger, and then a render worker sits inside String.replace
# forever. VOID_TAGS_RE shipped that way for as long as no alt text
# contained a slash, and its first fix was still exponential on a
# subtler witness. Nothing else here can see it, because there is
# nothing to see until the content changes.
#
# Reads regex literals AND every `new RegExp(...)` the source
# decides the arguments of. That second half is not a refinement:
# assembling a pattern from shared string constants is ordinary
# JavaScript, and for as long as this read literals only it was
# also a way out of the gate. Six such regexes went into one gate
# unseen, one of them polynomial.
#
# Gates on exponential only -- about a fifth of the patterns here
# are polynomial, nearly all the ordinary `<tag[^>]*>` shape on
# bounded input, and a gate that fails on day one gets switched
# off. The self-test probes run inside the same pass, classification
# and folding both, so a green line here cannot be a gate that has
# stopped detecting. No browser, no built tree, a few seconds
# sharded across the runner's CPUs.
#
# recheck's native backend is an optional dependency resolved per
# platform; if it is missing the script says so and falls back to
# the pure-JS implementation, which is slower but reaches the same
# verdict on every probe.
- name: Verify regex safety (check_regex_safety.mjs)
run: node scripts/check_regex_safety.mjs
# render.mjs applies several kramdown-parity rewrites to RAW markdown,
# before anything has been parsed, so none of them can tell prose from
# code -- on a site whose subject matter is code. Four defects of that
# shape shipped: `{% raw %}` stripped inside fences, admonition bodies
# losing the indentation of the code they contain, `Items[1](a, b)`
# percent-encoded inside a fence, and a YAML sample's closing `---`
# deleted with the line above it promoted to a heading.
#
# No other gate can see any of it: the corruption is inside <code>,
# and the link, integrity, publish and axe checks all pass over it.
# Tokenise the source, apply the real rewrite chain, re-tokenise, and
# compare the literal regions. Probes ride along in the same run so a
# clean corpus cannot be mistaken for a working gate. No browser, no
# built tree.
- name: Verify code regions survive the pre-render rewrites (check_code_regions.mjs)
run: node scripts/check_code_regions.mjs
# The page-count drift guard reports nothing on a healthy tree, so a
# green build says exactly what a guard that had stopped working says.
# These probes make the other assertion, against a scratch baseline
# rather than the committed one. The first replays the defect that
# motivated it: 37 pages of AppGlobalClassObject lost to a blanket
# exclude rule, under a guard that knew only a floor of 836 against a
# real 908. No browser, no built tree.
- name: Verify the page-count drift guard (check_page_baseline.mjs)
run: node scripts/check_page_baseline.mjs
# Graphviz sizes each node box from a width table; the browser paints
# the label with a real font. Nothing in the build compares the two, so
# a mismatch ships as text hanging outside its box on a green build --
# which is how 27 labels across three diagrams went out, through a full
# accessibility sweep, unreported. axe does not evaluate SVG <text>
# geometry either.
#
# Safe on CI's font set: it loads Inter from the committed .woff2 by
# @font-face rather than relying on an installed face, so unlike the
# target-size rules it measures the same here as on a dev box.
- name: Verify DOT diagram fit (check_dot_fit.mjs)
run: node scripts/check_dot_fit.mjs
# check_a11y.mjs injects a PATCHED axe bundle (plain-color-fields,
# -26 % on a realistic page set -- see builder/PLAN-axe-perf.md), so the
# patch has to be verified before its results are trusted. The patch
Expand All @@ -137,7 +220,7 @@ jobs:
# PR that bumps axe-core is exactly when it earns its place.
- name: Verify axe source patch (check_axe_patch_equiv.mjs)
run: node scripts/check_axe_patch_equiv.mjs
# The scan is eleven pages of ~1,160, so its page list decides what it can
# The scan is thirteen pages of ~1,160, so its page list decides what it can
# report at all. This fails when the site grows a markup construct no
# sample page carries -- the drift that let the previous six-page sample
# report a clean pass while 54 pages had violations in constructs it never
Expand Down
64 changes: 64 additions & 0 deletions .github/workflows/tbdocs-gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,70 @@ jobs:
# comparison against the build's own checker.
- name: Verify the standalone link checker (check_links_diff.mjs)
run: node scripts/check_links_diff.mjs --case fixture --a script --b index
# The publish allowlist (builder/publish-policy.mjs) is enforced
# inside the build above, so a green build already says nothing
# unpublishable is in docs/. It does NOT say the allowlist still
# refuses anything: one widened until it refuses nothing reports the
# same clean pass. This asserts the refusals against named probes --
# a stray .bak, a .pem, a scratch .md with no frontmatter. No
# browser, no built tree, ~40 ms.
- name: Verify the publish allowlist (check_publish_policy.mjs)
run: node scripts/check_publish_policy.mjs
# The two gate lists on Tools.md against the wrappers that run
# them, plus every gate count stated in prose in README.md or
# under docs/Documentation/. Documented gate counts have rotted
# three times; the third was round 3's own fix pass, on the two
# pages the first version of this gate did not read. Pure text,
# ~50 ms.
- name: Verify the documented gate lists (check_gate_lists.mjs)
run: node scripts/check_gate_lists.mjs
# An exponentially backtracking regex does not fail a build, it
# stops one -- a render worker sits inside String.replace forever
# the first time a page contains the trigger. VOID_TAGS_RE shipped
# that way, and so did its first fix. See the same step in
# checks.yml for what it gates on and why only exponential.
#
# Here for the same reason check_dot_fit.mjs is: checks.yml runs
# only on pull requests, so this is the one gate a regex merged by
# a direct push to `staging` would otherwise never meet. No browser
# and no built tree, so its position relative to the build does not
# matter.
- name: Verify regex safety (check_regex_safety.mjs)
run: node scripts/check_regex_safety.mjs
# The pre-render rewrites in render.mjs run over raw markdown and
# cannot tell prose from code; four defects of that shape shipped,
# and nothing else looks inside <code>. See the same step in
# checks.yml. Here for the same reason the gate above is: checks.yml
# runs only on pull requests, so this is the one place a rewrite
# merged by a direct push to `staging` would meet it. No browser and
# no built tree.
- name: Verify code regions survive the pre-render rewrites (check_code_regions.mjs)
run: node scripts/check_code_regions.mjs
# The page-count drift guard reports nothing on a healthy tree, so a
# green build says exactly what a guard that had stopped working says.
# These probes make the other assertion, against a scratch baseline
# rather than the committed one. The first replays the defect that
# motivated it: 37 pages of AppGlobalClassObject lost to a blanket
# exclude rule, under a guard that knew only a floor of 836 against a
# real 908. No browser, no built tree.
- name: Verify the page-count drift guard (check_page_baseline.mjs)
run: node scripts/check_page_baseline.mjs
# Graphviz sizes each node box from a width table; the browser paints the
# label with a real font, and nothing in the build compares the two -- so a
# mismatch ships as text hanging outside its box on a green build. See the
# same step in checks.yml for how 27 labels once went out that way.
#
# checks.yml only runs on pull requests, so this is the one gate a diagram
# merged by a direct push to `staging` -- or by a manual dispatch -- would
# otherwise never meet.
#
# After the build on purpose: builder/dot.mjs rewrites a stale .svg from
# its .dot in place, so this measures the bytes about to be deployed, not
# the ones that were committed. Chromium is already installed above, and
# the check loads Inter from the committed .woff2 rather than an installed
# face, so it measures the same here as on a dev box. Five diagrams, ~1 s.
- name: Verify DOT diagram fit (check_dot_fit.mjs)
run: node scripts/check_dot_fit.mjs
# check_a11y.mjs injects a PATCHED axe bundle; verify the patch is still
# value-preserving before trusting what it reports. See the same step in
# checks.yml for why the fingerprint gate does not cover this.
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,9 @@ indexer/.packages/
/test/fixtures/_out-offline/
/test/fixtures/_out-pdf/
/test/fixtures/_out.json


# scripts/build_fonts.py caches the upstream font release archives here
# (~190 MB). The subset .woff2 it produces ARE committed, under
# docs/assets/fonts/ -- only the archives are throwaway.
/.font-cache/
20 changes: 20 additions & 0 deletions BOOKPLAN.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# PDF Book Build — Plan

> **Historical design record. Do not follow the commands or file paths in it.**
>
> This is the staged plan, written in the Jekyll era, for turning the PDF from a flat concatenation of every reference page into an actual book. The structure it designs — front matter, numbered parts, chapter dividers, in-PDF cross-references — is what the book has today; the file is kept for the reasoning behind each decision, not as instructions. Page counts, timings and command lines quoted below are from that era.
>
> **The build system it describes no longer exists.** The Phase 10 cutover replaced Jekyll with `tbdocs`, the Node.js generator under [builder/](builder/), and `docs/_plugins/`, `docs/_includes/` and `docs/_layouts/` were deleted — so every Ruby plugin, include and layout named below survives only in git history. Concretely:
>
> | Named below | Now |
> |---|---|
> | `bundle exec jekyll build` | `build.bat` — `node builder/tbdocs.mjs --src docs` |
> | `npx pagedjs-cli … -o _pdf/book.pdf` | `book.bat` — `node book/render-book.mjs … -o "docs/_pdf/twinBASIC Book.pdf"` |
> | `docs/book.bat` | [`book.bat`](book.bat), at the repository root |
> | `docs/_data/book.yml` | [`docs/_book.yml`](docs/_book.yml) |
> | `_plugins/pdfify.rb` | [`builder/pdf.mjs`](builder/pdf.mjs), pipeline Phase 8 |
> | `_plugins/book-*.rb`, `_includes/book-chapter-body.html`, `_layouts/book-combined.html` | [`builder/book.mjs`](builder/book.mjs) |
> | `assets/css/rouge.css` | `assets/css/tb-highlight.css`, generated by `builder/highlight-theme.mjs` |
>
> One entry under [Rendering gotchas](#build-environment) has stopped applying and is the one most likely to be acted on: **"PowerShell cannot invoke `npx` directly" no longer affects `book.bat`.** That batch file calls `node`, not `npx`, and a `.bat` is interpreted by `cmd.exe` whichever shell launches it — so no `.ps1` shim is reached and the execution policy is never consulted. The paged.js and CSS Paged Media gotchas above it still hold; the forked bundle lives at `book/lib/paged.browser.js`.
>
> **Current documentation.** The two-stage pipeline, the renderer's flags and phases, and how to triage a failed render are on the site: [PDF Generation](docs/Documentation/PDF-Generation.md) and [Book Configuration](docs/Documentation/Book-Configuration.md), with the vendored-library patches in [Fixes-PagedJS.md](docs/Documentation/Fixes-PagedJS.md) and [Fixes-PDFLib.md](docs/Documentation/Fixes-PDFLib.md). The Phase 8 specification is [builder/PLAN-8.md](builder/PLAN-8.md), and the Jekyll era as a whole is recorded in [WIP.OldJekyll.md](WIP.OldJekyll.md).

Currently `book.bat` produces a ~1500-page PDF that is a flat concatenation of every reference page. It works, but it doesn't read like a book — no front matter, no parts, no global TOC, every chapter is `<h1>`, and "See Also" cross-references point at standalone `file://` URLs rather than jumping within the PDF.

This file is the staged plan for turning that output into an actual book. Phases are independent; each one ends in a verifiable rendered artefact and is a reasonable commit boundary.
Expand Down
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,29 @@ If you want to get involved in improving this documentation directly, please for

All help is *very much* appreciated :)

## Building the site

The site is rendered by `tbdocs`, a Node.js static site generator kept in [`builder/`](builder/). You need **Node.js 22+**; a PDF or accessibility run additionally needs Chromium, installed once with `npx puppeteer browsers install chrome` (add `--install-deps` on Linux only).

```
npm ci # once, from the repository root
build.bat # renders _site/, _site-offline/ and _site-pdf/, and link-checks them
serve.bat # localhost:4000 with watch + live reload
check.bat # the gates that read the built site, ending in the accessibility scan
test.bat # the gates that test the toolchain itself
book.bat # renders the PDF book; run build.bat first
```

A clean `build.bat && check.bat` is the bar for "ready to commit"; add `test.bat` when the change touched anything outside `docs/`. Each wrapper names the gates it runs, in order, on [Tools and Scripts](https://docs.twinbasic.com/Documentation/Development/Tools). On Linux or macOS, run the `node` command inside each batch file directly --- they are thin wrappers.

Where to read more:

- **Writing or editing a page** --- [Authoring Pages](https://docs.twinbasic.com/Documentation/Development/Authoring) covers frontmatter, headings, prose style, attribution and links.
- **The build and deployment workflow** --- [Building and Deployment](https://docs.twinbasic.com/Documentation/Development/Building).
- **Every command and flag** --- [Tools and Scripts](https://docs.twinbasic.com/Documentation/Development/Tools).
- **Changing the generator itself** --- [tbdocs Internals](https://docs.twinbasic.com/Documentation/Development/Builder), with [`builder/README.md`](builder/README.md) next to the code.
- **Adding a build task or a markdown-it plugin** --- [Extending the Builder](https://docs.twinbasic.com/Documentation/Development/Extending) covers all four extension points --- a task in the build graph, a markdown-it plugin, a render-worker sub-stage, and a verification gate in `check.bat` or `test.bat`.




Expand Down
Loading
Loading