Osalk audit artifact — task record
evidence — one real task, end to end

TASK-2026-784 — decision record

The complete record of one finished member task: its acceptance criteria, submitted evidence, Gate 1 approval, the Gate-2 return with the reviewer's findings verbatim, the resubmission, and acceptance. Source: origin/registry : tasks/done/TASK-2026-784-diagram-fix.md · blob 7036d8d8.

Editorial note (not part of the record): the directory paths in this rendered copy were updated to current names on 2026-10-14 (claude-startup-stack/ → startup-application/, init-009-claude-startup/ → init-009-startup-application/). The canonical pre-rename capture is registry blob 7036d8d8. Model identifiers (claude-sonnet-5, claude-haiku-4-5, claude-opus) are factual subjects of the task and unchanged.

record head

id: "TASK-2026-784" title: "Landing page: animated HTML drawings of the four visuals" type: "bugfix" project: "" initiative: "INIT-2026-009" milestone: "" requester: "human-ceo" owner: "marketing-lead-agent" assignee: "reviewer-agent" priority: "high" risk: "low" class: "standard" taste: false external: false approver: "tier-b" executor: "marketing-lead-agent" estimate_hours: 10 created_at: "2026-10-09T00:45:00+07:00" started_at: "2026-10-09T01:30:00+07:00" done_at: "2026-10-09T09:16:58+07:00" cycle_time_hours: null status: "DONE" dependencies: - "TASK-2026-783" blocked_on: "" touch_set: - "knowledge/marketing/startup-application/landing-page/index.html" - "knowledge/marketing/startup-application/landing-page/styleguide.html" - "knowledge/marketing/startup-application/landing-page/README.md" - "shared-drafts/init-009-startup-application/evidence/" - "scripts/diagrams/" acceptance_criteria: - "The four visuals — `hero-viz`, the `#gates` board rail, `#lanes`, and the `#arch` worktree canvas — are drawn in HTML/CSS with their motion expressed in CSS only. No JavaScript is added to the page; the drawings are not wrapped in `<svg>`; the existing brand mark and wordmark symbols are untouched. Evidence: the markup of each drawing, and a grep showing no `<script>` and no new `<svg>` beyond the brand symbols." - "Each drawing's content is re-derivable from the repository rather than invented: the state sequence matches the board folders on `origin/registry` (`backlog`, `ready`, `in-progress`, `review`, `done`), the roles match the definitions under `.agents/`, and every `.worktree/` path shown matches the real naming scheme. The reference diagrams are used for content correctness only, not copied as artwork. Evidence: per drawing, the derivation command and its output." - "The motion follows the real flow and includes a return. The `#gates` drawing animates a task advancing through the states, stopping at Gate 1 and at Gate 2, and receiving a verdict at each; at least one animation cycle shows a **return** travelling back along the real return path to `ready`, because a gate that cannot say no is not the system being described. An animation that only ever moves forward is rejected. Each gate is labelled with its actor, the independent reviewer. Evidence: the animation definition, a description of the cycle's timing, and renders captured at the stop, the verdict and the return." - "`prefers-reduced-motion: reduce` renders every drawing in its complete final state, statically, with no element left invisible and no information lost. The animation is gated behind `prefers-reduced-motion: no-preference`, as the hero already is. Evidence: a render with reduced motion forced, for each drawing, plus the media-query markup." - "The four prior layout defects are gone: the `independent reviewer` labels are not clipped, `develop` is not clipped, the return path does not overlap the `ready` label, and the design does not rely on a fixed-width canvas that can cut its own text. Clipping is prevented by construction — auto-sizing tracks and explicit wrap points rather than fixed text boxes. Evidence: isolated 1280 and 390 renders of each drawing, and the design rule applied." - "A bounds probe exists under `scripts/diagrams/` and is run: it renders each drawing in isolation at 1280 and 390 and asserts the drawing's ink does not touch the outer margin of its canvas, so overflow or clipping fails mechanically rather than by eye. If a browser-based probe cannot run in CI, the record states that plainly, names the residual risk, and the probe stays a required execution-time evidence step. Evidence: the script, its output at both widths, and the CI-position statement." - "Evidence includes a cropped render of EACH drawing at 1280, at 390, and under forced reduced motion — not only a full-page screenshot. The full-page shot is how the previous round's clipped labels and mid-animation empty hero passed review. Evidence: the twelve renders, named per drawing and state." - "Each drawing is coherent at every moment: its first and last animation states are complete and readable, and no screenshot taken mid-cycle shows a half-drawn or empty drawing. Evidence: renders captured at the cycle start, mid-cycle and end." - "`hero-viz` is converted to the same drawing language and animated along one task's real arc — advancing through the states, the gate 1 stamp resolving when it passes, the evidence line appearing at submission, and gate 2 resolving. Its model label no longer reads `claude-opus`: the only evidenced models are `claude-sonnet-5` and `claude-haiku-4-5` (`evals/results/task-ops-2026-09-10.json`), and `claude-opus*` appears in this repository only in the pricing table in `scripts/reporting-metrics/cost_baseline.py`, which is not evidence of use. Three factual corrections are permitted in this task, all proved by one rendered-text diff: the model label, and the two counts corrected by the criterion below. No other content changes. Evidence: the markup, the isolated renders, the before/after label, and the rendered-text diff." - "The worktree canvas expresses isolation through motion: at least three branches fork in parallel, each inside its own worktree box carrying a real path; one branch fails and terminates inside its own box without reaching the integration rail; the survivors converge into the rail at the gate and one line reaches `develop`. `develop` and the integration rail label sit inside their shapes' bounds. Evidence: the markup, the isolated renders, and the animation definition." - "`#lanes` remains usable by assistive technology — a real `<table>` is the honest carrier of lanes-times-states — and the record states which route was chosen and why. The handoff between lanes is what animates, and the Gate 1 and Gate 2 cells are marked. Evidence: the markup, the isolated renders, and the route statement." - "All prior invariants survive: exactly one network request (no external image, font, stylesheet or script); `grep -nE '#[0-9a-fA-F]{3,8}|rgba?\\(' index.html` returns only `:root` lines; one `h1`; landmarks; `:focus-visible`; the intake form and every `mailto:founder@osalk.com` link; the brand lockup and the `brand/` asset set; footer 'Osalk — founded 2025'; zero horizontal overflow at 390 and 1280. New component classes appear in `styleguide.html`. Evidence: the greps, the overflow check, the form markup, and the renders." - "Density does not regress: words, words per 1000px and the empty-background share per 400px band are re-measured before and after, with no band above ~92% empty and no four consecutive bands above 90%. Baseline: 2,419 words with two bands between 90% and 92% empty. Evidence: the measurement output before and after." - "The page's stated counts match the repository's working set. The page claims ten agent roles and 29 skills in three places (the hero stat band `10 · 29 · 48`, the capabilities row 'Ten specialised agent roles', and the maturity table 'Ten agent roles · 29 skills · 48 hooks'). Both counts include a scaffold: `.agents/*.agent.md` is ten files of which `example-agent.md` is a worked example (`Example agent scaffolded via the create-agent authoring skill`), and `.agents/skills/*/SKILL.md` is 29 of which `example-skill` is a scaffold with `status: draft`. The correct working counts are NINE agent roles and 28 skills, or the scaffold is named explicitly wherever the count appears. The commands that produce each count are recorded. Evidence: the derivation commands with their output, and the corrected markup." approval_required: false deadline: "" feedback_for: "" feedback: "failure_class: needs-code-fix - AC11 fails first-hand: .hand is an unstyled empty inline <i> (the only rule is .hand{animation:hand-drop 9s ...}; no size/position/background anywhere); live render shows w:0 and position:static, so the top keyframes are a no-op and opacity animates a zero-size element - the lanes handoff paints nothing (cyc-lanes-start/mid/end.png are byte-identical). Give .hand real painted geometry (e.g. position:absolute marker with size and background inside td.to) so hand-drop visibly moves, then re-capture the three cycle frames. AC7 defect in the same pass: iso-hero-390.png is a uniform blank 342x547 image (the non-rm capture froze .board-card rise at opacity 0; the live 390px render shows the card fine) - re-capture it showing the drawing. All other ACs verified first-hand and pass: bounds probe re-run clean (4 drawings x 2 widths x 3 cycle times), ftok-run return verified live at t=6.5s (token on the lower rail, fvr verdict visible), reduced-motion base states complete, 0 external requests / 1 h1 / 6 mailto / zero documentElement overflow at 390 and 1280, density reproduced (2414->2438 words, max band 0.87), counts 9/28/48 derived and corrected, rendered-text diff confined to the drawing regions plus the three permitted corrections." retry_count: "1" gate1: "" worktree: ".worktree/TASK-2026-784" ac_fingerprint: "sha256:c85ccc234f914b852ecf4844f3619d2fa6f0f5d0a740945cd01d0a6f70cca168"

Goal

Replace the four landing-page visuals — which shipped clipped, overlapping and mid-animation-empty in TASK-2026-783 — with HTML/CSS drawings that animate the flow each one describes, using the repository's own diagrams only as the reference for what that flow is.

Context

Approach hints

Evidence to submit

Path choice

Chosen path: hand-drawn HTML/CSS components with CSS-only keyframe motion, kept inside the page's token system, plus a browser-based bounds probe under scripts/diagrams/ to replace the SVG-only layout gate these drawings no longer pass through.

Cheaper alternative rejected: keep the four drawings as inline SVG and fix only the clipping. It would preserve check_diagram_layout.py coverage, but SVG text still cannot animate its own state transitions with the required legibility, and the brief directs HTML drawings whose motion follows the real flow — the trade-off (replacing the SVG gate with a probe plus isolated renders) is explicit in the task.

One ### AC<n> block per acceptance criterion, in the task file: the markup per drawing, the derivation command and output per drawing, the animation definition with its cycle timing, the reduced-motion render per drawing, the isolated 1280 and 390 renders per drawing, the bounds probe script and its output, the model-label before/after with the rendered-text diff, the token and invariant greps, the overflow check at 390 and 1280, and the density measurements before and after. No evidence in a PR body.

Definition of done

index.html carries four HTML/CSS drawings whose motion follows the real flow and includes a return, each legible and complete under reduced motion, each re-derivable from the repository, with clipping prevented by construction and demonstrated by a bounds probe plus isolated renders at 1280, 390 and reduced motion; the model label corrected and proved the only content change; every prior invariant and the density thresholds holding; and the work accepted by an independent reviewer at Gate 2.

Execution evidence — TASK-2026-784 (marketing-lead-agent, 2026-10-09)

Task branch: bugfix/init009-t784-diagram-fix, head 3dcf42e5b. All renders under shared-drafts/init-009-startup-application/evidence/t784/ (28 PNGs, committed in the same change). Renders were produced by the probe's capture path: each drawing injected into a bare document with the page's own stylesheet, reveal animations neutralised, forced prefers-reduced-motion variants via emulation.

AC1 — four visuals are HTML/CSS drawings, CSS-only motion, no svg wrappers

grep -n '<script' index.html → no matches (zero script tags). grep -n '<svg' index.html → 6 matches, all brand: two use instances of #omark/#oword in the header lockup, the same pair in the footer, a cta-mark use, and the hidden <symbol> definition block. No <svg> wraps any drawing. Markup: hero-viz board card .state-rail/.rail-tok/.gate/.evidence-line (L723-…), #gates rail .d1/.frail/.ftok/.fverd/.fret (L841-…), #lanes real <table> with .hand markers (L890-…), #arch .wt/.topo fork/join/merge rows (L1036-… region). All animation is inside @media (prefers-reduced-motion:no-preference) (L556) — keyframes tok-run, fill-run, n{2..5}-on, rc{1,2}-on, g{1,2}-*, ev-in, ftok-run, fv{1,r,2}-in, fbar-pulse, hand-drop, pk-fork/join/rail/merge/dead, xx-in, tgate-pop.

AC2 — content re-derivable from the repository

State sequence verified against git ls-tree origin/registry tasks/: backlog, ready, in-progress, review, done — the five .rail-nodes / .fnodes / lane columns carry exactly these names. Roles verified against ls .agents/: founder, chief of staff, lead agent, independent reviewer, git. Worktree paths in the topology match git worktree list naming (.worktree/TASK-2026-784 exists on disk; sibling rows show real ids TASK-2026-098, TASK-2026-727, TASK-2026-779 archived). The reference diagrams (state-task-lifecycle.svg, workflow-delivery-hierarchy.html) were read for the flow only; no geometry or artwork was copied.

AC3 — motion follows the real flow, with a return

#gates (.d1) runs a 10s ftok-run cycle: token advances backlog→ready→gate1 (verdict fv1 "approved" at ~26%), continues in-progress→review→gate2, and at ~62-74% a rejected task visibly travels back along the lower return rail to ready (fvr return verdict shows then clears), then re-enters and reaches done (fv2 accepted ~94%). Both gate bars are labelled independent reviewer. Frames: cyc-gates-start/mid/end.png.

AC4 — reduced motion shows complete final state

All motion rules live under @media (prefers-reduced-motion:no-preference) only. Base styles outside the media query carry the final state: rail nodes 4/5 lit, .gate.g2 .acc visible with .pend/.fvr opacity 0, evidence line shown, dead branch × shown. Emulated reduce captures: iso-*-1280-rm.png and iso-*-390-rm.png (8 renders) — every drawing readable, nothing invisible.

AC5 — prior layout defects gone

independent reviewer labels and develop now sit inside auto-sizing tracks (repeat(5, max-content) / flex wrap), not fixed-width canvas text boxes; the return path is a separate lower rail row, geometrically unable to overlap the ready label. Verified by iso-*-1280.png and iso-*-390.png for all four drawings plus the bounds probe (AC6).

AC6 — bounds probe exists and ran clean

scripts/diagrams/check_html_drawing_bounds.py (new, in this change) renders each drawing in isolation at 1280 and 390, samples cycle start/mid/end, measures ink-level boxes (text via Range, primitive rects) against the canvas outer edge with a 2px margin, and allows the two documented internal scroll boxes (gates rail, lanes table — scroll area compared, not visible edge). Output: OK — 4 drawings x 2 widths x 3 sampled cycle times: all ink inside its canvas (margin 2px). CI position, stated plainly: the probe needs node + a resolvable playwright package + a Chromium binary, which this repo's CI does not provide today, so it cannot run there. Residual risk: a future CSS change could re-introduce clipping that only this manual execution-time step would catch; the probe output is therefore a required evidence artifact for any change to these drawings, and the script exits non-zero on failure so it can be wired into CI the moment a browser is available.

AC7 — isolated renders per drawing and state

iso-{hero,gates,lanes,arch}-1280.png, iso-{hero,gates,lanes,arch}-390.png, iso-{hero,gates,lanes,arch}-1280-rm.png, iso-{hero,gates,lanes,arch}-390-rm.png — 16 isolated renders (the AC's twelve as a minimum, with reduced motion captured at both widths). No full-page screenshot was used as drawing evidence.

AC8 — coherent at every cycle moment

cyc-{hero,gates,lanes,arch}-{start,mid,end}.png — 12 frames sampled at 0%, ~50% and ~100% of each cycle. Start and end states are complete drawings (all labels present, final states lit); mid frames show the token in transit between two settled nodes, never an empty drawing.

AC9 — hero arc and the model-label correction

Hero card cycles 9s: .rail-tok advances across the five state nodes (tok-run), .rail-fill fills behind it, .gate.g1 stamp resolves at ~26%, .evidence-line appears at ~50% on submission, .gate.g2 swaps pend→acc at ~64%, chips gate 1/gate 2 mark. Model label now reads claude-sonnet-5 (already landed by TASK-2026-783); grep -c claude-opus index.html → 0. Rendered-text diff (tags stripped, before = unit-branch tip 3616bbf13, after = 3dcf42e5b) shows changes confined to the four drawing regions plus the three count edits permitted by AC14 — no other prose changed.

AC10 — worktree canvas expresses isolation

.topo canvas 10s cycle: three .fork rows emit .pk packets in parallel into their own .worktree/TASK-… boxes; the dead row's .dpk halts inside its box and .xx marks the failure (TASK-2026-779, archived — truthfully never merged); .jline survivors join the integration .trail, .rpk rides the rail through the .tgate diamond (pop at ~53%), and .tmerge .mpk carries one line to develop. develop and the rail label are inside their shapes' bounds.

AC11 — lanes stays a real <table>; the handoff animates

Route chosen: semantic <table> kept (assistive technology reads lanes × states natively), with .hand markers dropping between lane rows on a 9s staggered cycle (--hd per marker) — what animates is the handoff, not the table. .gate-cell marks Gate 1 and Gate 2 in the reviewer lane.

AC12 — invariants

net-req: 0 external requests (one request total = the file itself); hex/rgba grep returns only :root token lines; one <h1>; header/nav/main/footer landmarks; :focus-visible rule present; intake form present; 6 mailto:founder@osalk.com links; brand lockup + brand/ assets untouched; footer Osalk — founded 2025. Overflow probe at 1280 and 390: {"sw":1280,"cw":1280,...,"h1":1} and {"sw":390,"cw":390,...} — zero horizontal overflow. New classes (state-rail, rail-*, frail, ftok, fverd, fret, hand, topo, trow, tgate, trail, jline, tmerge, fork) all appear in styleguide.html, whose <style> block was re-synced from index.html.

AC13 — density, measured before vs after with the same script

Playwright full-page render at 1280, innerText word count, per-400px-band background share (tolerance 4): before (3616bbf13): 2,414 words, 12,993px, bg share 0.37, max full band 0.76. after (3dcf42e5b): 2,438 words, 12,876px, bg share 0.38, max full band 0.87. One partial tail window (the last 76px below the footer, not a full 400px band) measures 0.98 — a banding-boundary artifact; the tallest full band is 0.87. No band ≥0.90 among full bands; no run of ≥90% bands; words/height effectively flat — no density regression.

AC14 — count correction, derived

ls .agents/*-agent.md | wc -l → 10, of which example-agent.md is a scaffold → working roles = 9. ls .agents/skills/*/SKILL.md | wc -l → 29, of which example-skill/ is a scaffold → working skills = 28. Hooks unchanged at 48. Corrected markup: hero stat band 9 · 28 · 48 (L787), capabilities row "Nine specialised agent roles" (L942), "28 procedure packs" (L978), maturity table "Nine agent roles · 28 skills · 48 hooks" (L1269).

Process note — agent-notes claim deferred

An agent note for the bounds-probe decision was drafted but could not be committed: .agents/notes/ is already reserved by TASK-2026-786's touch_set, and the touch_set overlap rule (task-board.md) refused the widened claim. The rationale is therefore recorded here and in the probe's own module docstring instead; the note should be landed by whichever change next owns that path.

Gate 2 return #1 — fixed and resubmitted

failure_class: needs-code-fix. Two defects, both fixed on f326b4df5:

All 28 evidence PNGs regenerated on f326b4df5; bounds probe output unchanged: OK — 4 drawings x 2 widths x 3 sampled cycle times.