24 sprints, 210 tracked items
This page is read from plan-status.csv, the same ledger the project workbook is built from. Nothing here is a hand-written release note — a changelog maintained by hand stops being true in week three.
It includes the findings, not only the features: what was measured, what was wrong first time, and what was refused. That is the part of a changelog worth reading.
- F23-01the method is DERIVED not declared - no fixture carries an integration-method field, and inventing one would have meant inventing architecture. Credential+schedule=API, csvOnly=import, no project=unbound
- F23-0212 arms on the ring ordered by how much depends on them, 66 leaves; the planned SDK lane gets its own slot so it reads as a lane not a missing system
- F23-03CORRECTION MID-SPRINT: the plan said no document proposed an SDK. R-D-19 does, 02 diagrams the signing flow, and /integrations/api already promises departments it will speak the same contract. Drawn DASHED and empty - solid would claim a lane that does not exist, absent would drop a promise already made
- F23-0454 of 66 systems are NOT drawn and the number is in the callout heading, not a footnote - an architecture diagram gets quoted long after the caveat is forgotten
- F23-05/integrations/map beside the coverage table - the same data in the two shapes people ask for it in
- F23-06209 svg paths, 45 rects, 66 leaf circles verified IN THE SERVED HTML. 900 renders 0 bad; a11y 0; 209kB, under budget. 37 of 140 metrics are on a real feed; 103 arrive some other way
- F22-01the defect was not 11 narrow pages - it was FIVE different content widths across 42 pages and no rule anywhere. One width on <main>; 40 page roots stripped
- F22-028 nested refusal panels KEPT narrow - those are short messages, which is narrow CONTENT not a narrow page. Only 2 unmeasured long paragraphs were exposed by the widening; both measured
- F22-03DESIGN.md gains the content-shell rule so the next page cannot invent a sixth width
- F22-04a wand, not the AEON ring F18 put there - the ring answered the chatbot problem with brand instead of with what the thing does. Drawn inline to match hugeicons ai-magic, not copied: this codebase ships no icon library by design
- F22-05D1 and D2 could not be equal while LAYER-1 COVERAGE shared D2's column. The coverage card is the CONCLUSION of both panels, so it became a full-width band underneath - which is also where it belongs
- F22-06each card pins its closing paragraph with mt-auto, so the pair aligns by construction rather than by luck
- F22-07width audit of the SERVED HTML across all 16 routes: shell=max-w-6xl, 0 stray roots. 890 renders 0 bad; a11y 0; no new perf breach
- F21-0111 checks, each returning the ARITHMETIC not a verdict - these findings name a data owner, and a detector that cannot show its working is an accusation (R-G-19)
- F21-02MAD not standard deviation: 24 points and one outlier destroy a mean, and the outlier is the thing being looked for, so it would hide itself (A-76)
- F21-03B1-B5 over 8 feeds. B1 reports NOT ENOUGH DATA on all 8 - median batch is 3-16 rows, so a 50% shift is one or two rows and the test would fire on noise
- F21-04S1-S6 over 140 metrics. S1 at 6xMAD alone flagged 62 of 140 - noise. Adding a 15%-of-level gate took it to 1. A detector that flags 44% of the registry is not a detector
- F21-05SEEDING TURNED OUT UNNECESSARY - the real fixtures carry 13 findings including 5 high. A-77 was written expecting to need seeds and the honest outcome was better
- F21-06findings / not-enough-data / everything, with the per-check table showing what each one returned - including the 3 checks that found nothing anywhere
- F21-07per-metric page lists EVERY check including the clean ones - a page that only showed failures would let a reader believe the rest passed when several could not run
- F21-08batch checks on the deliveries tab, where the deliveries are; not gated on a feed role, because a metric owner must be able to see whether their own number behaves like a measurement
- F21-09the memo's integrity line - day by day is where the ask puts it
- F21-10THE FINDING: AP-12 KRI 376/2024 fraud-and-collusion-detected has reported 0 for 24 consecutive months. On the module the feedback called fraud detection, the top result is that the FRAUD METRIC has never moved - true, or a dead feed, and the platform cannot tell. 890 renders 0 bad; a11y 0; 13 findings 511 clean 298 not-enough-data
- F20-01one decomposition function; scope applied before anything is shaped, as R-S-17 forces on boards
- F20-02THE FINDING: computing the perspective score over the whole registry gives a DIFFERENT number from the company card - PL 130 against a GAP, IP 58 vs 45, F 87 vs 98. Two numbers for one perspective is the forty-NPL problem in miniature, so the page shows both, labels which the scorecard uses, and leads with that one
- F20-03spendable share per perspective: F 29% C 9% IP 40% PL 3%. PL's company score is a gap and its registry score is one metric of nineteen
- F20-04reachable from every perspective label on the BSC; the card denominator reconciled - 5 named metrics on 6 rows, because one row is an objective with nothing measuring it
- F20-05ID coloured by perspective with a legend; the PERSPECTIVE column still says it in words so colour is never the only channel
- F20-0666 systems over 140 metrics; needs no new fixture - every field was already on a metric page where nobody could add it up
- F20-0756 systems bound to no feed; 2 in no ACF inventory carrying 5 metrics (R-G-01)
- F20-08six steps ending at a registry pull request - a create-a-metric form was the easier answer and the wrong one (A-11)
- F20-09a11y FAILED on two ink-faint usages - out-of-scope IDs now carry a lock glyph instead of being dimmed. 830 renders 0 bad; both new routes under budget
- F19-01built on <details> so there is NO client JS at all - the menus open with JS off and cost nothing on 57 routes. Every item labelled built / in the estate / not built
- F19-02initials not a photograph - an avatar image would be personal data on every route, for a decoration
- F19-03sign out is REAL: the persona cookie is the auth stand-in, so clearing it genuinely returns you to the default reader. Writes an audit event; verified 303 + cookie expiry
- F19-04/whats-new reads plan-status.csv - 19 sprints, 170 items. Carries the FINDINGS not only the features, which is the part of a changelog worth reading
- F19-05/docs reads the repo front matter - 16 deliverables with what each ANSWERS, the one thing front matter cannot say
- F19-06/feedback reads feedback/ - 5 rounds and what each produced, including where the ask was right for a different reason than the one given
- F19-07support items bound to ManageEngine ServiceDesk Plus, which is already a SOURCE SYSTEM here behind IT-04..IT-10. Q-08 blocks both the ticket link and the IT pack's automation - one question, two closures
- F19-08no form on /feedback, deliberately - a feedback box in a prototype posts into nothing. 770 renders 0 bad; a11y 0; all three pages under budget
- F18-01StatusPill and Callout - one definition for what was 19 copies of a left bar. Both require a glyph AND a label, which is the constraint that did not change
- F18-02the tile encoded RAG THREE times - edge bar, corner dot, inline icon. Now ONE pill under the value. Tint reserved for stale and regulatory-off: 5 tiles of 140, so the emphasis still means something
- F18-0312 status callouts migrated across 11 files; verified 0 left bars remain on /compliance /govern /me /campaigns /reports /boards
- F18-044 perspective cards and 2 simulator tables KEEP the left rule - a grouping is not a status, and it is the only thing holding those tables together (A-73). Plus one neutral quotation rule on comments
- F18-05--color-aeon-persp-* replaces three copies of four literals; teal darkened #0E8A8A -> #0A7070 because 4.18:1 is fine as a border and a FAIL as text, and F20 makes it text
- F18-06the stock robot became the AEON ring with a reading rule - on a product whose first sentence is I am not an AI model, a robot says chatbot before the panel says explainer
- F18-07DESIGN.md's RAG-channel rule amended in place with the reasoning and the exception, not quietly rewritten
- F18-08a11y 0 failures; 740 renders 0 bad; 286 answers 174 refusals 0 bad; no new perf breach
- F17-01hand-built SVG; edge status carries BOTH a line style and a glyph so the causal claim does not depend on colour; every node is a link, which a canvas symbol could never be
- F17-02six columns, transforms labelled on the edges, blocked nodes named in prose underneath - this is Internal Audit's first question and a blank panel was answering it with silence
- F17-03MEASURED: /metric/CG-01 441->427kB, /metric/FN-01 440->423, /bsc 429->414; assets 18->16 and 16->14. Still over budget but 14-17kB closer on three routes
- F17-04a blank canvas where a metric has no target is the silent-zero failure this platform exists to prevent, happening inside the platform. It now names the missing target and its owner
- F17-05entry 3 rebound to CO-02, which crosses its target 8 times in 24 so the chart shows both signs; AP-04 kept as entry 03b because no-target is 101 of 140, not an edge case
- F17-06the ASCII pre block became a real state diagram; missed drawn as the terminal that matters because the sentence under it is what makes push safe
- F17-0731 of 31 gallery entries verified to render IN THE SERVED HTML - strategy map 12 svg paths and lineage 7, both previously zero. 740 renders 0 bad; a11y 0
- F16-01rules are DATA with a mandatory basis - a rule that cannot name the requirement it implements does not get written
- F16-0211 rules reproducing all six predicates; scope lifted to lib/access/scope.ts to break the import cycle
- F16-03deny wins at any priority, default deny, and the full trace returned not just the verdict
- F16-04the six canSeeX() are now thin wrappers over evaluate() - this is the real code path, not a picture of one
- F16-05THE CHECK CAUGHT A REAL BUG: a scope-conditioned deny fired on create-campaign because the request names no org unit yet, denying every persona. Fixed; 240 predicate outcomes now identical to the pre-refactor definitions
- F16-06/settings shows the reader what the platform thinks they are, and where that will come from at fullstack
- F16-07trace explorer - persona x action x resource, every rule with why it matched or did not, decisive one marked
- F16-0814 seeded events, 5 of them REFUSALS. A log of successes answers who read this, not who tried
- F16-09SECOND REAL FINDING: deny-wins was implemented and never EXERCISED - no request matched both. Added deny-individual-export (R-S-14, the DPIA is not issued) which overrides allow-export, so the property now does work instead of sitting in the table
- F16-10a11y failed again on ink-faint in the trace marker - fixed, not exempted. 740 renders 0 bad; 286 answers 174 refusals 0 bad; registry 0 errors; 6 perf breaches all pre-existing; 55 pages build
- F15-01one builder, cadence as a parameter; a report is a VIEW not a store - the A-51 argument for boards applies unchanged
- F15-02ISO weeks done properly - Monday start, week belongs to the year containing its Thursday. W39 2026 verified as 21-27 Sep
- F15-03four cadences with the current period marked; the memo pinned above them because it is the one opened daily
- F15-04six sections in the order a reader needs them, and section 6 is COMPUTED - a boilerplate caveat is one nobody reads twice
- F15-05CSV + print-HTML; watermark is part of the document not a footer, so a screenshot of the middle still says who it was built for
- F15-06memo is EVENT-based; the standing cadence line is computed, so it changes on its own if ACF fixes the registry
- F15-07the line reads: 1 of 140 actually report daily, 140 declare daily_t1, so 139 declare a cadence they do not meet
- F15-08export writes an audit event; verified by the Set-Cookie on the CSV response. lib/audit/log.ts built here rather than in F16 because export had to have something to write to
- F15-09@page margin, print-only note explaining why there is no PDF button (A-67)
- F14-01Watch and Campaign are two types not one - a watch is a standing notify level, a campaign is a dated intervention. Merging them is how a dashboard acquires the power to set thresholds
- F14-02boards pattern exactly; the module cannot reach the registry, so R-G-16 is enforced by there being no code path rather than by a check
- F14-03sufficiency gate first, then freshness, then goal-and-guard. Baseline is DERIVED from the window so it cannot be picked after the result is known
- F14-045 seeded campaigns, one per outcome; the builder validates R-G-17 and prints the point counts so the intended outcome is visible in the tool, not only on the screen
- F14-05/monitor says in its first paragraph that a watch level is not a threshold, and flags every row where the watch disagrees with the registry target
- F14-06out-of-scope campaigns listed but locked - two departments should not run the same intervention twice, and that needs the NAME to be visible and nothing else
- F14-07the guard is attached SERVER-SIDE from the registry, not as a form field a client could omit - a rule enforced only in a form is not a rule
- F14-08scope checked BEFORE the metric resolves, as R-S-17 forces on boards
- F14-09route handler not a Server Action (F10-03); JS-free create verified by POST - 303 with the guard auto-attached
- F14-10610 route x persona renders 0 bad; a11y 0; /monitor 190kB /campaigns 189kB - no new perf breach. All four intended outcomes verified on the rendered pages
- F13-019 kinds in one shape; 200 entries for a CEO, 226 for the auditor - the difference is PEOPLE, which is the point
- F13-02scope applied server-side before anything serialises; no-store because the index is per-persona and a shared cache would serve one reader's scope to another
- F13-03full-width field not a 120px button; grouped results; arrows walk ACROSS groups so a group boundary is not a wall
- F13-04/search?q= is a GET form - works with JS off, and a search is a link
- F13-05people EXCLUDED not locked - verified across 10 personas: 0 for a CEO with no employee record, 1 for a frontline agent, 10 for a line manager, 26 for HR and Audit. No locked person in any index
- F13-06MEASURED and the plan's claim was too generous: 2.4kB gz off every route, not the ~11kB the raw payload implied - 140 near-identical JSON rows compress to almost nothing. Index costs 6.9kB gz once. Break-even is 3 page views
- F13-07combobox + aria-activedescendant + role=listbox/option; locked rows are aria-disabled, not removed
- F12-01the ladder is 5 clauses over facts the registry already holds; every band carries the clause that fired and re-running is idempotent (--check exits 1 in CI)
- F12-02R-G-18 in the validator: band/status/basis present, and a guard's band may never be weaker than its KPI's. Negative-tested by demoting AP-09 - caught
- F12-03one tool writes BOTH sides of the A-24 contract - registry yml and the checked-in fixtures - because there is no separate mock builder for metrics
- F12-04PRIORITY column + facet ordered P1-P5 not by count + sort=priority in the URL + a sixth stat card that counts what ACF has AGREED, which is zero
- F12-05band, the clause that fired, share of its perspective and share of total attention at the approved weighting; +1.7kB measured against the page without it
- F12-06priority = perspective weight x band share, share normalised over ALL metrics in the perspective so unspendable weight stays visible (A-63)
- F12-07spendable column + the stranded list, which is the certification queue already in priority order
- F12-08THE FINDING: overlap with approved went 90% -> 100%. Weighting the metrics made it LESS responsive. Same ten metrics at every preset. Recorded, not hidden
- F12-09zero-target defect found while re-measuring: 9 zero-tolerance metrics were silently unscorable (ratio over 0) while the page counted them scorable. Now blocked with a reason; Q-34 asks ACF how zero tolerance scores
- F12-10a11y audit FAILED first run - band carried level in colour alone and used ink-faint outside a disabled control. Fixed with the ramp glyph, not by relaxing the check. 490 renders 0 bad; 286 answers 174 refusals 0 bad; 6 perf breaches, all pre-existing
- F11-01one rank() shared by the server render and the drag preview - they cannot disagree because there is only one definition of leverage
- F11-02hand-built SVG not ECharts; ~40kB saved on a route that ships no chart code AND a real keyboard path a dragged graphic would not have
- F11-03~37 candidates to the client not 140 metrics; URL write debounced so a drag is not a history entry per pixel
- F11-04view is a LINK not client state so the numbers form still works with JS off
- F11-0512 chart readings; TWO were wrong on first run - funnel rate read as a fraction (177%) and a this-year-vs-last-year claim derived from array order not dates. Caught by reading all 12 outputs
- F11-06scope check runs where the data is; the browser gets prose and never the registry
- F11-07first thing it says is what it is - it looks exactly like a chatbot and letting people assume a model would undo the argument the rest of the product makes
- F11-08drag arms the FAB from anywhere on the page; the same grip is a button (A-59) so keyboard and touch are not excluded
- F11-09370 route x persona renders 0 bad; 360 assistant answers 112 refusals 0 bad and no refusal leaked a number; a11y 0; studio+assistant cost 13kB total, no new perf breach
- F11-10the -transparent master has NO alpha and its wordmark measures 1.01:1 on its own matte - invisible as shipped. Matte reconstructed from the green channel, re-keyed white over #B20070 at 6.72:1, 303kB -> 51kB, lazy so nobody who never opens the assistant fetches it
- F10-018 widget kinds all built on components that already shipped; NOT ONE new chart type
- F10-02CleverTap 'All boards' structure; permission is the author's intent and the note says plainly it never widens what a reader sees
- F10-03was a Server Action - Next 15.1.6 runs the no-JS action path outside the request scope so cookies() throws 500; proved with a 5-line probe then replaced with a route handler
- F10-04scope checked BEFORE resolution so an out-of-scope value never enters the RSC stream; locked not hidden
- F10-053 starters as asked; a 4th (data owner feed health) considered and refused - it is the feeds widget plus /integrations
- F10-06GET form + preset links; works with JS off; the simulation is a link with the argument attached
- F10-07priority x gap x movability x evidence; every action derived from registry state - no advice engine in the path
- F10-08the finding: at ANY weighting 90% of the shortlist is identical, because PL contributes 1 of 19 scorable. Panel 0 says so
- F10-09370 route x persona renders 0 bad; a11y 0; /boards/[boardId] 18-22kB over - measured, cause is route-level bundling, dynamic import tried at zero gain
- F9-01centred with the KPI & SCORECARD label
- F9-0225/page over 140; 5 facets counted over the WHOLE registry so a filter never hides its own option; state in the URL so a filtered view is a link
- F9-03CleverTap structure only - AEON aubergine kept; one nav not split with the top bar; details-based groups need no JS
- F9-04PROTOTYPE banner rides with the frozen header deliberately - a banner that scrolls away stops saying so
- F9-05frontline was being shown the company BSC despite being scoped L3/L4
- F9-06bucket bars / loss triangle / dumbbell / histogram / gantt / mix area / queue ageing. Vietnam map dropped on bundle cost - dumbbell answers NS-01 better anyway. Refused: bar race, rose, 3D, polar
- F9-0730 entries 30 canvases; the 8 built since F4 had never been in the gallery - it under-reported by a third
- F9-08189 route x persona renders 0 bad; a11y 0 failures; lucide dropped for inline SVG after the budget caught it in the layout
- F9-09persona chip restyled for the aubergine rail - it had been carrying light-bar styling since the sidebar move; colorScheme dark so the native option list matches; now shows role scope and read-only
- F9-10scrollbars styled for both grounds; thin not hidden so the affordance survives; scrollbar-gutter stable so collapsing a nav group does not shift labels
- F8-01canonical work_item; 210 items across clickup/jira; tool is an attribute
- F8-02all 4 conditions RED; each names the role that can close it
- F8-0310 of 10 scorecards PROVISIONAL at 13-35% coverage - computed, not asserted
- F8-04evidence per line: metric->lineage, commitment->work item, behaviour->signed form
- F8-05roster + per-person state; peer view proves the reporting-line rule
- F8-06E2 built on bar+markLine - no new echarts module; quota is a line per bar not a 2nd series
- F8-07E3 reliability not volume; E4 cycle time TEAM ONLY - individual version is never fair
- F8-08L4B_RATING ships OFF; submission blocked by quota AND gate; nothing auto-demotes
- F8-093 unmatched accounts; lane-2 weight zeroed and renormalised - 0 people scored zero
- F8-10Teams/Slack adapter; approve button refused server-side; Slack is not a measurement source
- F8-11DEMO 8 - build passes; /me 172kB /team 366kB /appraisal 189kB all under budget
- F8-12the join Layer 4 was missing - built bottom-up and never connected to the department; readiness is comparable across depts and delivery deliberately is not
- F7-018 projects incl suspended / 47 row errors / key expiring in 6d / never promoted; 609 windows
- F7-02list + 4 counters; FeedChip lands on metric detail so integration is not an island
- F7-033 live refusals: same owner (R-G-02) / metric already produced (A-39) / cadence too slow
- F7-04one-time screen; project_key fixture HAS no private-key field - the rule is structural
- F7-05refuses a frequency slower than the fastest bound metric AT CREATE TIME
- F7-06reuses CalendarHeat - 0 new echarts modules; missed is grey not red (absence vs refusal)
- F7-074 classes not 1; zero-fill absent from the menu; carry-forward locked when regulatory
- F7-08row errors carry THEIR file rows; 38 of 47 are one structural fault repeated
- F7-09dry run stores nothing; diff catches a re-upload; tier capped at manual
- F7-10endpoints + envelope + error codes + TS/Python SDK; contract frozen for S6
- F7-11DEMO 7 - build passes; 48 static pages; a11y 0 failures; all 9 new routes under 400kB
- F6-01unmeasured axes render as a gap in the web not a zero - People & Learning has 0 scorable
- F6-02bridge reconciles exactly to the Jan-26 PBT of -12.7bn from real budget ratios
- F6-03certification palette not RAG - manual means unverified, not bad
- F6-04blank cells where a perspective has no scorable metric that month
- F6-056 metrics that carry both actual and plan
- F6-063 exceptions incl the orphan CIR; F4 detail retained below the dashboard
- F6-07a11y 0 failures; fixed 2 aria-labels that stated things not on screen; /bsc 412kB - A-33
- F5-0132 chrome keys in EN/VI/JA + /i18n coverage page; 0 of 140 metric names translated - deliberate (A-32)
- F5-02audit_a11y.py 0 failures; found+fixed 3 real contrast defects incl a status label at 3.89:1
- F5-03details-based mobile nav needs no JS; all wide tables in scroll containers
- F5-04perf_budget.py; -27kB on pack pages; /metric ~19kB over - open finding A-33
- F5-0507-evaluation-pack.md - 7-step 25-minute walkthrough
- F5-06scoring sheet T1-T6 P1-P5 C1-C5 G1-G4 + the 7 asks back
- F5-07official AEON wordmark in shell; favicon switches Ae mark under 48px; all regenerable from one master
- F4-0117 metrics 4 perspectives; CIR flagged NO PARENT per 03 s16.2 (Q-12)
- F4-02every edge carries its hypothesis status - 7 of 9 untested, drawn dashed not neutral
- F4-03roll-up arithmetic on the page; score renders PROVISIONAL below 60% coverage
- F4-04cascade tree with weights on the nodes - without them it is an org chart
- F4-05lineage on metric detail; blocked nodes outlined red with their diagram id
- F4-06plausibility check demands an explanation; not-reported is first-class
- F4-07self-approval refused outright not hidden; A-14 fallback checker stated
- F4-08read-only registry admin; R-G-01/02/11 evaluated live against 139 definitions
- F4-09DEMO 5 - build passes; 29 static pages; all F4 routes verified
- F3-01funnel on log scale - a linear 738769 to 174 hides the collapse; inferred stage drawn hollow
- F3-025 cohorts vs the 4% NE-pilot threshold; curve shape modelled between published points (A-28)
- F3-03sankey; published resolved links solid, derived roll-forward links faint+dashed (A-29)
- F3-04two markLines draw the AND rule; only upper-right quadrant actionable
- F3-05cumulative line is the point; (inferred) codes drawn pale (Q-11)
- F3-06boxplot with the published average overplotted - argues the average is the wrong summary
- F3-07built as a bullet not a dial; saves an ECharts module on SD-WAN
- F3-08sequential magenta ramp not RAG - NS-01 has no system of record
- F3-09all 13 packs already rendered; 14th (Credit Card) shown as Phase 4 deferred rather than omitted
- F3-10/charts gallery; 12 chart types + sparkline; build passes; HTML verified
- F2-01solid cap markLine carries its legal basis; warn band shaded
- F2-02/compliance built; breach-run counter reads 12 months in breach
- F2-03both bases shown and labelled; 18.5pt gap computed on screen (A-04 / DEC-11)
- F2-04regulatory routes to owner + Corp Gov + CEO on day one; stale feed raises its own alert
- F2-05ack dialog demands cause/action/owner/date; prototype not persisted
- F2-06basisNote + metric-scoped alerts + period commentary added to detail page
- F2-07build passes; HTML verified; fixed hydration-unsafe dates and a duplicated CG-01B tile
- F1-01one component does target markLine AND KRI markArea bands
- F1-02the one place a chart may use status colour
- F1-03weekends render no_run not failed (T24 C-Bank dependency)
- F1-04/states gallery built for evaluation questions T1-T6
- F1-05persona switcher + simulated scoping verified across 4 personas
- F1-07KRI 376/2024 bands loaded into fixtures
- F1-09Cmd-K over 139 metrics
- F1-10build passes; all features verified via rendered HTML
- F1-11BOOK THIS - week 2 per the plan, not week 6
- F0-03card badge tooltip separator skeleton
- F0-04Jost Inter JetBrains Mono self-hosted at build
- F0-05tree-shaken; register new chart types here
- F0-06MetricResult - the contract (A-24)
- F0-08all 7 elements; RAG filled / tier outlined
- F0-10all 13 packs render, not just IT Ops
- F0-12registry validator + typecheck + build
- F0-13build passes; HTML verified