Skip to content

E01 · F04 · AUD-007 — Audit F04: free rotation of shapes ​

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

Acceptance criteria ​

  • Given the functions of F04, 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 F04 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-007.Tn.

Findings (2026-10-12) ​

Independent review by the auditor subagent (sections A to E, on a copy of the committed tree), mutation spot-checks by the agent (A4). Each story of F04 had its own review before (pull requests #122 to #127).

CheckResultEvidenceAction
A1, A2 — derivations and expected valuescorrectDERIV-turned-shape steps 1–5 and DERIV-arc-bounding-box steps 1–4 re-derived; every value of the feature's tests and test cards recomputed—
A4 — one mutation per function (14)all caughtdegreesInTurn modulo (7 tests), turnDirection sign of sin (4), turnAbout sign (4), arcAxisPoints direction (1), contourBoundingBox arc filter (3), boxToViewBox margin (4), turnedCorners center (11), isShapeAngle bound (5), isShapePlacement y (1), positionKeepingPoint sign (10), positionAfterResize corner (2), freeShapeKeptInPlace local y (4), freeShapeContour move (12), regularPolygonContour position (1)—
A3 — degreesInTurna dead + 0, a false commentthe inner sum lies in (0, 720): never a negative zero (probe over ±1e5)fixed: removed, the TSDoc says why
A3 — positionAfterResize at 0°early return unobservablethe general path gives the same position (100 000 random cases)no action: kept, nothing computed at 0° as for every straight shape
A5 — propertiesmissing for four functions; turned edits only at 90°positionKeepingPoint, arcAxisPoints, boxToViewBox; midpoint, deletion and conversion of a turned shapeadded: properties at any angle
B — sourcesreachable, quotes verbatim9 URLs re-opened on 2026-10-12—
C — provenancewritten from the derivationsno library pattern, no dependency added—
D1 — duplicatesbox center computed three times; 360 declared twiceturnedCorners, positionAfterResize, freeShapeWithPoint; degreesInTurn, isShapeAnglefixed: boxCenter, DEGREES_PER_TURN
E1 — a width emptied, then retypedthe turned shape jumpeda refused draw dropped the turned box keptfixed: only a refused angle drops it; test
E1 — ADR-0034changed by ADR-0035 without saying soa coordinate typed on a turned shape is an integer in the drawing onlyfixed: status lines, index, domain (Q27, Q28, shapes.md)
E1 — TSDoc saying "as drawn" for straight cornerscontradicted turnedCornersfreeShapeCorners, freeShapeAroundCorners, rectangle and polygon corners, midpoint, deletionfixed
E1 — snapping to the integer gridto reconcile with a fractional stored positioninteraction.md §4noted there: the straight box's x and y are snapped
F — quality gatesgreencheck:all, 627 tests, coverage 100 % of src/—

G. Next feature ​

F05 (text), next in E01's order, needs for its spike:

  • SVG 2 text: <text>, x, y, text-anchor (start, middle, end), font-family, font-size in user units, fill; how dominant-baseline places the line (the baseline, not the top).
  • Its straight box: without reading font files (ADR-0002), the box of a text cannot be computed by the core; a browser's getBBox measures it. How the editor shows it, and whether it is needed before E13's layout box.
  • A turned text (F04): transform="rotate(…)" on <text>, the only primitive turned by SVG rather than computed; the angle and position of ADR-0035 for a text.
  • Fonts available offline and the same in every browser (generic families, a font embedded in the library?): a Product Owner question.
  • Integer size, color as for the shapes (E04 strokes and fills not there yet).

H. Light evolvability check ​

QuestionAnswer
Size105 modules in src/ (model 49, geometry 30, math 15, io 6, render 5), 627 tests; the subfolders of model are due (improvement log)
ToolsStrykerJS still blocked; 14 mutations by hand, all caught
Fitness functionsthe playground coverage threshold of CHK-007 still to do
PatternsboxCenter now the one center of a turn: the movable center of E02 changes one place
Agent configurationpitfalls of CHK-007 still true; nothing new
Processthe stories' reviews caught most findings; the audit found the gaps between stories (a width retyped, ADR-0034, "as drawn")