Skip to content

Commit 8bb313e

Browse files
Staacksclaude
andcommitted
Phase 2 complete: delete the three conformed entries, pin the ruled behaviors
The iOS development branch now conforms on all three rulings - atan2 element-wise with a fixed-value operand (d2659e86), the static write-once lifecycle with the module skip and clear-data reset (bf735899), and the requireFill first-run exemption (67ed71e8) - and both platforms run the golden-vector suite green, so the entries and their references go per the mechanism. inconsistencies.yml is back to the two permanent entries. The promised conformance vectors land: atan2/value-with-buffer pins the element-wise ruling; corpus/analysis/cases/execution.yml pins the execution model with the generator's new multi-module cases (a modules list per case) and analysis-block attributes - static-write-once proves the skip by the refilled feed buffer surviving cycle 1, and requirefill-first-run-exempt proves cycle 0 runs while the gate is empty and cycle 1 is gated. 117 cases; the runner contract now states requireFill must be honored with its ruled semantics. The analysis-golden-vectors matrix row is active - both platforms carry the tag. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent d691d75 commit 8bb313e

15 files changed

Lines changed: 352 additions & 176 deletions

‎corpus/analysis/README.md‎

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,12 @@ Both app test suites run every pair under `vectors/`. The contract:
3737
current cycle number; snapshot the inputs; clear `keep=false`
3838
non-static input buffers on read; clear non-`append` output buffers
3939
before writing (the `if` module manages its own output clearing); run
40-
the module. The scheduling layer above the kernel — `sleep`,
41-
`dynamicSleep`, `onUserInput`, `requireFill` — must not gate the runs
42-
(no vector uses those attributes).
40+
the module. Of the scheduling layer above the kernel, `sleep`,
41+
`dynamicSleep` and `onUserInput` must not gate the runs (no vector
42+
uses them); `requireFill` MUST be honored with its ruled semantics —
43+
the first run after opening or starting is exempt, later runs are
44+
gated — because the execution/requirefill-first-run-exempt case pins
45+
exactly that.
4346
- **Compare** after the cycle whose 1-based execution count equals an
4447
`expect` entry's `after_cycle`: for each listed buffer the full
4548
contents must match the expected list — same length, NaN equal to NaN,
@@ -51,23 +54,23 @@ Both app test suites run every pair under `vectors/`. The contract:
5154
reference expectation or both apps are wrong, and which one is a docs
5255
decision (the case files record the derivation).
5356

57+
Most cases exercise a single module; `cases/execution.yml` holds the
58+
execution-model cases that need more than one (a per-case `modules:`
59+
list) or an analysis-block attribute (`analysis_attributes:`) — the
60+
static write-once skip and the requireFill first-run exemption, both
61+
ruled 2026-08-24.
62+
5463
## What the vectors deliberately avoid
5564

56-
Constructs whose behavior currently differs between the platforms or is
57-
inherently non-deterministic are left out:
65+
Constructs that are inherently non-deterministic or platform-defined
66+
are left out:
5867

59-
- `atan2` mixing a fixed value with a longer buffer
60-
(`atan2-scalar-input`, decided: element-wise) — buffer-with-buffer
61-
cases only until iOS conforms; then a mixed case is added.
6268
- `timer`'s `offset1970` output — the current timestamp before the first
63-
start (both platforms conform since 2026-08-24), inherently unpinnable
64-
as a golden value; only the experiment-time output is pinned, in the
65-
never-started state.
66-
- `static="true"` buffers (`static-buffer-lifecycle`, decided: written
67-
once, module skipped, reset by user clear) — a skip-pinning
68-
multi-cycle case is added once iOS conforms.
69-
- The block-level `requireFill` gate (`requirefill-first-run`, decided:
70-
the first run is exempt) — a case is added once iOS conforms.
69+
start (ruled 2026-08-24), inherently unpinnable as a golden value;
70+
only the experiment-time output is pinned, in the never-started state.
71+
- The static-buffer reset on the user's clear-data action (ruled with
72+
the write-once lifecycle) — the runner has no user-clear step; the
73+
write-once skip itself is pinned by execution/static-write-once.
7174
- `fft` with non-power-of-two input (`fft-non-power-of-two-input`,
7275
permanent) — power-of-two lengths only. The fft and crosscorrelation
7376
tolerances are widened to cover Android's float32 native path, and

‎corpus/analysis/cases/atan2.yml‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,20 @@ cases:
3535
- {buffer: out}
3636
expect:
3737
out: [45.0, -45.0, 135.0]
38+
- name: value-with-buffer
39+
description: >-
40+
A fixed value with a longer buffer stays element-wise: the value
41+
behaves exactly as a one-element buffer, repeating for every
42+
element (ruled 2026-08-24, formerly the atan2-scalar-input
43+
divergence).
44+
expected_source: reference
45+
buffers:
46+
y: {size: 4, init: [1, 2, 3]}
47+
out: {size: 4}
48+
inputs:
49+
- {as: y, buffer: y}
50+
- {as: x, value: 1}
51+
outputs:
52+
- {buffer: out}
53+
expect:
54+
out: [0.7853981633974483, 1.1071487177940904, 1.2490457723982544]
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Golden vectors: execution-model semantics that need more than one module
2+
# or an analysis-block attribute. Each case carries its own modules list;
3+
# there is no single module this file belongs to.
4+
module:
5+
cases:
6+
- name: static-write-once
7+
description: >-
8+
A module whose output buffers are all static executes once and is
9+
skipped afterwards (ruled 2026-08-24, formerly the
10+
static-buffer-lifecycle divergence). The append module refills
11+
feed every cycle; count reads feed (keep=false) into the static
12+
total. Cycle 0: count runs, consumes feed, writes total. Cycle 1:
13+
count is skipped, so feed KEEPS the freshly appended value - a
14+
platform that still ran the module would clear it.
15+
expected_source: reference
16+
buffers:
17+
src: {size: 4, init: [5]}
18+
feed: {size: 8}
19+
total: {size: 1, static: true}
20+
modules:
21+
- module: append
22+
inputs:
23+
- {buffer: src, keep: true}
24+
outputs:
25+
- {buffer: feed, append: true}
26+
- module: count
27+
inputs:
28+
- {buffer: feed}
29+
outputs:
30+
- {buffer: total}
31+
cycles: 2
32+
expect_per_cycle:
33+
- {feed: [], total: [1]}
34+
- {feed: [5], total: [1]}
35+
- name: requirefill-first-run-exempt
36+
description: >-
37+
The first analysis run is exempt from the requireFill gate (ruled
38+
2026-08-24, formerly the requirefill-first-run divergence): cycle 0
39+
runs although the gate container is empty, so out receives the
40+
appended data; cycle 1 is gated and the block does not run, so out
41+
does not grow.
42+
expected_source: reference
43+
analysis_attributes: {requireFill: gate}
44+
buffers:
45+
gate: {size: 4}
46+
src: {size: 4, init: [1, 2]}
47+
out: {size: 8}
48+
modules:
49+
- module: append
50+
inputs:
51+
- {buffer: src, keep: true}
52+
outputs:
53+
- {buffer: out, append: true}
54+
cycles: 2
55+
expect_per_cycle:
56+
- {out: [1, 2]}
57+
- {out: [1, 2]}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"case": "value-with-buffer",
3+
"cycles": 1,
4+
"default_tolerance": {
5+
"abs": 1e-09,
6+
"rel": 1e-06
7+
},
8+
"expect": [
9+
{
10+
"after_cycle": 1,
11+
"buffers": {
12+
"out": {
13+
"values": [
14+
0.7853981633974483,
15+
1.1071487177940904,
16+
1.2490457723982544
17+
]
18+
}
19+
}
20+
}
21+
],
22+
"expected_source": "reference",
23+
"module": "atan2"
24+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<phyphox xmlns="http://phyphox.org/xml" version="1.0" locale="en">
2+
<title>golden vector: atan2/value-with-buffer</title>
3+
<category>Analysis golden vectors</category>
4+
<description>Generated from corpus/analysis/cases/atan2.yml - do not edit.</description>
5+
<data-containers>
6+
<container size="4" init="1,2,3">y</container>
7+
<container size="4">out</container>
8+
</data-containers>
9+
<analysis>
10+
<atan2>
11+
<input as="y">y</input>
12+
<input as="x" type="value">1</input>
13+
<output>out</output>
14+
</atan2>
15+
</analysis>
16+
<views>
17+
<view label="golden vector">
18+
<separator />
19+
</view>
20+
</views>
21+
</phyphox>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"case": "requirefill-first-run-exempt",
3+
"cycles": 2,
4+
"default_tolerance": {
5+
"abs": 1e-09,
6+
"rel": 1e-06
7+
},
8+
"expect": [
9+
{
10+
"after_cycle": 1,
11+
"buffers": {
12+
"out": {
13+
"values": [
14+
1,
15+
2
16+
]
17+
}
18+
}
19+
},
20+
{
21+
"after_cycle": 2,
22+
"buffers": {
23+
"out": {
24+
"values": [
25+
1,
26+
2
27+
]
28+
}
29+
}
30+
}
31+
],
32+
"expected_source": "reference",
33+
"module": "execution"
34+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<phyphox xmlns="http://phyphox.org/xml" version="1.17" locale="en">
2+
<title>golden vector: execution/requirefill-first-run-exempt</title>
3+
<category>Analysis golden vectors</category>
4+
<description>Generated from corpus/analysis/cases/execution.yml - do not edit.</description>
5+
<data-containers>
6+
<container size="4">gate</container>
7+
<container size="4" init="1,2">src</container>
8+
<container size="8">out</container>
9+
</data-containers>
10+
<analysis requireFill="gate">
11+
<append>
12+
<input keep="true">src</input>
13+
<output append="true">out</output>
14+
</append>
15+
</analysis>
16+
<views>
17+
<view label="golden vector">
18+
<separator />
19+
</view>
20+
</views>
21+
</phyphox>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"case": "static-write-once",
3+
"cycles": 2,
4+
"default_tolerance": {
5+
"abs": 1e-09,
6+
"rel": 1e-06
7+
},
8+
"expect": [
9+
{
10+
"after_cycle": 1,
11+
"buffers": {
12+
"feed": {
13+
"values": []
14+
},
15+
"total": {
16+
"values": [
17+
1
18+
]
19+
}
20+
}
21+
},
22+
{
23+
"after_cycle": 2,
24+
"buffers": {
25+
"feed": {
26+
"values": [
27+
5
28+
]
29+
},
30+
"total": {
31+
"values": [
32+
1
33+
]
34+
}
35+
}
36+
}
37+
],
38+
"expected_source": "reference",
39+
"module": "execution"
40+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<phyphox xmlns="http://phyphox.org/xml" version="1.17" locale="en">
2+
<title>golden vector: execution/static-write-once</title>
3+
<category>Analysis golden vectors</category>
4+
<description>Generated from corpus/analysis/cases/execution.yml - do not edit.</description>
5+
<data-containers>
6+
<container size="4" init="5">src</container>
7+
<container size="8">feed</container>
8+
<container size="1" static="true">total</container>
9+
</data-containers>
10+
<analysis>
11+
<append>
12+
<input keep="true">src</input>
13+
<output append="true">feed</output>
14+
</append>
15+
<count>
16+
<input>feed</input>
17+
<output>total</output>
18+
</count>
19+
</analysis>
20+
<views>
21+
<view label="golden vector">
22+
<separator />
23+
</view>
24+
</views>
25+
</phyphox>

‎docs/file-format/analysis/trigonometric-functions.md‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ Calculates the inverse tangent of a single input element-wise and writes the res
2424

2525
Calculates the two-argument variant of the inverse tangent (corresponding to atan(y/x), see [Wikipedia](https://en.wikipedia.org/wiki/Atan2) for an explanation) element-wise and writes it to a single output buffer. The angle is returned in radians unless degrees are requested using the *deg* attribute. Like the other element-wise modules with several inputs, the output has the length of the longest input and a shorter input repeats its last value; any empty input yields an empty output.
2626

27-
{{inconsistency:atan2-scalar-input}}
28-
2927
{{spec:analysis/analysis/atan2}}
3028

3129
## cos

0 commit comments

Comments
 (0)