Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
bb4e47d
docs(brief): add M0.2.1 milestone brief
guysenpai May 23, 2026
f00d3dd
docs(brief): confirm specs read for M0.2.1
guysenpai May 23, 2026
2cb0408
docs(brief): activate M0.2.1
guysenpai May 23, 2026
11016cd
docs(brief): record E1 diff analysis and hypothesis ranking
guysenpai May 23, 2026
d39472e
docs(brief): journal update E1 precisions
guysenpai May 23, 2026
d6d4cca
test(ecs): add livelock dump helper and 5s watchdog harness
guysenpai May 23, 2026
429bd1b
test(ecs): add steady-state stress variant and test-stress build step
guysenpai May 23, 2026
f6e3e68
docs(brief): record E2 implementation observation and stop criteria
guysenpai May 23, 2026
3e04405
docs(brief): record E2 deviations — repro target 50%, H6 added
guysenpai May 23, 2026
2a7461f
test(stress): add CPU oversubscription to no_alloc_steady_state_stress
guysenpai May 23, 2026
4e0e7e9
test(stress): add process forks to no_alloc_steady_state_stress
guysenpai May 23, 2026
0df6917
test(stress): add fs IO contention to no_alloc_steady_state_stress
guysenpai May 23, 2026
d6616f4
docs(brief): record E2bis measurements and B-E2bis-1 blocker
guysenpai May 23, 2026
1a290e4
test(stress): remove stress test from default test_step
guysenpai May 23, 2026
85ae9e4
docs(brief): close E2bis and revise E7 validation plan
guysenpai May 23, 2026
bbadf88
docs(brief): record E3 static analysis findings and B-E3-1 blocker
guysenpai May 23, 2026
2ce7131
docs(brief): close E3 static and add E2ter runtime assertion
guysenpai May 23, 2026
4ef46d8
perf(jobs): instrument scheduler with E2ter over-decrement assertion
guysenpai May 23, 2026
5cb3fcb
docs(brief): record E2ter outcome and E3 root cause R1 confirmation
guysenpai May 23, 2026
c04cf70
docs(brief): close E3+E4 — R1 confirmed, plan A atomic packing
guysenpai May 23, 2026
60a1526
fix(jobs): pack gen+n atomic to fix wave-lifecycle race
guysenpai May 23, 2026
0dfce78
fix(jobs): add dispatcher pending_count invariant assert
guysenpai May 23, 2026
dc8b680
docs(brief): journal update E5 — fix applied
guysenpai May 23, 2026
6a457de
fix(jobs): comptime guard against false sharing in scheduler
guysenpai May 23, 2026
88fca38
chore(bench): add E6 thermal-aware orchestrator script for S1 and C0.1
guysenpai May 23, 2026
3f6528a
fix(bench): v2 of E6 orchestrator — enforced idle, correct regex
guysenpai May 23, 2026
a1bd379
docs(bench): archive E6 thermal-aware reports for S1 and C0.1
guysenpai May 23, 2026
e80a8c4
docs(brief): journal update E6 — S1 and C0.1 thermal-aware GO
guysenpai May 23, 2026
d6f9aee
docs(bench): annotate C0.1 delta vs M0.1 baseline for investigation
guysenpai May 23, 2026
c1b1875
docs(brief): record E7 results and fill Notes de fin
guysenpai May 24, 2026
353e4ba
docs(brief): close M0.2.1
guysenpai May 24, 2026
e5889ad
docs(claude-md): update for M0.2.1
guysenpai May 24, 2026
3fb6de9
docs: apply CLAUDE.md learnings from M0.2.1 review
guysenpai May 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 68 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,73 @@ If blocked by a point not covered by the brief or its referenced specs: stop, lo

The `briefs/` directory is the source of truth for milestone state. The brief's FROZEN SECTION is editable only via a Claude.ai round-trip (tracked under "Acted deviations").

## Workflow

### Thermal-aware bench MBP M-series

- `caffeinate -i` est obligatoire pour toute boucle de validation longue
(E7 stress, bench multi-run) sur MBP. Sans lui, macOS endort la machine
sur les fenêtres d'idle protocolaires et produit de faux positifs de
hang. À acter dans `engine-phase-0-criteria.md` § Méthodologie bench.

### Milestone hotfix à cause root inconnue

- Format M0.2.1 reproductible : décomposition E1..En avec stop systématique
entre étapes + N décisions interdites en autonomie listées en § Notes du
brief. Les retours Claude.ai fréquents sont du protocole, pas du re-scope.
La règle workflow §2.4 « 2+ blocages = re-scope » vise les défaillances
de cadrage, pas les décisions structurelles prévues par le brief.
- Pattern de validation tiers cumulatifs : Tier 1 synthétique rapide
(faux positif statistiquement faible mais qualitativement incomplet) +
Tier 2 authentique slow (couverture qualitative). Inversion du raisonnement
vs « plus de runs synthétiques = meilleure validation » qui rate les
charges de travail VM/cache non-répliquables synthétiquement.

## Anti-hallucination

### Discipline E1 analyse statique

- En E1 d'un milestone de diagnostic, confirmer chaque symbole nommé dans
le brief par lecture directe du code. Le brief M0.2.1 mentionnait
`helpUntilDone` comme hypothèse — qui n'existait pas dans le code.
Sans cette vérification, le diagnostic se serait déroulé autour d'un
fantôme. À appliquer systématiquement dans les briefs de diagnostic
futurs : les noms de symboles dans la SECTION FIGÉE sont des candidats
à vérifier, pas des affirmations.

## Patterns

### Atomic packing pour racing snapshots

- Quand deux champs `(a: u32, b: u32)` doivent être lus comme un snapshot
cohérent depuis un thread non-writer, packer en un seul
`std.atomic.Value(u64) align(64)` avec helpers `pack`/`unpack` est
préférable à un pattern double-check + retry. Coût perf nul (load 64-bit
aligné = load 32-bit aligné sur Apple Silicon et x86_64), robustesse
préservée face aux refactors (impossible de casser silencieusement).
Réutilisable au-delà du job system — n'importe quel scheduler
(frame state, generation counters, version+epoch) suit ce pattern.

### Comptime layout guards

- Pour les invariants de layout cache-line entre champs `align(64)`
écrits par des threads différents, ajouter un `comptime {
std.debug.assert(@offsetOf(...) ...); }` proche de la déclaration de la
struct. Pin l'invariant à la compilation, résiste aux refactors
silencieux qui réorganisent les champs. Voir M0.2.1 fix scheduler.zig.

## Garde-fous

### Interprétation prudente des baselines bench héritées

- Le commit squash M0.1 listait C0.1 à 14.2 ms ; M0.2.1 mesure 3.74 ms en
thermal-aware ReleaseFast. Ratio 3.8× cohérent avec un écart
ReleaseSafe → ReleaseFast. Avant d'opposer une baseline héritée, vérifier
qu'elle a été mesurée selon le protocole opposable courant
(`engine-phase-0-criteria.md` § Méthodologie bench). Pour les baselines
Phase 0 ancien protocole, la première mesure conforme au protocole
thermal-aware est une candidate plus robuste que la valeur héritée.

---

Last updated: 2026-05-18
Last updated: 2026-05-24
86 changes: 86 additions & 0 deletions bench/reports/ecs_benchmark_C0.1_2026-05-23-thermal-aware.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# ECS bench C0.1 — M0.2.1 / E6 (thermal-aware)

**Date** : 2026-05-23
**Commit** : `3f6528a` (`3f6528ae6b8ec3078fc06edc171b0f921afa3441`)
**Machine** : Apple M4 Pro
**Build mode** : ReleaseFast
**Workers** : default (CPU-topology-driven)
**Protocol** : thermal-aware MBP M-series, cold-isolé conforme.
**Gate** : 16.6 ms (16600000 ns)
**Initial idle** : 1800 s (30 min)
**Inter-run idle** : 900 s (15 min)

## Runs

| Run | Median (ns) | Powermetrics samples | Non-Nominal Pressure |
|---|---|---|---|
| 1 | 3742958 | 68 | 0 |
| 2 | 3779000 | 96 | 0 |
| 3 | 3729667 | 65 | 0 |

## Médiane des médianes

**3742958 ns**

Verdict : **GO** (≤ gate 16600000 ns).

## Conformité thermal-aware

Pressure = Nominal sur **100 %** des samples (68 96 65 samples cumul). **Protocole conforme.**

## Question — delta vs baseline M0.1 14.2 ms (M0.2.1 / E6 review)

Mesure 3.74 ms vs baseline M0.1 14.2 ms documentée dans le squash commit
M0.1 et reproduite dans `engine-phase-0-criteria.md`. Investiguer :

- (a) Le bench C0.1 a-t-il changé de paramètres entre M0.1 et HEAD M0.2.1 ?
**Non** — `git log v0.1.0-M0.1-ecs-full..HEAD -- bench/ecs_benchmark.zig`
retourne vide. Les constantes C0.1 (1M entités sur 4 archetypes 700k/200k/60k/40k,
10 systèmes, warmup 100 + measured 1000) sont identiques.

- (b) Compile mode discrepancy ? **Probable cause.** Le squash commit M0.1
affiche un header `Measures (..., ReleaseSafe, --workers=4 pour S1)` qui
englobe la ligne C0.1 14.2 ms. Or le protocole `engine-phase-0-criteria.md`
§ Méthodologie bench exige **ReleaseFast pour C0.1**. ReleaseSafe ajoute
bounds checks + overflow checks + autres safety runtime — typiquement
2-4× plus lent. Ratio observé : 14.2 / 3.74 ≈ 3.8× — cohérent avec un
écart ReleaseSafe → ReleaseFast.

- (c) La baseline M0.1 14.2 ms reste-t-elle opposable ? **Non, vraisemblablement
pas** — non-protocol-compliant si effectivement mesurée en ReleaseSafe. La
valeur 3.74 ms thermal-aware ReleaseFast est la première mesure protocol-
compliant archivée pour C0.1.

- (d) Nouvelle baseline ? **À acter par milestone Phase 0.1+ dédié.** Pas en
scope M0.2.1. Pour ce milestone, le gate 16.6 ms est respecté (3.74 ms ≤
16.6 ms ✓, headroom ~4.4×). M0.2.1 conclut GO sur le gate, et la question
baseline est tracée comme dette `D-M0.2.1-c01-baseline-investigation`.

## Inspection false sharing (M0.2.1 / E6 note 2)

Le comptime layout guard dans `src/core/jobs/scheduler.zig` (post-E5)
valide à compile time que `gen_and_n` et `pending_count` sont chacun
aligné sur sa propre cache line (offsets multiples de 64, delta ≥ 64).
Build passe ⇒ assertion validée. **Aucun false sharing entre dispatcher
et workers sur ces atomics.**

## Logs archivés

Sous `/tmp/m0_2_1_bench_e6_c01_2026-05-23_11537/` :
- `bench_report_run1.md` — sortie Markdown du bench.
- `bench_stdout_run1.log` — stdout/stderr de l'invocation.
- `powermetrics_run1.log` — trace thermique (11 samples par run).
- `bench_report_run2.md` — sortie Markdown du bench.
- `bench_stdout_run2.log` — stdout/stderr de l'invocation.
- `powermetrics_run2.log` — trace thermique (11 samples par run).
- `bench_report_run3.md` — sortie Markdown du bench.
- `bench_stdout_run3.log` — stdout/stderr de l'invocation.
- `powermetrics_run3.log` — trace thermique (11 samples par run).

## Protocole respecté

- ≥ 1800 s (30 min) idle après pre-build avant run #1 — enforced par sleep.
- ≥ 900 s (15 min) idle entre runs — enforced par sleep.
- 3 runs par session — limite la chaîne thermal cumulée.
- `powermetrics --samplers thermal,cpu_power -i 100` capturé en parallèle de chaque run.
- Vérification programmatique `Current pressure level: Nominal` sur 100 % des samples.
58 changes: 58 additions & 0 deletions bench/reports/ecs_benchmark_S1_2026-05-23-thermal-aware.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# ECS bench S1 — M0.2.1 / E6 (thermal-aware)

**Date** : 2026-05-23
**Commit** : `3f6528a` (`3f6528ae6b8ec3078fc06edc171b0f921afa3441`)
**Machine** : Apple M4 Pro
**Build mode** : ReleaseSafe
**Workers** : --workers=4 (forced — S1 baseline calibration)
**Protocol** : thermal-aware MBP M-series, cold-isolé conforme.
**Gate** : 62 µs (62000 ns)
**Initial idle** : 1800 s (30 min)
**Inter-run idle** : 900 s (15 min)

## Runs

| Run | Median (ns) | Powermetrics samples | Non-Nominal Pressure |
|---|---|---|---|
| 1 | 59500 | 12 | 0 |
| 2 | 61875 | 12 | 0 |
| 3 | 61042 | 12 | 0 |

## Médiane des médianes

**61042 ns**

Verdict : **GO** (≤ gate 62000 ns).

## Conformité thermal-aware

Pressure = Nominal sur **100 %** des samples (12 12 12 samples cumul). **Protocole conforme.**

## Inspection false sharing (M0.2.1 / E6 note 2)

Le comptime layout guard dans `src/core/jobs/scheduler.zig` (post-E5)
valide à compile time que `gen_and_n` et `pending_count` sont chacun
aligné sur sa propre cache line (offsets multiples de 64, delta ≥ 64).
Build passe ⇒ assertion validée. **Aucun false sharing entre dispatcher
et workers sur ces atomics.**

## Logs archivés

Sous `/tmp/m0_2_1_bench_e6_s1_2026-05-23_78889/` :
- `bench_report_run1.md` — sortie Markdown du bench.
- `bench_stdout_run1.log` — stdout/stderr de l'invocation.
- `powermetrics_run1.log` — trace thermique (11 samples par run).
- `bench_report_run2.md` — sortie Markdown du bench.
- `bench_stdout_run2.log` — stdout/stderr de l'invocation.
- `powermetrics_run2.log` — trace thermique (11 samples par run).
- `bench_report_run3.md` — sortie Markdown du bench.
- `bench_stdout_run3.log` — stdout/stderr de l'invocation.
- `powermetrics_run3.log` — trace thermique (11 samples par run).

## Protocole respecté

- ≥ 1800 s (30 min) idle après pre-build avant run #1 — enforced par sleep.
- ≥ 900 s (15 min) idle entre runs — enforced par sleep.
- 3 runs par session — limite la chaîne thermal cumulée.
- `powermetrics --samplers thermal,cpu_power -i 100` capturé en parallèle de chaque run.
- Vérification programmatique `Current pressure level: Nominal` sur 100 % des samples.
Loading
Loading