Commit Graph

12 Commits

Author SHA1 Message Date
Edward Langley 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>
2026-09-20 13:37:20 -07:00
Edward Langley 757abf3b88 docs: REVERT the mobile fix (user ruling), caption the stale drill cast
Read the revert first, because this commit undoes the headline change of the
one before it and a subject line saying "caption" would have hidden that.

**REVERTED: 3fcb88b's `@media (max-width: 900px)` block.** User ruling: the
mobile defect is to be FILED, not fixed in this PR. It is improvise-o31u, P2,
carrying the measurement, the proposed fix (`overflow-x: auto` on `.player`
plus `fit: false` or an explicit `terminalFontSize`), and the note that a
working fix was written and measured here before being reverted, so the next
person starts from evidence. Measured both ways at 390x844, so the cost of the
revert is on the record rather than implied:

    3fcb88b as committed   font 11.9457px   player width 880
    this commit             font  4.83258px  player width 356

`document.documentElement.scrollWidth` is 390 and equal to `clientWidth` in
both, so the revert does not introduce horizontal page scroll — it restores an
unreadable font, and nothing else.

**F1, the stale drill cast, captioned rather than re-recorded or dropped** —
also a user ruling. `drill.cast` shows the narrow records format with a single
`Value` column, which improvise-2zq and improvise-c5v replaced with a column
per measure plus the `+cat` and `+` columns, so it demos a UI the software no
longer has, now at the site root. The caption is `p.dated`: body size, body
colour, set off with a rule, and ABOVE the player rather than under it —
verified by measuring its computed style against `body` and its box against the
player's, because "captioned" and "captioned in grey 10px under the fold" are
the same word and different things. improvise-2oxt stays open; improvise-e61
stays closed, with its notes now saying plainly that the caption is an honest
label on an UNMET criterion rather than a met one.

**F7: the harness readiness probe** was `/index.html`, which used to be the app
and is now the landing page — so it would answer 200 against a tree with no
bundle assembled at all. Now `/app/index.html`. Proved discriminating rather
than assumed: served a directory containing only the landing page, and the old
probe returns 200 while the new one returns 404.

`docs/index.html` is now 213 lines, past improvise-e61's "under 200". The
criterion is reinterpreted on the ticket rather than the file crammed to fit:
the number was a proxy for single file, vanilla, no build step, no framework,
and all four hold.

Also corrected, in the record rather than the tree: improvise-bck's evidence
cited the deployed root for its page-load and bundle-size measurements, and
this PR moved the app out from under those URLs.

Verified: 6/6 harness shell specs pass with the new probe, four casts still
play 37 lines each at the root, call to action still 200, cargo test 1311,
both comment checkers clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-20 11:23:57 -07:00
Edward Langley 3fcb88b291 docs: the landing page on a phone, and two stale instructions in the plan
Review findings on PR #47.

A 120-column cast shrunk into a 390px viewport computed a **4.83px** terminal
font — measured in Chromium against the assembled tree. That was tolerable when
the landing page sat at `/landing/`; since the user's ruling it is the first
thing a phone visitor sees. Under 900px each player now scrolls sideways at a
legible size instead: **11.95px**, measured the same way, with the page's own
`scrollWidth` still equal to its `clientWidth` — the overflow is contained
inside the player, so there is no horizontal PAGE scroll.

That takes `docs/index.html` to 209 lines, past improvise-e61's "under 200".
The criterion is reinterpreted rather than crammed to fit, and said so on the
ticket: the number was a proxy for single file, vanilla, no build step, no
framework, all of which hold. A limit met by one line and checked by nothing was
never really met.

`context/plan.md` carried two instructions that this PR made actively
misleading:

- §2.4 still told a re-recorder to use 100x30. That is the instruction whoever
  picks up improvise-2oxt would follow, and it disagrees with both the existing
  casts and the player. It now says 120x37, and says the two must be changed
  together.
- §4.2 still said to set Pages to branch `main` / folder `/docs`. That used to
  fail loudly — there was no `docs/index.html`, so it was a 404 — and since
  improvise-e61 it fails QUIETLY: the landing page renders perfectly and its
  call to action 404s, because `app/` exists only in the assembled tree. It now
  says GitHub Actions, and says why the other setting is worse than it looks.

Verified: 6/6 harness shell specs still pass against the assembled tree, the
four casts still play 37 lines each at the root, and the call to action still
resolves 200. cargo test 1311, both comment checkers clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-20 11:20:59 -07:00
Edward Langley 2ccd21f3e8 docs: the landing page is the front door, the app moves to /app/
User ruling on improvise-kh8, overturning the arrangement the previous commit
shipped: "The landing page should be served at the root of the repository and
link to the in-browser demo." The argument for the other arrangement is left
standing in the ticket rather than deleted — it is overruled, not wrong to have
considered — and the root is now `docs/index.html`.

The app moves under `app/` WHOLE, both bundle directories included. Every path
in `app.js` and `worker.js` is relative, so moving the bundle together keeps
every one of them correct and the wasm-pack generated glue untouched;
`worker.js`'s `fetch("demo.improv")` resolves against the worker's own URL, so
the seed follows for the same reason. The four `stamped` guards in
`assemble.sh` follow the files: they are the only check that the cache-bust
substitution worked, and a guard aimed at a path nothing writes fails in the
direction that looks like success.

`harness/tests/shell.spec.js` navigates to `/index.html` six times, including
the `?ws=` and `?doc=` variants, and every one of those now lands on the
landing page. All six are repointed at `/app/index.html`. That file is outside
this unit's declared scope and is the second deliberate stray in this PR.

VERIFIED AGAINST THE ASSEMBLED TREE, not against `docs/` directly, because a
path move is what re-arms the trap this page already caught once. With real
bundles from `web/build.sh`:

  * `npx playwright test tests/shell.spec.js --project=chromium` — 6 passed,
    with `/app/{index.html,app.js,style.css,worker.js,demo.improv}` and both
    `?v=` stamped bundles all served 200;
  * the four casts play 37 lines each at the site root, no failed request and
    no page error;
  * the full journey: load the root, click the call to action, land on `/app/`,
    and the grid draws out of the in-page worker — 12 cells, all editable,
    a "Revenue" header, `#status` reading "in-page worker · demo.improv".

The call-to-action check was proved able to fail by pointing the link at
`./aap/`: 404, while the page still looks entirely correct.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-20 11:12:43 -07:00
Edward Langley 3a32d1348c docs(landing): drop the duplicated idleTimeLimit
Every cast header already carries idle_time_limit 2.0; repeating it in the
player config is a second answer to one question, and the one that drifts is
whichever is not the cast. Found reviewing against design-principles "a
derivation done twice is the defect".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-20 11:04:37 -07:00
Edward Langley 161e36ea60 docs: a landing page, served beside the app rather than in front of it
improvise-e61. Vanilla, single file, 192 lines, no build step: the four casts
improvise-d4w recorded, played by asciinema-player pinned from jsdelivr.

improvise-kh8 recorded a collision to resolve before starting — Pages already
serves the standalone web app at the root, so a landing page either replaces
it, sits beside it, or is dropped. It sits beside it at `/landing/`, because
kh8's own note is right that the live app is the better front door, and a page
the deploy never copies is a file nobody can reach. `web/assemble.sh` copies
it, so the browser harness serves the same tree the deploy publishes and there
is still one answer to "what ships".

The player config deviates from the tickets, deliberately. improvise-d4w's
description and improvise-e61's criteria both say 100x30; every cast header
says 120x37, so the recordings never complied with their own ticket. A 30-row
player clips the bottom seven rows of a 37-row cast, which is exactly where
the tile bar and the status line are, so the page declares the geometry the
casts actually have.

e61 also asked for the casts to be checked against the current UI before
embedding. They were: the tile bar's short_label vocabulary and the mode line
still match, but the casts predate improvise-2zq's `+cat` column by five
months and every one of them opens on the recorder's shell prompt. Filed as
improvise-2oxt rather than silently embedded as current.

Verified by driving the page in Chromium: four players construct, each renders
37 terminal lines after play, no failed request and no page error — against
both `docs/` directly and the assembled `site/landing/`. Counting the players
alone was proved worthless first: with autoPlay false the cast is not fetched
until the click, so a page whose every cast path 404s constructs four players
and throws nothing. Breaking `./casts/` to `./cats/` passes the construction
check and fails the play check with four 404s. improvise-bgtf carries that as
a harness spec, since nothing in CI asserts any of it yet.

README: `cargo install improvise` was false — the crate is not on crates.io —
and the Pages description named two of the three gates a deploy waits on.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-20 11:04:00 -07:00
Edward Langley 4583b59520 chore: update casts and support scripts 2026-04-11 00:08:02 -07:00
Edward Langley 21a5ea9d55 chore: update demo.gif 2026-04-11 00:08:02 -07:00
Edward Langley 767d524d4b unwind LFS for now 2026-04-11 00:07:59 -07:00
Edward Langley a61d7aa229 feat(demo): add asciinema casts for pivot, drill, formulas, import
Four recorded casts at 100x30 with 2s idle cap:
- pivot.cast: axis reassignment with tile mode
- drill.cast: drill-down into aggregated cells
- formulas.cast: formula panel and adding formulas
- import.cast: CSV import wizard walkthrough

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 00:07:58 -07:00
Edward Langley e00f2e032e feat(demo): add VHS demo tape and generated GIF
Create docs/demo.tape scripting a ~15s pivot axis reassignment demo.
Hide shell startup and quit so the GIF opens directly on the TUI.
Set up git-lfs for docs/*.gif. Merge LFS hooks with existing beads hooks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 00:07:57 -07:00
Edward Langley 4751b800fd chore: remove stale SPEC.md, salvage vision into docs/design-notes.md
Audited SPEC.md against code — mostly accurate but redundant with
repo-map.md and design-principles.md. Minor drift in storage internals,
wizard step count, and mode representation. Salvaged product vision and
non-goals into docs/design-notes.md with staleness disclaimer.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 00:07:57 -07:00