Skip to content

Commit 61e7b69

Browse files
Staacksclaude
andcommitted
Units: implemented on both apps, the web interface and the editor - planned becomes agreed
spec/units.yml is agreed: the Android, iOS and web-interface tables were compared line by line with the spec (49 units, symbols, scale, offset, system, counterpart) and match; the editor generates its table from the file. The unit-reference rule records the conforming revisions and tests, the three test-matrix rows (unit-reference-parse, unit-conversion-display, unit-conversion-ui) are active with both platforms' tags in place, and the units page and next.md say the implementations exist. With the agreement flipped, _check_units now fails the build on a missing or differently spelled English symbol; it passes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 parent 4e5ac56 commit 61e7b69

6 files changed

Lines changed: 53 additions & 24 deletions

File tree

‎CLAUDE.md‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,4 +417,7 @@ proven against the corpus on every build) is done, and so is phase 4b's app half
417417
both apps run the corpus in their own test suites with T0 CI, kept in step by `test-matrix.yml`
418418
and its checker. What is left of 4b is wiring the corpus into the editor test suite (deferred
419419
until the editor is picked up again), and phase 5, making the Blockly editor consume the spec
420-
instead of encoding the format a fifth time.
420+
instead of encoding the format a fifth time. Phase 5 has its first piece since 2026-09-30: the
421+
editor's unit picker is generated from `spec/units.yml` (`scripts/generate-units.mjs`, with a
422+
test that fails when the committed table drifts from the spec) - the pattern the rest of
423+
phase 5 should follow.

‎docs/file-format/units.md‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
Unit references are part of file format 1.21, which the
55
[next release](../reference/version-history/next.md) carries. A file using them must declare
66
that version, and every app released before it refuses such a file. This page was written
7-
ahead of the implementations (2026-09-30): it is the design the apps, the remote interface and
8-
the editor are built from.
7+
ahead of the implementations (2026-09-30), which followed it the same day on both apps'
8+
development branches, in the remote interface and in the editor; it remains the definition
9+
they are checked against.
910

1011
Several view elements show a unit next to a number: the [value](views/basics.md#view-element-value)
1112
and [edit](views/user-input.md#view-element-edit) elements with their *unit* attribute, and the
@@ -68,8 +69,9 @@ added with 1.21 have no placeholder form, only the reference.
6869

6970
## Known units
7071

71-
The table is generated from `spec/units.yml`, which is the single source for the validators and
72-
for the conversion tables of the apps and the remote interface. Units of one quantity convert
72+
The table is generated from `spec/units.yml`, which is the single source for the validators,
73+
for the editor's unit picker (generated from it at build time) and for the conversion tables of
74+
the apps and the remote interface, which copy it. Units of one quantity convert
7375
into each other through the quantity's base unit; the *conversion* column gives the factor to
7476
that base unit. *System* is metric, imperial or common (neither — a unit the unit-system setting
7577
never touches); *counterpart* is the unit the app switches to when the user forces the other

‎docs/reference/version-history/next.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ interface and in the editor from that specification:
5454
- **`spacing`** on vertical, horizontal and grid inserts a gap between the children, in text
5555
line heights (see [Sizing](../../file-format/views/groups.md#sizing)).
5656

57-
Specified 2026-09-30 ahead of the implementations (Android first, then iOS and the editor):
57+
Specified 2026-09-30 ahead of the implementations and implemented from that specification the
58+
same day on both platforms, in the remote interface and in the editor:
5859

5960
- **Unit references:** the *unit* attributes of value, edit and graph (*unit*, *unitX*, *unitY*,
6061
*unitZ*, *unitYperX*) take `@id` naming one of the [known units](../../file-format/units.md)

‎spec/rules.yml‎

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -420,13 +420,28 @@ rules:
420420
applies_to: "every attribute with type: unit"
421421
state:
422422
android: >-
423-
Not implemented (2026-09-30): PhyphoxFile.translate() resolves the
424-
placeholder to a string after the translation-block lookup and the
425-
elements store strings. Planned; see the Android handoff.
423+
Conforms as of the development branch (326a4c3c, 2026-09-30): the
424+
unit attributes are parsed to a Unit (Units.java holds the table
425+
from spec/units.yml), `@id` at file format 1.21 and the deprecated
426+
placeholder in any version resolve to it, everything else stays
427+
text; the Unit system setting (key unitSystem) and the per-element
428+
dialog convert what the elements display, the remote server emits
429+
the logical unit. Tests: UnitReferenceParseTest,
430+
UnitConversionDisplayTest, GraphUnitConversionTest (Robolectric),
431+
UnitConversionUiTest (instrumented).
426432
ios: >-
427-
Not implemented (2026-09-30): ExperimentTranslationCollection.
428-
localizeString() resolves the placeholder to a string and the view
429-
descriptors store strings. Planned; follows Android.
433+
Conforms as of the development branch (f995e6a8 and 8f290c93,
434+
2026-09-30): Helper/Units.swift holds the table, the view
435+
descriptors carry the logical unit, the Settings-app entry
436+
unitSystem and the dialog convert the display, the web server emits
437+
the logical unit. Tests: UnitReferenceParseTests,
438+
UnitConversionDisplayTests (XCTest), UnitConversionUITests.
439+
editor: >-
440+
The unit attributes offer a preset picker generated from
441+
spec/units.yml (ed3b152, 2026-09-30; scripts/generate-units.mjs
442+
with a --check mode and tests/units.test.ts comparing the committed
443+
table with the spec); `@id` and the placeholder load into the
444+
preset, the editor writes `@id`.
430445
check: >-
431446
Adding a unit means a row in spec/units.yml AND a string
432447
common_unit_short_<id> in both app string tables; the docs build

‎spec/units.yml‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@
1010
# interface), which must carry exactly these numbers.
1111
#
1212
# Decided by the maintainer 2026-09-29/30 (specification ahead of the
13-
# implementations, like the view groups). No app reads unit references yet;
14-
# `agreement: planned` flips to agreed once both apps ship them.
13+
# implementations, like the view groups). Implemented from it on both apps'
14+
# development branches, in the web interface and in the editor by
15+
# 2026-09-30 (Android 326a4c3c, iOS f995e6a8, webinterface c4bf958, editor
16+
# ed3b152); the editor generates its table from this file
17+
# (scripts/generate-units.mjs), the apps and the web interface copy it and
18+
# were compared line by line when the agreement was flipped.
1519
#
1620
# Fields per unit:
1721
# id the reference is `@<id>`; the app's symbol string resource is
@@ -44,7 +48,7 @@
4448

4549
units:
4650
since: "1.21"
47-
agreement: planned
51+
agreement: agreed
4852
systems: [metric, imperial, common]
4953
quantities:
5054
- {name: length, base: meter}

‎test-matrix.yml‎

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,21 +57,22 @@ tests:
5757
area: file-format
5858
tier: T0
5959
platforms: [android, ios]
60-
status: planned
60+
status: active
6161
description: >-
6262
The unit attributes are parsed to logical units (spec/rules.yml,
6363
unit-reference; spec/units.yml): in a 1.21 file `@meter` yields the
6464
known unit meter, shown with the app's symbol; `[[unit_short_meter]]`
6565
yields the same unit in any version; a literal `m`, an `@meter` in a
6666
file declaring 1.20, and an unknown `@metre` in a 1.21 file are custom
67-
text, shown verbatim and not convertible. Specified 2026-09-30 ahead of
68-
the implementations; flip to active once both parsers carry the tag.
67+
text, shown verbatim and not convertible (UnitReferenceParseTest /
68+
UnitReferenceParseTests). Specified 2026-09-30 ahead of the
69+
implementations, active the same day.
6970
7071
- id: unit-conversion-display
7172
area: ui
7273
tier: T0
7374
platforms: [android, ios]
74-
status: planned
75+
status: active
7576
description: >-
7677
What the view elements DISPLAY follows the unit conversion
7778
(docs/file-format/units.md, "Conversion in the app"), checked on the
@@ -86,15 +87,16 @@ tests:
8687
slope unit once an axis is switched, and that text units, a value
8788
with positiveUnit/negativeUnit and an edit with decimal="false" are
8889
untouched. Android: Robolectric against the elements and GraphView
89-
(like GraphTicLabelTest); iOS: XCTest against the view descriptors
90-
and the graph module. Specified 2026-09-30 ahead of the
91-
implementations.
90+
(UnitConversionDisplayTest, GraphUnitConversionTest); iOS: XCTest
91+
against the view descriptors and the graph module
92+
(UnitConversionDisplayTests). Specified 2026-09-30 ahead of the
93+
implementations, active the same day.
9294
9395
- id: unit-conversion-ui
9496
area: ui
9597
tier: T1
9698
platforms: [android, ios]
97-
status: planned
99+
status: active
98100
description: >-
99101
The user-facing path of the unit conversion on the running app
100102
(Espresso / XCUITest, on the emulator or simulator, with
@@ -106,7 +108,9 @@ tests:
106108
change (the buffer value read back through the remote interface or
107109
the export is the original); the Unit system setting converts every
108110
convertible element on the next experiment load and leaves the
109-
exclusions alone. Specified 2026-09-30 ahead of the implementations.
111+
exclusions alone (UnitConversionUiTest / UnitConversionUITests).
112+
Specified 2026-09-30 ahead of the implementations, active the same
113+
day.
110114
111115
- id: corpus-invalid-reject
112116
area: file-format

0 commit comments

Comments
 (0)