Skip to content

E01 · F08 · AUD-005 — Audit F08: node editing ​

Full check of F08 in depth and of the project in breadth, following audit.md (ADR-0020), with the /audit skill.

Acceptance criteria ​

  • Given the functions of F08, when audited, then every formula is re-derived, every expected value recomputed by hand, and each function survives a mutation spot-check.
  • Given the sources, when audited, then every @see of F08 is re-verified online and dated.
  • Given the project, when audited, then no duplicate, no copied code and no inconsistency between code, domain, ADRs and docs remains unrecorded.

Tasks ​

One task = one commit, referenced as AUD-005.Tn.

Findings (2026-10-11) ​

Independent review by the auditor subagent (sections A to E) and mutation spot-checks by the agent (A4).

CheckResultEvidenceAction
A3 — a point typed that leaves no width or heightlost the free shape kept, showed the rectangle's messagehappy-dom probe: converted hexagon, three points deleted, two x typed 0 → no rowsfixed: writeStoredFreeShape keeps only a valid shape; test "keeps the free shape when a point typed would leave it no width"
A3 — a point added on a shape of width 0dropped silently, a radius resetprobe: step 1, width 0, points 1 and 2, add → radius 10 became 0fixed: the button is greyed when width or height is 0; test
A4 — freeShapeWithPoint dropping the moved point's radiussurvived the src testsmutation { ...corner, point } → { point, radius: 0 }fixed: test "[F08.AC5] moves a point with its radius" and a property; now caught (2 tests)
A4 — areFreeShapePoints without the finiteness clausesurvivedmutation: clause removed, 372 tests passfixed: an Infinity point case; now caught
A4 — stretchToSize multiplying inside the divisionsurvived, equivalentw · ((p − o) / n) keeps the exact edges; the harmful order, dividing first, fails 2 tests of F09no action: equivalent at the edges
A4 — eleven other mutations of the featurecaughtunitRegularPolygon sign of 2j (19 tests), areFreeShapePoints y span (2), isValidFreeShape size > 0 (2), freeShapeAroundCorners height (10), freeShapeContour size (17), freeShapeCorners radii order (9), freeShapeRadii zero (13), freeShapeWithPoint index (3), regularPolygonAsFreeShape width (1), rectangleAsFreeShape height (10), and in the stories midpoint, edgeOfSelection, freeShapeWithMidpoint, freeShapeWithoutPoints, deletionOutcome—
A5 — propertiesmissing for three functionsfreeShapeWithPoint, deletionOutcome, freeShapeAroundCornersadded
A1 — DERIV-free-shape-stretch step 2presented the identity at its own size as given by the formulaprobe: o + w·(p − o)/w differs from p by an ulp for 7 coordinates of scaled unit polygonsfixed: the derivation says the code does not compute that axis
B — sourcesall still say what is cited13 references re-fetched by the auditordates set to 2026-10-11
C — provenanceno findingcompositions of 1 to 10 lines written from the derivations—
D — duplicatesradii rebuilt in the playground; two "exactly one selected" readerswrite-stored-free-shape.ts, listen-to-point-fields.ts, show-point-fields.tsfirst fixed (freeShapeRadii); second left for the playground state module (improvement log)
E1 — integer point after a move: whole point (ADR-0031, Q27) or coordinate typed (ADR-0033, US-014)contradictionthe converted hexagon's point 1 typed x 80 keeps y 93.30127Product Owner decision at VAL-005: open question Q28 (a)
E1 — fractional points and sizes after a stretch, a middle point or a deletion, further than ADR-0003 sayscontradictionhexagon with three points deleted: height 43.30127Product Owner decision at VAL-005: Q28 (b); ADR index row of 0003 aligned with its status line
E1 — "all points on one line are refused"wrong for slanted linesprobe: (0, 0), (1, 1), (2, 2) validTSDoc fixed; ADR-0033 left as accepted, Q28 (c)
E1 — stale TSDoc of regularPolygonContour, of isValidFreeShape, of freeShapeWithMidpoint and deletionOutcome limitsstale or silentstart at the topmost vertex; fractions "only as a conversion leaves them"fixed
E2 — open points only in the feature file and interaction.mdnot with the open questionsdeleting joins neighbours; crossing edges; cap of typed coordinatesgathered in Q28
F — quality gatesgreennpm run check:all—

G. Next feature ​

F04, free rotation of shapes (draft): the rotation of a point about a center (a verified source), the bounding box of a rotated contour of segments and arcs, how an integer angle in degrees stays exact for quarter turns, how the box of F07 turns with its content (Product Owner's rule), and how a rotation composes with a free shape's points and its stretch (ADR-0033).

H. Light evolvability check ​

QuestionAnswer
Size91 modules in src/ (model 42); 51 playground modules; about 500 tests; model subfolders stay for the E01 retrospective
ToolsStrykerJS still blocked: 23 mutations by hand in this feature, 2 gaps found that way
Fitness functionsa stored playground value is checked on writing and reading (isValidFreeShape)
Patternsthe playground state module (improvement log) would remove the "exactly one selected" twins and the guards spread over writers
Agent configurationthe auditor found what the story reviews missed at the seams between stories (an edit leaving a flat shape): keep a feature-wide probe in every audit
Processfour Product Owner decisions gathered in one open question (Q28) for the validation, rather than asked one by one during the run