app
Adom Gantt
Public Made by Adomby adom
Interactive Gantt chart viewer for project timelines, with a table view and an analytics page over the same data. Data-driven, dark by default with a print-friendly light mode, and fully editable in the browser: drag bars to move or resize, multi-select and batch-shift dates, manage dependency arrows inline, reorder rows, filter by phase, and undo. One click auto-schedules the whole plan so every dependency lines up finish-to-start on working days, skipping weekends and US federal holidays, push
← Commit history
docs: three-musketeers build handoff for the 0.8.x table view line
1 file changed
+65
docs/build-2026-08-07.mdadded+65@@ -0,0 +1,65 @@+# three-musketeers build, adom-gantt table view + DC demo granular plan, 2026-08-07++**Task:** Add a table view (second lens) to adom-gantt with owner/deadline/status columns, per-owner filter, and inline edit, pushed to main; rewrite the DC demo plan data as granular subtasks with owners and deadlines, DoW audience woven in, hiring excluded.+**Stage:** live instance on port 8901 serving `/home/adom/project/dc-demo-gantt/dc-demo.json`; source pushed to wiki main `adom/adom-gantt`.+**Rounds:** 4 (initial build, two fix rounds, one micro-round).+**Models:** Builder Opus, Adversary Fable (fresh context per round), Verifier Sonnet.+**Final version:** 0.8.4, commit `40015e5e8842488a133b448be66118bac93b1e43`. Interim commits: 0.8.0 initial, 0.8.1 `87635bc`, 0.8.2 `80b3e49`, 0.8.3 `f937ea5`.++## What was built++**Table view (0.8.0 to 0.8.4).** A `Gantt | Table` header toggle over the same in-memory items. Columns: Task, Phase, Owner, Start, Deadline, Status, Notes. Sorting on every column (deadline ascending default, blanks last both directions). Filters: owner dropdown (All / Unassigned / distinct owners, persisted), status dropdown, free text, Clear; the legend's phase and Milestone toggles drive both lenses. Inline edit of Owner, Start, Deadline, Status, Notes with Enter/Esc/click-away semantics; edits flow through the existing scheduleSave pipeline into the sidecar and changelog, reflect in the Gantt immediately, survive reload, and are one undo step. Sidecar bumped to v3 (additive owner/status/desc on tasks and milestones; v1/v2 still load). `owner` is a first-class item field carried by /export/json and /export/csv and read back by CSV import. New changelog actions: owner, status, desc, milestone.rename, import.++**Hardening delivered along the way:** stable `#row<n>` keys for id-less rows with an all-or-nothing order application (client and server, textually parallel ladders); crash-proof changelog rendering and a server that survives arbitrary malformed /log posts (validated shapes, 8MB body cap, headersSent guard, uncaughtException backstop); stored-XSS closed at the tooltip and eleven other innerHTML sinks; script-breakout closed in the HTML snapshot export; duplicate-milestone-name resolution; server-owned monotonic rev counter; CSV formula-injection guard and lossless phase-name round-trip; import validation that rejects dateless rows by name; client render that drops undateable rows with a dismissible warning instead of dying; SVG export resilient to the same class; brand fonts actually loading for the first time (adom.inc font URLs were CORS-blocked since forever; now Google Fonts + cdn.fontshare.com with verified ACAO).++**DC demo data (`/home/adom/project/dc-demo-gantt/dc-demo.json`).** 73 items: 6 lanes (Hardware, Test, Logistics, Software & Content, NSF Coordination, Event) with lane leads in the group labels, 58 granular tasks each with a unique id, a single named owner, start, deadline, status, description, and real dependencies; 9 milestones on the plan-of-record backward-scheduled checkpoints. Four DoW-audience tasks woven into Software & Content and NSF Coordination (Dan x3, John x1). The reflow gap from team chat is in as hw-pcb-reflow. Nothing about hiring the NSF Liaison PM. Zero dependency inversions.++## Plan amendments (builder was right where the plan was wrong)++- Legend stays visible in table view and filters it, so the two lenses can never disagree; chart-only controls hide.+- Task/milestone names are not editable in the table (rename-vs-state-key hazard); milestone rename lives in the milestone editor, and was made to actually persist, which it never had.+- Start dates are editable in the table, not just deadlines.+- Undo covers table edits (spec allowed skipping), and this closed a pre-existing milestone-rename undo gap.+- Group rows are not table rows; the phase column carries grouping so sorting keeps meaning.+- Id-less tasks render read-only rather than pretending to persist an unkeyable edit.+- Import rejection over defaulting for dateless rows: an invented date is indistinguishable from a real one once written.+- SVG export names dropped rows in an XML comment rather than skipping silently.+- Fontshare's CSS endpoint loads a stylesheet with zero font-face rules; Satoshi is declared directly against cdn.fontshare.com.++## Adversary findings resolved++Round 1 (16 findings, 2 Critical): milestone rename silently deleted the row on reload; one malformed changelog event killed the server permanently and re-killed it on restart; stored XSS via Notes; `</script>` breakout in /export/html; duplicate milestone names misrouting edits; no-id sidecar entries corrupting group rows; client-forgeable rev counter; phantom reorder instead of rename events; CSV formula injection; CSV round-trip destroying phases; unescaped first-paint labels; unbounded request bodies; dropped group-owner labels and 18 dependency date inversions in the data (adversary flagged 8; builder's sweep found 10 more). All fixed in 0.8.1, none rebutted, each reproduced before fixing.++Round 2 (verifier, behavioral): Gantt tooltip stale after reload (plus a sibling gap on diamond-style milestones the builder found); changelog able to claim an edit the closed tab never persisted. Fixed in 0.8.2 with a pagehide/visibilitychange flush via sendBeacon; /log shape validation and a loud import changelog event taken as minors.++Round 3 (dry-well adversary): server export path missing the stable-key ladder (exports disagreed with the screen after rename+reorder, owner silently dropped) with the root client/server key asymmetry; dateless rows bricking the chart; changelog markdown line spoofing via embedded newlines; fonts never loading. Fixed in 0.8.3.++Round 4 (micro): /export/svg 500 on hand-corrupted dateless rows, plus two same-class defects (dateless phase throw, negative width on fully dateless data). Fixed in 0.8.4; normal-path SVGs byte-identical pre/post.++## Behavioral verification (Sonnet verifier, headless Chrome, screenshots)++| Flow | Result |+|---|---|+| Gantt render: 58 tasks, 9 milestones, 6 lanes, lane leads, arrows, today line | PASS |+| Milestone tag pairwise non-overlap | PASS (0 collisions) |+| Table toggle, 67 rows, correct columns, no "undefined" | PASS |+| Owner/status/text filters, clear, sort | PASS |+| Inline edit: commit, cancel, reload persistence, changelog, undo | PASS |+| Milestone rename round-trip, no row loss, rename event logged | PASS |+| XSS probes: table, tooltip, exported snapshot (re-opened standalone) | PASS |+| Malformed /log posts: server survives, md renders | PASS |+| CSV export/import round-trip: owners, phase names, literal payloads | PASS |+| Data sanity as served: owners, date window, deps, DoW, no hiring | PASS |+| Computed-style looks: fonts, dark tokens, row heights, no overflow | PASS |+| Round-2 fixes re-verified: tooltip freshness both milestone styles, flush inside debounce, single-event logging | PASS |+| Round-3/4 fixes re-verified by the finding adversary: all DEAD at root | PASS |++## Open items / human calls++- No human eye has seen the UI: every check was headless (pup bridge down, adom-desktop-puppeteer-bridge#33). Spacing, colour, and the newly-loading typography deserve a glance.+- No package release was cut: main has 0.8.4 but `adom-wiki pkg install` still delivers the last released version. Cut a release when ready.+- Recommendation for the platform: serve `Access-Control-Allow-Origin` on adom.inc/fonts so every Adom app's font-face rules work; the CORS block was silently defeating them all.+- MS Project XML and Jira CSV imports do not carry owner (no unambiguous single-owner field in those formats); CSV and both exports do.+- No batch reassign in the table (chart's batch editor remains date-only).+- /log remains unauthenticated by design; rev framing can no longer be forged, but posted event text is trusted prose.+- Live instance state and changelog were reset to pristine twice during the build after verified-net-zero inspection of test noise; the plan data file itself was never touched by tests.