cc113c732fd45d14c1c02a5fcdf1b28a3f680b18
11 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
cc113c732f |
docs(context): answer the review of the repo-map split
- repo-stats reads the gotcha list from context/gotchas.md (the digest in repo-map.md no longer measures the doc-growth signal) and reports it as `docs.gotchas`; the test fixture and its derived expectations follow. - AGENTS.md and the wave agent-rules protect gotchas.md and file-inventory.md like the repo map they were split from. - doc-site.md's publication table lists the two new pages. - file-inventory.md's Context docs rows describe the three files correctly. - the code-review skill points at gotchas.md for the long form. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> |
||
|
|
f0119a437d |
docs(context): condense repo-map to a digest; move gotchas and inventory to their own pages
repo-map.md was 173 KB (~43k tokens), too long to be part of every new agent's context. The full gotcha text moves verbatim to context/gotchas.md and the per-file inventory (with the old Wasm/CLI/Testing sections) to context/file-inventory.md; the map keeps a one-or-two-line digest per gotcha under the same numbers, so every `gotcha N` citation still resolves. The doc-site manifest publishes the two new pages, and `gotchas` gets the same gotcha-N anchors as `repo-map`. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> |
||
|
|
676347674a |
chore(site): stop tracking generated site/ (improvise-1xfb.4)
site/ is web/assemble.sh's default output, and site/docs is scripts/build-doc-site.mjs's. 27 generated pages under site/docs were committed by accident and went stale. Nothing reads the tracked copy: CI's build job assembles with `nix build .#site` into the store, the harness assembles into harness/serve/, and build-web-release.sh assembles into a temporary stage. Remove site/ from the index, ignore /site/, and say so in context/code/doc-site.md. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze |
||
|
|
6034a216e1 |
docs(site): publish the two new context docs, and de-number two stale counts
The `build` job failed, correctly: `scripts/build-doc-site.mjs` requires every `context/**/*.md` to be either in the SECTIONS manifest or a named omission (improvise-res9's cure), and the two files this branch added were neither. Both are now published, beside the TUI in each section. While there: `context/code/doc-site.md` asserted 'the seven `context/code/*.md` documents' when there were already twelve, and '501 entries' when the checker reports 801. Both were stale before this branch and this branch makes them staler, so they are de-numbered rather than re-asserted — a count in prose that nothing checks is a fact with no owner, and the shape that stops drifting is not having one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FC2jVn8Au7E9JPkw6bwXXH |
||
|
|
787e354b9b |
doc-site: name context/code/pr-review.md as an omission
The `build` job fails on main and on every branch merged from it: doc-site: context/code/pr-review.md is neither published nor a named omission NOT a merge loss -- scripts/build-doc-site.mjs in this branch is byte-identical to main's, and neither lists the file. PR #96 added context/code/pr-review.md without a manifest line, which is exactly the gate improvise-res9 added: a doc added without a line publishes nothing and says nothing, so the generator refuses. Omitted rather than published, and the line is cloud-agents.md's rather than tooling.md's. tooling.md explains checkers a reader of the code will meet; pr-review.md is about THIS REPOSITORY'S PROCESS -- where a Codex review appears, how to tell it from our own agents' comments, why absence is not approval. Nobody visiting a website is about to read a PR thread. Both homes updated, because an omission is restated beside the manifest AND in doc-site.md section 2, and the prose there counted them ("Neither is referenced...") so it went stale at three. This strays into scripts/, which is Wave N's ground. Flagged in the hand-back; it is a one-line data entry either way if the orchestrator would rather publish it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FC2jVn8Au7E9JPkw6bwXXH |
||
|
|
1c3e1bd968 |
feat(doc-site): the published set is derived, and the generator must run last (improvise-res9)
The manifest only ever grows, so a doc added without a line in it published nothing and said nothing: build green, link check green, doc simply absent. The generator now walks context/**/*.md plus docs/design-notes.md, subtracts the manifest, and fails unless the remainder is exactly the OMITTED map -- checked in BOTH directions, because an entry naming a file nobody can find asserts a reason for nothing. Filed as latent; it was live. context/code/kb-tool.md had been unpublished, unargued and unnoticed since it was added, while doc-site.md's own table says context/code/*.md is published. It is published now, with context/code/tooling.md and context/test-evidence/tooling.md: 23 pages to 26. Second gate, same file: the generator reads web/assemble.sh and refuses unless its own invocation is that script's last command. Its outward-link check resolves ../index.html and ../app/ against the filesystem, so a line appended below it would make that check pass against a half-built tree. Both run at module scope, before any page is generated, so a manifest error is answered before the 48 outward-link failures a bare run reports -- a missing doc is actionable wherever you ran the generator, and the two are unrelated diagnoses. Three faults injected and observed; evidence in context/test-evidence/tooling.md. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FC2jVn8Au7E9JPkw6bwXXH |
||
|
|
702c1d43ff |
docs: correct the alt-text argument, which was right for the wrong reason
The commit that added `content: "\2630 " / ""` claimed Firefox ignores the
alt-text form and falls back to reading the content, making the change "an
improvement in two engines and a no-op in the third". The mechanism is wrong:
Firefox shipped the syntax in 133, and all three engines parse it -- measured
in Chrome 141, Firefox 142 and WebKit 26, each computing the declaration
intact. The conclusion survives; the reason given for it does not, and the
reason was the load-bearing half, because it was what made the change look
like a one-way door. It is one because every engine shipped to supports the
syntax, not because the unsupported path is harmless.
The unsupported path is NOT harmless, and that is the risk neither the change
nor its first review named: `/ alt` in an engine that does not know it is a
parse error for the whole `content` declaration, so the glyph does not lose
its alt text -- it VANISHES. A silent visual regression, the opposite of the
assumed failure mode. The glyph is now verified painted in all three engines
by pixel diff against `::before { content: none }`, text starting 20px further
right in each.
This is written to context/ rather than left in the commit message because
design-principles.md §6 says an argument must not live only in a commit
message -- a message is write-once, unauditable, and no check in this repo can
read one. The rule landed in the same merge this corrects under, which is a
reasonable first exercise of it.
It also records this file's fourth wrong-property instance, and the sharpest,
because it produced a confident FALSE POSITIVE: the first probe measured the
label's width with and without ::before and reported the glyph missing in all
three engines. The label is display:block, so its width comes from the
container and cannot see inline content. Right question, wrong property --
and this time the wrong instrument accused working code rather than clearing
broken code.
Gates on the merged tree: 1379 rust, 26 node --test, 16 playwright (3 skipped,
webkit OPFS), fmt clean, clippy -D warnings clean, all three
check-comment-runs modes, 3473 site links / 0 broken, 0 nested anchors, 189
bead ids all resolving.
improvise-djoo
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FC2jVn8Au7E9JPkw6bwXXH
|
||
|
|
c0b786cf0d |
fix(docs): the phone nav toggle needs a keyboard, not a mouse
A regression the previous commit introduced, found in review. The checkbox driving the collapsed nav carried `hidden`, which is `display:none`, which removes it from the tab order AND from the accessibility tree. A <label> is not focusable on its own -- the checkbox it labels is what carries focus -- so at <=900px the navigation could be clicked and reached no other way, and the accessibility snapshot contained neither the checkbox nor any of the 25 links. The toggle is now visually hidden but focusable at narrow widths, and display:none at wide ones. Keeping display:none on the wide side matters: merely un-hiding it puts focus on an invisible control whose label is display:none, which is its own wart. Measured at 390, 900, 901 and 1280, because the regression lives on one side of a media query. At 390 and 900 the tab order is brand -> navtoggle, the toggle is focusable, the a11y tree carries a checkbox node, and Space takes visible nav links 1 -> 26. At 901 and 1280 the toggle is display:none, not focusable, absent from the a11y tree, and tab runs straight through the 26 links -- desktop identical to before. 0 of 23 pages scroll horizontally at 320, 390 and 1280, so the absolutely-positioned 1px input introduces nothing. WHAT IS WORTH MORE THAN THE FIX, and why doc-site.md gains a paragraph rather than the code gaining a comment: my probe for the previous commit counted VISIBLE nav links. That answers "does operating the toggle reveal the links" -- correct and complete for a mouse -- and is silent on whether any non-mouse route exists. It could not have seen this, however sharp the visibility instrument was. Last round's lesson was that a measurement which cannot distinguish the two states is not a measurement; this round adds the half it was missing: a measurement of the wrong PROPERTY is not a measurement either. checkVisibility fixed the visibility instrument; it does not turn a visibility count into an operability check. The instrument here is tab order, .focus() and the accessibility snapshot. Gates: 1378 rust, 26 node --test, 16 playwright (3 skipped, webkit OPFS), all three check-comment-runs modes, 3462 site links / 0 broken, 0 nested anchors, 0 of 23 pages overflow at 320/390/1280. improvise-djoo Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
41f694f535 |
fix(docs): collapse the phone nav, and stop the header comment lying
Round 2 of review. Three notes and the mobile-nav call. THE NAV, and the correction that prompted it. I had called the 25-link sidebar wall pre-existing and declined to fix it. That was wrong: the entire CSS is new in this PR, so the wall ships for the first time here and it is mine. Every phone page opened on ~1500px of nav before any content. The mechanism is a checkbox and not <details>, and the reason is measured rather than assumed. <details> was the obvious control, and it collapses correctly on a phone -- but the sidebar layout has to force it OPEN, and a closed <details> hides its content through ::details-content, which `display` cannot override. Chromium showed the desktop sidebar collapsed to one link with its toggle hidden: unusable. So the hiding is ours, in a media query, where overriding it is just cascade. Measured at both widths: 390px shows 1 link and the toggle, with the h1 at 189px instead of ~1500; 1280px shows all 26 links with no toggle and the h1 at 40px, unchanged; and the phone toggle really expands 1 -> 26 on click. Note the first probe was wrong -- getBoundingClientRect reports a height for content-visibility-hidden children, so it read 26 visible in both states and would have passed the broken version. checkVisibility() is what separates them. The same argument applies to the table of contents, which is equally new here: repo-map opened on 1397px of TOC on a phone. Capped at 45vh so it scrolls; 1397 -> 924, desktop identical at 652. THE HEADER COMMENT. The generator stopped running standalone when the link check began resolving ../index.html and ../app/ on disk, and its header still advertised a default OUT_DIR that now exits 1. That is gotcha 48's third paragraph exactly -- a fact stated in two places and updated in one, with the copy that was updated being doc-site.md and the copy someone about to run the script actually reads being the header. It now says so, keeps the strictness (the hole it replaced was counting those links as checked while skipping them), and records the other thing the reorder changed: the DIRECTION of a failure, from an obviously-broken tree with no app/ to a complete-looking one with a partial docs/. And one documented subset: a \| inside a code span in a table cell keeps its backslash where GFM would unescape it. Splitting is suppressed inside code spans, so the escape is never needed there and never consumed. No corpus instance; recorded as a decision rather than left to be rediscovered. Gates: 1378 rust, 26 node --test, 16 playwright (3 skipped, webkit OPFS), all three check-comment-runs modes, 3460 site links / 0 broken, 0 nested anchors, 0 of 23 pages overflow at 390 and 1280. improvise-djoo Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
1a0f04856e |
fix(docs): the review's four rendering defects, and the check that could see one
Review of PR #62 found four live defects and four smaller ones. The most valuable is the first, because of what it says about the rest. A TOC entry wrapping a heading whose rendered text already contained a link emitted <a href="#anchor"><a href="github...">...</a></a>. The parser closes the outer anchor early, so the entry became an empty unclickable stub and clicking "src/draw.rs" in the TOC navigated to GitHub. 19 occurrences over 10 pages. Both hrefs resolved perfectly, so the link check, the whole-site link check and a screenshot pass all missed it -- it answers "does every href resolve" and this is not that question. So the fix is two things: the TOC keeps a tag-free variant of each heading, AND a new check asserts no <a> appears inside another <a>. Proved by reverting the first half: 66 nested anchors reported, assembly exits 1. Clicking that TOC entry now lands on #src-draw-rs. esc() escaped & < > but not the quote it was interpolated into title="..." with. Five shipped bead titles contain one, and Chromium parsed the resulting tag as having three junk attributes. Now escapes " and ' as well. Today's corpus being friendly is not a reason to interpolate tracker text unescaped. Seven pages overflowed at 390px by up to 92%. The reviewer attributed it to the TOC; the TOC was real but not sufficient, and the first fix measured clean by getBoundingClientRect while the page still overflowed, because the heading text overflows its box without widening it. Only per-element scrollWidth names the culprit: hundreds of snake_case test names as headings. overflow-wrap on the headings and on .toc a, plus dropping display:table from .tickets, which had been cancelling the mobile overflow-x guard. 0 of 23 pages overflow at 390 and 1280 now, measured. table() split rows on every pipe before inline parsing, so `|Time Period|` -- this repo's own quoting syntax, in a corpus whose subject is that syntax -- was shredded into extra columns. A row that still parses, so no column count could see it. Now walked, respecting code spans and \|. Proved with a fixture: 9 tds with the fix, 12 with the old splitter reinstated. The four smaller ones: the link check counted 48 links it never verified behind a comment promising they were "checked below" when there was no below -- those are the links leaving the docs tree, and they are now resolved against the filesystem, which is why assemble.sh runs the generator LAST, once its siblings exist. The gotcha jump bar's hardcoded 48 is derived from the emitted anchors, because it failed closed on deletion and silently on addition, and the list only grows. context/code/doc-site.md cited improvise-xxxx and so broke the audit the surrounding paragraph describes; the repo-wide audit is now 189 ids, all resolving. And the Conventions paragraph's own example path now goes through inline(), so the sentence demonstrates the linking instead of asserting it. The ticket index keeps all 180 rows, open bugs and titles included, by the user's ruling: the data is already public in .beads/issues.jsonl, the page only makes it legible, and filtering it while the lede links the raw JSONL would be theatre. Gates: 1378 rust tests, 26 node --test, 16 playwright (3 skipped, webkit OPFS), all three check-comment-runs modes, 3460 site links / 0 broken, 0 nested anchors, 189 bead ids all resolving. improvise-djoo Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
f1011d7f6f |
feat(docs): publish the context/ prose as a site folded into Pages
The landing page is the site root and the app is /app/; the prose now sits at /docs/, assembled by the same web/assemble.sh the Pages job and the browser harness both run, so what ships and what is tested are one tree. Published: design-notes, design-principles, repo-map, the three ADRs, the seven context/code/ arguments, and the 501 test-evidence entries as their own clearly-labelled section. Not published: context/plan.md, which is an agent prompt about a launch rather than a description of the program, and context/cloud-agents.md, which is addressed to nobody who visits a website. Neither is referenced by a published document outside a code fence, so leaving them out dangles nothing. The reasoning is context/code/doc-site.md, which is itself published. Two things the corpus needed that a generator would not have given it. The ~190 improvise-xxxx citations resolve to a generated ticket index built from the already-public .beads/issues.jsonl rather than to an invented URL that would 404; an id the export does not yet carry stays plain text. And a code span that is wholly a repo path links to GitHub at the assembled ref, but only when the file exists on disk, so a stale citation degrades to text. The generator link-checks its own output and exits non-zero on a break, and assemble.sh runs under set -eu, so a dead cross-reference fails the assembly rather than shipping. It earned that on its first two runs: it caught a fence-close regex comparing a three-character marker to a one-character string, which swallowed every document from its first code block onward, and a list parser that ended the gotcha list at the first blank line, emitting 1 of the 48 anchors the jump strip links to. Proved by injection afterwards -- renaming the anchors reports 48 missing anchors, pointing the ticket links at an ungenerated page reports 763 missing pages. No framework, no node_modules for the site, no build step beyond one zero-dependency node script, matching the landing page's posture. improvise-djoo Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |