GENERATED VIEW · PRIVATE ARCHIVE · DO NOT SERVE
RobCo Industries · Archive Museum

WORKFLOW_REVIEW_PROMPT.md



STANDING

planning/_standing/WORKFLOW_REVIEW_PROMPT.md

sha256 c9f0c9ba1900b719 · 30639 bytes · original held in the private archive

# WORKFLOW REVIEW — blind external audit request > **Status:** kept CURRENT incrementally (owner directive 2026-07-18 — folding in ≠ sending). Last folded 2026-07-20 (museum + reproducibility, Protocol 50, the trim's remaining stages, and the two new sections §15–§16). SEND only once the in-flight wave settles. > **Target models:** paste into **GPT-5.6 Sol** and **Gemini 3.1 Pro Extended** separately, blind to each other. **DeepSeek is included ONCE for this review** as a third *witness* (§16) — and gets a **workflow-description-only cut**: strip §14 (museum internals), the archive/memory specifics, and anything repo-identifying, because its free tier retains and may train on inputs. That cut is built at send time, not here. > **Delivery:** hand the owner the block below as a fenced COPY-PASTE BLOCK in chat (not file-only). --- You are auditing the **working process** of a solo software project (one developer, plus his brother as the second user). Do NOT review the product's features or code quality. Review **the workflow itself** — how work gets planned, built, verified, shipped, remembered, and governed — and tell me **what's missing, what's fragile, and what you'd optimize.** "Nothing meaningful to add" is completely acceptable for any section; I'd rather have three real findings than twelve padded ones. **The one rule that makes your answer useful: be checkable.** A gap I can verify against how we actually work is worth ten that merely sound wise. Ground each finding in something concrete below. If a suggestion would violate a hard constraint in §1, don't make it — or argue explicitly that the constraint itself is wrong. ## 1. Context — just enough to judge constraints (NOT the thing under review) - **Solo developer**, sole maintainer and decision-maker. An AI agent ("the orchestrator") runs execution across many disposable sub-sessions; the developer directs. "The maintainer" and "the execution path" are different entities — process that assumes a human team mostly doesn't apply. - **Two real users:** the developer and his brother, both Android/Chromium phones. **Mobile-first.** - **Hard constraints any suggestion must respect:** free tier only (no paid infra/CI/server; AI features are bring-your-own-key) · **no build step** (plain vanilla HTML/CSS/JS, global scope, no bundler — deliberate) · offline-first + installable PWA · **save-sacred** (never silently lose user data) · the developer's hardware is modest. ## 2. The team model (all AI) - **The Orchestrator** never writes code. It absorbs scattered, evolving requests, consolidates them into one locked spec, routes work to disposable code sub-sessions, holds each to completion, and reports back in plain phone-readable English. **Turning messy input into a clean spec is explicitly the orchestrator's burden, never the developer's.** - **Three execution models, chosen per stage:** a design/creative model; a high-reasoning model (diagnosis, planning, independent auditing); an efficient model (implementation). ## 3. The build workflow 1. **Spec-lock** — no new requirements enter a running session; changes wait for the next unit. 2. **Plan** (high-reasoning) — investigate the real code, find the confirmed root cause (never a guess), enumerate EVERY entry path/state/edge case, self-audit the plan against that enumeration. No edits this stage. 3. **Implement** (efficient) — first critically review the plan against current code (line numbers and assumptions drift), then implement, run the gate, and verify the user-facing result by actually rendering/running it — never from headless measurements alone. 4. **Independent audit** (high-reasoning) — **starts from the diff and re-derives the truth; never reads the implementer's report.** Governing principle: **a session's account of its work is a claim, not evidence.** It reproduces red-then-green itself and re-checks facts against primary sources. A failed audit loops back to *planning*, not to more grinding. 5. **Definition of done** — written testable acceptance criteria up front; done only when each is verified on the real artifact. ## 4. The gate — what "done" means mechanically - **At commit:** lint, format, the test runner, and a cheap browser boot-smoke (so green means "it boots and paints"). **At push:** the full gate adds real-browser checks — boot, render integrity at mobile widths, accessibility, an offline-first behavioural test, and save-survival. - **Never bypassed.** **Self-improving:** any defect that escapes a layer gets a check added AT that layer in the same fix. - **Branch model:** all unreleased work on `dev`, held to an identical bar; `main` is release-only. - **Baselined debt pattern:** where a rule is violated by existing code (e.g. architectural layering), the current violations are captured as an accepted baseline so the gate stays green, and **any NEW violation fails the build** — the debt is counted, frozen, and can only shrink. ## 5. Governance ~45 numbered protocols, **each written in response to a real bug**; many backed by automated guards so the rule isn't honour-system. **The rulebook is now TWO LAYERS, not one file.** It used to be a single ~100KB document every session read top to bottom regardless of the task. It is now: a **short universal contract** (the rules that apply to all work and require human judgement, so cannot be mechanised) plus a **retrieval map** — touched files → which of ten path-scoped subsystem notes to load. A session touching the service worker reads the cache/deploy note; a session touching saves reads the state/durability note; neither reads the other. The driving principle, from an external review: *written is not the same as retrieved.* A rule only works if it is loaded for the relevant task, current, unambiguous, and more salient than the rules crowding it — and the repo had already disproved the old model (contradictory branch instructions, architecture file sizes wrong by 40×, a cache guard written AND hooked AND tested that still compared against the wrong branch). **There is now a RETIREMENT RULE, which the project previously lacked.** A rule may be retired when the risk it covers no longer exists or was never real — and retiring it means **removing its enforcement too, not just its prose**, since a check policing something no session can read is worse than either. Retire in place, never renumber, never reuse a number, and state plainly what coverage is genuinely lost. Three protocols are now retired on the page as dated records. This matters because the project's escape-ratchet (every escaped defect permanently adds a check) only ever ADDED; there was no release valve, and weight accreted whether or not the risks were still live. **A staged trim is underway**, not a single cut: stage one removed only rules with zero enforcement behind them. Stages 2–4 are now written into the queue (they had lived only in the orchestrator's memory) rather than left implicit: **(2)** convert prose-only rules into automated enforcement where they're expressible with zero false positives; **(3)** the contentious one — narrowing the universal escape-ratchet so it stops adding weight reflexively — is **explicitly gated on the owner's decision, not a session's judgement**; **(4)** cutting actual machinery (a dev-console's scope, a duplicate CI leg, nightly runs, a browser test page), each needing its own cost/benefit case. Every **keep-case** is recorded so it can't be re-litigated by accident (the architecture baseline, real-device auth verification, source-encoding integrity, cloud-safety, the cache bump, no-concurrent-pushes, and "actually render UI changes"). The staging is deliberate: later stages are gated on the restructure having been *used* for real work first — because staging without observation between stages is just one large amputation delivered in instalments. **Plans are now written where they live, not just remembered.** A new protocol requires any decision reached in conversation (new work, a scope change, a reorder, a close) to be written into the phone-readable queue **in the same session it's decided** — because a plan that lives only in the orchestrator's memory decays or dies when a session ends. It's backed by an automated pre-push nudge that lists every "ongoing-work" memory the queue doesn't appear to reference — a fail-safe reminder that can never block a push and stays silent where it can't read the memory store. (Honest limitation, now named in the protocol itself and in §16: it catches *memory-vs-queue* drift, not *conversation-vs-queue* drift — a decision made and acted on in one conversation, never written to a memory, still slips it. The project's conclusion, after that exact gap fired hours after the protocol shipped, is that the conversation-vs-queue case is **behavioural with no honest automated backstop** — a script can't read a conversation, and the sessions most likely to drop a decision are purely conversational and never reach the one hook where a nudge fires — so it is fixed by a session-end ritual, not a guard that pretends.) **A session acquires its context from FOUR sources, and the fourth was the unguarded one.** A session is oriented by (1) `CLAUDE.md` + the path-scoped `rules/*.md` notes, (2) the phone-readable queue, (3) the orchestrator's memory store, and (4) an installed **skill** that loads even before the repo is opened. The first three now each have some drift protection; the skill had **none**, had no tracked source in the repo, and had gone stale (a dead repo path, a deleted second test runner, a retired protocol cited as live) — found independently by two sessions. The instructive part is the *wrong* first fix and the correction. The first pass made the skill a hand-written **copy** of the rules and added a bespoke gate check plus a standing nudge to police that copy's drift — which is just building machinery to guard a second source of truth you chose to create. The correction (owner's tightening, an external completeness review's discipline): **the skill must not be a second source of truth at all.** It was rewritten as a **pointer** — it says where truth lives and restates nothing, so it has almost nothing that can drift — and both bespoke guards were **removed** for failing an explicit bar (a guard must earn its existence through a real, occurred failure at a defined enforcement point; one duplicated the existing doc-integrity check and only ever demonstrated itself against a synthetic case; the other guarded a divergence the pointer rewrite had already removed). The only residual risk — the pointer naming a deleted file — is caught for free by folding the skill into the *existing* doc-integrity gate. Net new mechanisms: zero. It is a clean worked example of preferring a direct fix (and a deletion) over accreting guards. ## 6. Verification philosophy (hard-won) - **Deterministic tools first** — if a plain tool (search, a computed-style check, a diff) can establish a fact, use it before asking a model. You can mechanically enforce honesty about *evidence*; you cannot about *reasoning*. - **"Green is scoped evidence, not proof."** · **"Make green mean the user can see it"** (a whole screen once rendered invisible under a fully green gate). · **"A citation guard proves a label EXISTS, not that the number is RIGHT."** · **"Test count is inventory, not confidence."** · **Axioms vs guidelines** — a rule becomes an automated guard only if expressible with zero false positives; a noisy guard gets ignored, then weakened, then dies. - **A worked lesson in NOT trusting a standard tool blindly (§14 has the full case):** when rebuilding the archive-museum's link addresses, git's own content-similarity rename detection was measured at a **22% undercount** on this corpus — and failed silently. The project's response was to refuse to build link-permanence on the heuristic that had just proved unreliable, and to use an explicit human-recorded ledger plus a git-diff tripwire instead. Deterministic ≠ correct; a deterministic tool still gets measured before it's trusted. ## 7. Session, git & continuity discipline - ⭐ **Every code session runs in its own GIT WORKTREE** — an isolated checkout that merges back on completion. This is worth stating explicitly because it is easy to miss and it changes what advice makes sense: a session that goes badly wrong fails in its own copy rather than contaminating the working branch. It is per-task isolation, automatic, with nothing to name or clean up. **Reviewers who assume sessions write into one shared checkout tend to recommend feature branches — that problem is already solved by different means.** - **Only two branches**, deliberately: all work on `dev`, `main` release-only. Feature branches solve parallel contributors and pre-merge review; there is one contributor and the review step is a diff audit *after* the commit. Release tags are load-bearing though — the museum's historical capture (§14) checks them out to render old versions. - **Serialize pushes** — never two sessions committing to the same repo at once. **Hash-verify every push** (sessions often report "pushing" while a multi-minute gate is still running). **Batch related work**, push once. **A fresh session per task** — never reuse one. - ⭐ **Concurrent sessions in the same repo can fail each other's gates through the WORKING DIRECTORY — a real incident, and nothing in the documented process anticipated it (2026-07-21).** The full pre-push gate runs `npx eslint .`, which lints the **entire directory including untracked files**. A scratch file belonging to a *concurrently-running* session was on disk during a push and **failed that push's lint** — while the commit had passed, because the FAST gate lints only *changed* files. So "serialize pushes" (above) and the per-task worktree claim do **not** fully isolate concurrent sessions: worktree isolation is asserted, yet these sessions were sharing a directory, so either worktrees weren't in force here or the isolation is incomplete against whole-directory lint. **This is a genuine gap in the isolation story, not just a friction — attack it.** - **The junk-sweep rule needs a concurrency caveat (same incident).** A session performing its Protocol 41 end-of-task junk sweep deleted three untracked scratch files that belonged to a **live concurrent session**, not a finished one. No harm — they were recreated — but the sweeping session noted that its own instinct had been to *surface* files it did not create rather than delete them, and that it **overrode that instinct**. The lesson: an automatic "delete untracked junk" step is unsafe while another session may be mid-task in the same tree; the safe default is surface-don't-delete for files this session didn't create. - **Continuity:** sub-sessions are disposable and amnesiac; durable facts (decisions, constraints, gotchas, rejected experiments and *why*) live in a persistent file-based memory the orchestrator maintains. - **Off-machine durability:** the repo is public, but the internal docs, planning artifacts, and the orchestrator's memory are gitignored/local-only — they're mirrored to a separate **private** archive repo via a one-command sync, because a machine loss would otherwise destroy them. ## 8. Reporting A plain-English, phone-shaped report after **every** landing and every push: what changed, whether it's live, and exactly how to test it. No jargon, no internal identifiers. Reports are not requests for permission. ## 9. The tacit layer — how we actually communicate - **Shorthand, decoded:** "go"/"keep going" = proceed and stop asking (auto-advance the whole chain) · **"yo" = a check-in; usually "are you alive / what's happening," and when I've just asked a question it means "yes, get on with it" — a nudge forward, not a question** · "resend" = the launch timed out or died, fire it fresh · "go with recs" = adopt the recommendation as stated · "fold all in" = incorporate every flagged item. - **Terse one-word replies** are normal — the owner is on a phone, semi-attentive, and wants momentum over ceremony. - **The owner is allowed to be scattered.** Consolidating scattered messages into one coherent spec is the orchestrator's job. - **Attention pattern:** marathon sessions with intermittent one-word check-ins. - **Economics:** usage is a real budget and the efficiency burden sits on the orchestrator (reuse context, batch, don't re-run what's known). - **NOT delegated:** design decisions, roadmap order, destructive actions, and real-device verification stay with the owner. ## 10. Known frictions in the human↔AI channel itself Messages that silently never arrive (so the owner re-asks and the orchestrator must re-explain rather than argue) · task launches that time out **and sometimes spawn a duplicate anyway** (this caused two real collisions) · sub-sessions that **hang forever** when they stop to ask a clarifying question, because their prompt can't be answered through the orchestrator — the fix is to abort and re-dispatch with the decision pre-baked · **abort commands a running session simply ignores** (so a replacement must never be launched until the original is confirmed idle) · long gates that outlive the tool timeout, so "push failed" usually just means "still running." · ⭐ **there is no completion event when a session finishes** — the orchestrator learns a session is done only by polling inside a live turn, and once its own turn ends nothing wakes it until the owner speaks (§15 traces what this does to the whole workflow). ## 11. ⭐ Unresolved tensions (named deliberately — attack these) - **"Auto-advance without asking" pulls against "wait for me before resending."** Both are standing instructions; they conflict at the boundary. - **There is no rule for when a long run should checkpoint versus keep going.** Marathon sessions happen; nothing defines when to stop. - **The owner is simultaneously product lead, approver, tester, and release authority** — with no defined change in process when tired or returning after a long gap. ## 12. How we already use external review Work is periodically sent **blind to two external models independently**, then the orchestrator synthesizes — treating agreement as *weaker* signal when it's the easy answer, weighting **disagreement** highest, and trusting a finding only when it's **checkable against the real code**. This has caught genuinely real things (a missing persistent-storage request that could silently evict a save; an end-of-life CI runtime; unenforced architectural debt). It works *because* findings were verifiable, not because the models sounded smart. ## 13. Options already explored and SHUT DOWN — with real reasoning (do NOT re-suggest unless a constraint changed) - **A local LLM as a delegated worker (7B via a local runner).** Rejected on measured evidence: plain text search beat it on **speed** (~0.2s vs ~90s) AND **accuracy** (100% vs ~75%), and its output still needed independent verification — negative value. ⭐ **Crucial nuance: this is a HARDWARE limit, not a rejection of local AI in principle.** A stronger small model would likely not hallucinate the way the 7B did, but **cannot run on the current hardware.** "Use a better local model" is understood and blocked by hardware, not philosophy. - **A spare laptop as a dedicated deterministic test/browser runner** — separate, still **unresolved**, not authorized. Fair to weigh in on; treat as open. - **A duplicate (second-language) test runner** — deleted. Caught nothing the primary runner couldn't, at ~13× runtime and double the authoring cost of every test. - **Blanket in-fiction renaming of features** — vetoed: clarity outranks flavour; a themed name ships only if instantly understandable. ## 14. The historical archive & museum — reproducibility treated as its own workflow test The private archive (§7) is also rendered into a browsable **museum** of the project's history — an index, per-release "rooms," file lists, mockup galleries, and a graveyard of abandoned ideas *with their reasoning*. It's included here as **evidence about the workflow**, not as a feature to review. - **Generated, never hand-curated** — every view is derived from the archive's structure, so it can't rot the way a hand-maintained doc does. The one hand-written part is a short per-release account, written at release time then frozen (three are frozen; the unreleased one is explicitly marked *draft*, honest that it hasn't shipped). - **A RITUAL, NOT A GATE** — the generator exits 0 no matter what and can never block or delay a release. It is **release-pinned**: it renders the *released* state at a git tag, never `dev`, and refuses to pin a tag that doesn't exist. - **The reproducibility sub-program (four sessions) is the part worth attacking:** - **A determinism bug a content-hash naming scheme turned catastrophic.** `core.autocrlf=true` in the machine's *system* gitconfig meant every fresh clone checked out CRLF while the generator writes LF; because pages were content-hash-named, that **renamed every page** on regeneration (a clean clone produced 269 deletions + 240 renames + 39 modifications), turning the publication diff — the thing meant to make disclosure visible — into pure noise. Fixed at the source (force LF; write LF). - **A gitignored file leaked into the public artifact** because generation walked the filesystem. Fixed by walking git's *tracked-file* list instead of disk (an untracked-but-unignored stray would defeat a gitignore filter). - **A measured, silent failure of a standard tool** (the §6 case): git rename-detection undercounted historical page addresses by **22%** (305 of 389). The lesson drawn was to *not* build link-permanence on it — use a human-recorded alias ledger plus a build-time git-diff tripwire. - **A wrong diagnosis, corrected.** Thumbnail nondeterminism was previously blamed on "PNG encoder jitter"; the real cause is CSS animations still running when the screenshot is taken. - **Publication (planned, after this release, before the next):** the private archive can **never** be made public — its git history retains internal memory files regardless of later deletion — so a *clean* new repo of generated output only is published, from **a separate host (Cloudflare Pages), never the GitHub Pages org site.** The reasoning is load-bearing: a GitHub project site shares the org's origin, hence **browser origin and localStorage, with the live app** — and the archive holds executable HTML prototypes. Name substitution runs with a **fail-closed guard**, and the publication diff is verified on a private target *before* public exposure (disclosure can't be retracted). Measured gotcha: the real public tree is **~190 MB** once the referenced mockup images are counted, not the ~19 MB the site folder alone suggests. ## 15. ⭐ The party you are NOT auditing by default — audit the orchestrator too The owner's directive, near-verbatim: this shouldn't only test whether the *models* hold their weight — it should test whether **the orchestrator (Dispatch) holds its own.** Attack this section hardest, because it's the party you have the *least* independent evidence about — it is also the only party that reads the raw transcripts (the asymmetry below). - **Observed orchestrator failures, all real, all this week:** didn't poll sessions to completion, so the owner had to prompt for results — took **three** corrections before it stuck; wrote in plain assistant text that is **invisible on the owner's mobile client**; compressed session reports until the owner **could no longer steer** from them; **inflated the project's age** when the changelog contradicted it; handed the owner a **museum path that never existed**, sourced from the orchestrator's own stale memory; got a **repo name's capitalization** wrong; carried a **queue item as open** that had closed days earlier. - **The structural finding (matters more than the list).** Twice in one evening the orchestrator proposed a design and a session *with real repo access* rejected it — a parallel ledger that would have duplicated a source of truth, and a hand-maintained manifest that is the exact failure a *retired* protocol existed to prevent. **The orchestrator proposed the anti-patterns the project is actively eliminating.** The working conclusion: **the orchestrator's design proposals are hypotheses to verify, not specs to implement** — sessions are briefed to push back. Today that is a *cultural habit, not a rule.* **Should it be a rule? How would you enforce it without a human in the loop on every proposal?** - **The asymmetry (open problem — no structural answer on file).** The orchestrator is the only party that reads session transcripts; the owner reads the orchestrator's *account* of them; every report is a summary whose shape the orchestrator chose. Put verbatim, from GPT-5.6 Sol asked about this independently: **"Where can Dispatch selectively absorb, weaken, or bury dissent?"** Treat it as unsolved. - **The tooling constraint (a constraint, not a personal failing).** There is no completion event or callback when a session finishes (§10); the orchestrator learns nothing except by polling inside a live turn, and once a turn ends nothing resumes until the owner speaks. This is why *"remember to poll"* never fixed the polling failure and naming the mechanism (*"do not end the turn until the session is confirmed idle"*) did. Dispatch is in beta; there's little external guidance. **What does a workflow that structurally depends on this constraint need that it doesn't have?** ## 16. ⭐ The multi-model hand-off and its cost — attack this specifically - **The copy-paste bus is the real bottleneck.** The owner is *personally the transport layer* between the orchestrator and every external model — doing it on a phone. Information degrades at every hop. Adding models multiplies this cost linearly and improves nothing about it. **Attack this directly rather than hoping to notice it.** - **The DeepSeek decision (recorded here because it lived only in conversation until now — itself a violation of the "write plans where they live" rule in §5, hours after that rule shipped; noted honestly because it reveals the drift check catches memory↔queue drift but NOT conversation↔queue drift):** - Include DeepSeek **once, for this review, in a narrow role — not a standing stage.** - **Must stay FREE** — hosted chat/app only, never the token-billed API. **Never a required gate** (a free hosted service can change terms or vanish). **Not run locally** — the hardware can't host anything worth hosting, and the local slot was already tested and rejected (§13). - Framing (GPT-5.6 Sol's, which the orchestrator endorses): DeepSeek is a **THIRD WITNESS, not a third JUDGE** — valuable only if its dissent is *preserved and answered*, never smoothed into consensus. Role: **blind hostile systems auditor** of orchestration complexity, epistemic integrity, and unjustified governance weight. - **Privacy constraint (also the honest reason it can't be repo-aware the way a GitHub-connected reviewer is):** its free tier retains inputs and may train on them, processed in China — so it gets the **workflow description only**, never repo contents, archive/memory, keys, or museum internals. - **The claim-ledger artifact (GPT's proposal + the owner-approved amendment).** A ledger of unique claims, disagreements, supporting evidence, evidence-needed-from-the-repo, and status (confirmed / refuted / judgment-call / unresolved). GPT proposed the *orchestrator* hold it; the amendment the owner approved is that it must be **a committed file in the repo, not something in orchestrator context** — otherwise it *is* the unchecked-summary problem GPT's own asymmetry question (§15) identifies, and it dies when the orchestrator's context ends. - **A rejected proposal, kept as a calibration specimen.** One external model (Gemini) proposed replacing Dispatch itself with DeepSeek-as-dispatcher on speed/cost grounds. It described **a workflow the owner doesn't have** (Dispatch launches sessions on the owner's real machine, reads their transcripts, and holds them to completion — a browser chat tab can't), **priced the argument in API tokens** when the constraint was *staying free*, and **hallucinated unrelated context** ("an ADB deployment script on a rooted device"). A clean specimen of the exact failure this review must guard against: *a confident, well-written answer to a question nobody asked.* Consider it a worked test of your own answer. - **Model-version caution.** Cited figures (a DeepSeek "V4" with a 1M-token context; "R1"/"V3") are past the orchestrator's knowledge cutoff and were flagged even by the model citing them as vendor claims. **Do NOT design around any advertised capability**; the owner verifies the current free offering himself. ## 17. What I want from you Answer these, grounded in the specifics above; skip any where you have nothing real: 1. **What's genuinely MISSING** — a class of failure this defends against nowhere, a stage with no check, a feedback loop that isn't closed? Name the concrete hole, not a generic best practice. 2. **What would you OPTIMIZE** — where is effort disproportionate to what it buys for a solo dev on free tier, and what's the cheaper equivalent? 3. **Where is it FRAGILE** — what single point of failure, or what reliance on discipline instead of an automated guard, would you harden first? 4. **The unresolved tensions in §11** — how would you actually resolve them? 5. **Of the shut-down options in §13, does any deserve reconsideration** given the real constraints (especially the hardware reality)? Only if you can say what changed the calculus. 6. **Anything to STOP doing** as low-value ceremony — with reasoning, since much of what looks like ceremony was born from a specific past failure. 7. **The orchestrator itself (§15) and the hand-off cost (§16)** are new to this review and the least externally audited. Weight them accordingly — the embedded questions there (should "proposals are hypotheses" be a rule; where can dissent be buried; what the no-completion-event constraint implies; how to attack the copy-paste bus) are the ones I most want a real answer to. Be concrete, be checkable, and say plainly if a section is already in good shape.
STAMP · generated for RELEASE v2.8.5 commit 06e5180 (06e51801b38a) · archive input-tree hash c07fbfbdd2e1ddeb · 754 files · no wall-clock timestamp (regenerates identically when nothing changed).