Repository navigation
Spec 001 T005 and T006: a no-go, and the figures drawn in a step of their own - #95
Merged
Merged
Conversation
…heir own T005 measured the render service in the book's mix on an 8-core host: at most 1.41 figures a second (concurrency 8), limited by the processors at about 3 core-seconds a figure, against the 7.3 a second SC-003's figure budget needs. The script is ci/measure/throughput.ts. T006 takes a third route, the user's choice: `pdf-export figures` draws every figure the book needs into a folder before the book (SC-010, contracts/figures.md), and `book --figures` reads them, asking no render service. SC-003 is now the book's time from figures already drawn. T046 adds the command; T024, T029, T037 and T039 follow; T005's single-figure measurement moves to T007. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e folder tied to its release The measuring script now chooses a selection's ancestor as the book does (nearestAncestor, a top-level pathway last), samples the container's CPU without stalling the client, rejects bad numbers, and keeps the mix when a selection has no ancestor. Re-run on all four settings: 1.523 figures a second at best, 3.5-4.6 core-seconds a figure, rising with concurrency. The figures' folder gets a manifest (release; each figure's kind, source and selection): `book` refuses a stale or other release's folder, and `figures` redraws only what changed. `figures` takes --files and runs the book's release-file and character checks before drawing. The book's own run, contracts, research R3/R7/R9/R10, data-model, quickstart, plan and tasks no longer say the book asks the render service. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…safe resume, task order The figures' manifest now carries a fingerprint: the graph's DBInfo release number and checksum, the release of the content service behind the render service, and the render service's build. `figures` checks the content service's release before drawing and refuses to resume a folder of another fingerprint; `book` faults a folder of another graph as stale-folder. A file is moved into place before its entry is written, and a file with no entry is drawn again. T046 now follows T024, whose preflight it runs. The script states its two limits (EHLDs told by hasEHLD; the render container's CPU only), checks free memory and --render at the start, times out and reports docker stats, and exits 1 with no extrapolation when its memory guard stops it. The four runs' outputs are kept in ci/measure/results/2026-11-02/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd cannot see The folder's fingerprint is now specified where it is read: the render service's health `build` in contracts/render.md (refused when `unknown`), the graph's DBInfo checksum in data-model (present on release 98; missing is a fault), and the content service's release by GET /data/database/version. The contract states plainly what it cannot see: `build` hashes the service's code, not the website page that draws, and `--content` is the operator's word; both are asked of WebsiteAngular (R10, T042). The manifest is an append-only journal with one writer, a redrawn figure loses its old file first, the fingerprint is read again at the end, and a refused resume names a new --out. T046 extends the render stub with /health and adds a content stub; T024 adds the checksum. The script probes the render service and checks memory before sampling, records release, species, seed and figures asked, and exits 1 when any figure is missing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…when its run is `figures` ends its journal with a `complete` line repeating the fingerprint, written only once every figure is in place and the end-of-run check passed; `book` faults a folder without it (incomplete-folder) and a graph without a checksum (no-checksum). A torn last line is drawn again on resume. The content-service check is described as what it is (the service named by --content), the two asks of WebsiteAngular are named, and T046 tests the cases the review listed. The script records the render service's build. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…esumed A failed end-of-run check appends a `failed` line, and a folder holding one is never resumed, so a rollback cannot complete a folder drawn under two builds. `--out` must be empty or a resumable journal; anything else is refused. The book reads a folder only when the journal's last whole line is a `complete` equal to its first and no line is torn. A change undone within one run is stated as unseen, with a per-drawing header asked of WebsiteAngular (T042) so each figure can record what drew it. T046 now sits after T024 in tasks.md, and both gain the tests the review listed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ild that drew it Each figure's journal line records the render build and content release read just before it was drawn; a difference from the fingerprint is exit 1 at the next figure, a resume redraws any figure drawn under another build, and the book faults one as stale-figure. That replaces the end-of-run check and the `failed` line, and covers a run killed mid-change and rolled back. A resume cuts a torn last line off before appending; a figure failing its label check gets no line; the EHLD summary's hash joins the fingerprint; `complete` is equal to the first line field by field. T029's label tests write their own figures' folder, `book`'s label check being a backstop for a folder changed by hand. The script reports how many CPU samples its means rest on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…suming Resuming a figures' folder kept producing ways for a folder to mix what two runs or two deployments drew. `figures` now refuses a non-empty --out, and a run that stops for any reason leaves a folder the book refuses; the next run starts afresh. A figure's line is appended only after its file is synced and in place and the render build and content release, read again, still match the fingerprint. The book's folder checks (incomplete-folder, no-checksum, stale-folder, stale-summary, stale-figure) are listed once, in contracts/figures.md, and cited from cli.md and T024, which tests each. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t stop the run With no resuming, stopping at the first refused figure would cost a whole run per fault. A figure's own fault (refused after the retry, timed out, failing its label check) now leaves it with no file and no line while the run draws the rest, then exits 1 naming them all; only a changed deployment stops the run at once. A timeout is retried once like a 503 (T046 changes T014's client). The book's stale-figure covers a chosen figure with no line and a line for an event with no figure; T024 and T046 gain the matching tests, and T037 follows T046. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the run A figure missing for want of an answer (no connection, a timeout, a 5xx) is followed by the same health and content-release read as a drawn figure; no answer or a change stops the run at once, so a hung or dead render service is not waited out figure by figure. The service's own timeout sits below the client's. A timeout is retried only in `figures`, not `serve`. The report is written however the run ends; two lines for one figure are incomplete-folder. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…a stated timeout A render service stuck while its health still answers is caught by a breaker: 2 x --parallel figures in a row unanswered, or nothing drawn for 5 x --timeout, stops the run. `figures` retries a 504 once as well as a timeout. Its client timeout is a flag, --timeout (default 60 s), which the render service's own timeout must sit below. The client names each missing figure's cause (unanswered, refused, invalid); only unanswered triggers the health read and counts towards the breaker. The report names causes and why a run stopped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s trip the breaker A 500 (or another 5xx but 502-504) is the figure's own failure, cause `failed`: it neither triggers the health read nor counts towards the breaker, so a run of figures failing on one ancestor's diagram never stops the run. `unanswered` is no connection, a timeout, a body cut short, or 502-504 after the retry. The breaker's count resets on any other answer, and its clock runs from the start of drawing or the last answer of any kind. A label failure is cause `label`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t does T046 still gave the breaker's old rule; it now cites contracts/figures.md's (count reset by any other answer, a clock from the start or the last answer), with a test that slow 500s do not trip it. `failed` and `unanswered` no longer overlap on 502-504, and a 502 is not said to be retried. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Nov 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Spec 001, T005 and T006. Replaces #83 to #94, with their reviews' findings fixed.
T005: a no-go. The render service, in the book's mix (85% reactions, 6% diagrams, 1% illustrations, 8% selections), cold, on a private copy of release 98's graph, on an 8-core host:
SC-003's figure budget needs 7.3 a second; the processors are the limit, and the cost per figure rises with concurrency. What T005 did not run, and why, is in research R7. Script:
ci/measure/throughput.ts.T006: the route taken. The figures are drawn by a step of their own before the book:
pdf-export figureswrites them to a folder with a manifest tying it to its release (newcontracts/figures.md), after running the book's release-file and character checks;book --figuresreads them, refuses a stale folder, and asks no render service. SC-003 is the book's time from figures already drawn; new SC-010 covers the figures' step. New task T046; T024, T029, T031, T037, T039 and T045 follow; contracts, research, data model, quickstart and plan updated to match.From #83's review: the script chose a selection's ancestor differently from the book and stalled its client while sampling CPU; both fixed and all four settings re-run. R7's per-figure cost claims now follow from the table.
From #84's review: the folder's manifest carries a fingerprint (the graph's release number and checksum, the content service's release, the render service's build);
figuresrefuses to resume another fingerprint andbookfaults it asstale-folder; a file is moved into place before its manifest entry; T046 follows T024. The runs' raw outputs are inci/measure/results/2026-11-02/.From #85's review: the fingerprint's parts are specified where they are read (render
buildin contracts/render.md, the graph checksum in data-model, the content release endpoint), and what it cannot see is stated and asked of WebsiteAngular (R10, T042). The manifest is an append-only journal; the script probes the service and fails on missing figures.From #86's review: a figures folder is complete only with a closing
completeline written after the end-of-run check;bookfaultsincomplete-folderandno-checksum.From #87's review: a failed run marks its folder
failedand is never resumed; the book requires the last whole line to becomplete.From #88's review: each figure records the render build and content release that drew it, replacing the end check and the
failedline; a resume cuts a torn tail before appending.From #89's review: no resuming.
figuresneeds an empty--out; a stopped run is rerun from scratch, so no folder mixes two runs or deployments. (This supersedes the per-figure build lines and resume rules described for #85–#88.)From #90's review: a figure's own fault no longer stops the run: the rest are drawn and every fault named; a timeout is retried once like a 503.
From #91's review: a figure missing for want of an answer triggers the health read, so a dead service stops the run at once.
From #92's review: a breaker stops a run whose render service is stuck while its health still answers; a 504 is retried once;
--timeoutis a stated flag; missing figures carry a cause.From #93's review: a 500 is the figure's own failure (
failed) and never trips the breaker; the breaker's reset and clock are defined.🤖 Generated with Claude Code