Skip to content

Commit 1d6b5c9

Browse files
Update workflow
1 parent cf3734f commit 1d6b5c9

25 files changed

Lines changed: 334 additions & 3857 deletions

.github/workflows/deploy.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ jobs:
4343
run: |
4444
mkdir -p public/generated
4545
python -m multilingualprogramming compile src/automate_universel.ml > public/generated/automate_universel.py
46-
python -m multilingualprogramming build-wasm-bundle src/automate_packed_wasm.ml --out-dir public/generated/automate_packed --wasm-target browser
46+
python -m multilingualprogramming build-wasm-bundle src/automate_packed_wasm.ml --out-dir public/generated/automate_packed
4747
cp public/generated/automate_packed/host_shim.js public/generated/automate_packed/host_shim.mjs
4848
4949
- name: Verifier les artefacts de compilation
@@ -62,6 +62,7 @@ jobs:
6262
6363
- name: Valider le moteur et le WASM
6464
run: |
65+
python tests/stage6_french_core.py
6566
node tests/stage3-smoke.js
6667
node tests/stage4-wasm.mjs
6768
node tests/stage5-static.js

.github/workflows/monitor-multilingual.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ jobs:
7373
run: |
7474
mkdir -p public/generated
7575
python -m multilingualprogramming compile src/automate_universel.ml > public/generated/automate_universel.py
76-
python -m multilingualprogramming build-wasm-bundle src/automate_packed_wasm.ml --out-dir public/generated/automate_packed --wasm-target browser
76+
python -m multilingualprogramming build-wasm-bundle src/automate_packed_wasm.ml --out-dir public/generated/automate_packed
7777
cp public/generated/automate_packed/host_shim.js public/generated/automate_packed/host_shim.mjs
7878
7979
- name: Verifier la syntaxe JavaScript
@@ -85,6 +85,7 @@ jobs:
8585
8686
- name: Valider le moteur et le WASM
8787
run: |
88+
python tests/stage6_french_core.py
8889
node tests/stage3-smoke.js
8990
node tests/stage4-wasm.mjs
9091
node tests/stage5-static.js

.gitignore

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Thumbs.db
1616

1717
# Python/cache helpers
1818
__pycache__/
19+
**/__pycache__/
1920
*.py[cod]
2021
*$py.class
2122
.pytest_cache/
@@ -28,14 +29,15 @@ __pycache__/
2829
/tmp/
2930
/coverage/
3031

32+
# Generated Multilingual/WASM artifacts.
33+
# GitHub Actions regenerates these before publishing Pages.
34+
/public/generated/automate_packed/
35+
/public/generated/automate_universel/
36+
/public/generated/automate_universel.py
37+
3138
# Logs
3239
*.log
3340
npm-debug.log*
3441
yarn-debug.log*
3542
yarn-error.log*
3643
pnpm-debug.log*
37-
38-
# Keep deployable static artifacts for GitHub Pages.
39-
# public/generated contains the Multilingual/WASM browser bundle.
40-
!public/generated/
41-
!public/generated/**

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,21 @@ https://<owner>.github.io/Automaginarium/
5959

6060
See `docs/github-pages.md` for deployment notes.
6161

62+
Useful docs:
63+
64+
- `docs/quickstart.md`
65+
- `docs/create-universe.md`
66+
- `docs/gallery.md`
67+
- `docs/stage4-runtime.md`
68+
- `docs/release-checklist.md`
69+
6270
The repository also includes GitHub Actions workflows:
6371

6472
- `.github/workflows/deploy.yml` compiles the French Multilingual sources, validates the browser/WASM runtime, prepares a static Pages artifact, and deploys on pushes to `main`.
6573
- `.github/workflows/monitor-multilingual.yml` runs scheduled compatibility checks against pinned, latest, and upstream `multilingualprogramming` builds.
6674

75+
Generated Multilingual/WASM outputs under `public/generated/automate_packed/` are intentionally ignored. GitHub Actions regenerates them before publishing Pages.
76+
6777
Stage 3 also adds smoke tests:
6878

6979
```bash
@@ -84,6 +94,12 @@ Stage 5 adds the preset gallery and static deployment checks:
8494
node tests/stage5-static.js
8595
```
8696

97+
Stage 6 strengthens Multilingual ownership by testing the generated Python produced from the French core:
98+
99+
```bash
100+
python tests/stage6_french_core.py
101+
```
102+
87103
## Attribution
88104

89105
Automaginarium is a successor to Cellcosmos and intentionally reuses its project ideas and visual direction. The initial browser metrics and rendering approach are derived from Cellcosmos concepts:

docs/create-universe.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Create A Universe
2+
3+
A universe is a JSON object. The most important fields are:
4+
5+
- `alphabet_entree`: values read from each neighborhood
6+
- `alphabet_sortie`: values produced by the transition rule
7+
- `taille_voisinage`: neighborhood width, usually 3, 5, or 7
8+
- `nombre_canaux_sortie`: how many values each transition returns
9+
- `mode_regle`: `table`, `totalistique`, or `aleatoire`
10+
- `table_transition`: explicit rule table when using `table`
11+
- `etat_initial`: seed pattern
12+
13+
Example:
14+
15+
```json
16+
{
17+
"nom": "Mini univers",
18+
"alphabet_entree": [0, 1],
19+
"alphabet_sortie": [0, 1],
20+
"taille_voisinage": 3,
21+
"nombre_canaux_sortie": 1,
22+
"mode_regle": "table",
23+
"table_transition": {
24+
"[1,1,1]": [0],
25+
"[1,1,0]": [1],
26+
"[1,0,1]": [1],
27+
"[1,0,0]": [0],
28+
"[0,1,1]": [1],
29+
"[0,1,0]": [1],
30+
"[0,0,1]": [1],
31+
"[0,0,0]": [0]
32+
},
33+
"largeur": 101,
34+
"hauteur": 80,
35+
"etat_initial": { "mode": "centre" }
36+
}
37+
```
38+
39+
Rule keys are JSON arrays encoded as strings. This is deliberate: `"[\"a\",\"aa\"]"` is unambiguous, while a concatenated key such as `"aaa"` is not.
40+
41+
## Multi-Channel Output
42+
43+
The first output channel becomes the next state. Later channels can affect rendering. For example:
44+
45+
```json
46+
"[0,1,0]": [1, 3]
47+
```
48+
49+
Here `1` drives evolution and `3` can drive color.
50+
51+
## French Multilingual Ownership
52+
53+
The canonical model lives in `src/automate_universel.ml`. The browser-friendly numeric WASM bridge lives in `src/automate_packed_wasm.ml`. JavaScript should stay focused on JSON loading, UI events, and canvas rendering.

docs/github-pages.md

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,37 @@ Recommended repository settings:
66

77
1. Open repository settings on GitHub.
88
2. Go to **Pages**.
9-
3. Set **Source** to `Deploy from a branch`.
10-
4. Select the main branch and `/ (root)`.
9+
3. Set **Source** to `GitHub Actions`.
1110
5. Save.
1211

13-
The root `index.html` redirects to `public/index.html`, where the application runs. This keeps the repository structure explicit while still making the GitHub Pages root URL usable.
12+
The root `index.html` redirects to `public/index.html`, where the application runs. The workflow builds generated Multilingual/WASM artifacts at deploy time and uploads a complete Pages artifact.
1413

15-
Files that must be committed for Pages:
14+
Source files that must be committed for Pages:
1615

1716
- `public/index.html`
1817
- `public/app.mjs`
1918
- `public/automate-core.js`
2019
- `public/style.css`
21-
- `public/generated/automate_packed/module.wasm`
22-
- `public/generated/automate_packed/*.js`
23-
- `public/generated/automate_packed/*.mjs`
20+
- `public/generated/automate_packed_runtime.mjs`
2421
- `examples/*.json`
22+
- `src/*.ml`
23+
- `.github/workflows/deploy.yml`
24+
25+
Generated files that should not be committed:
26+
27+
- `public/generated/automate_packed/`
28+
- `public/generated/automate_universel.py`
2529

2630
The `.nojekyll` file disables Jekyll processing so GitHub Pages serves static generated assets as-is.
2731

2832
Before publishing, run:
2933

3034
```powershell
3135
.\scripts\build-stage4.ps1
36+
python tests\stage6_french_core.py
3237
node tests\stage3-smoke.js
3338
node tests\stage4-wasm.mjs
39+
node tests\stage5-static.js
3440
```
3541

3642
Then serve locally from the repository root:

docs/quickstart.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Quickstart
2+
3+
Automaginarium runs as a static site.
4+
5+
```powershell
6+
python -m http.server 8788
7+
```
8+
9+
Open:
10+
11+
```text
12+
http://localhost:8788/
13+
```
14+
15+
From there:
16+
17+
1. Pick a preset from the gallery.
18+
2. Change the alphabet, neighborhood size, or initial state.
19+
3. Choose a rule generator.
20+
4. Click **Generer** or **Appliquer**.
21+
5. Export the result as PNG or JSON.
22+
23+
No application server is required. The generated Multilingual/WASM bundle is served from `public/generated/`.
24+
25+
## Rebuild Generated Artifacts
26+
27+
```powershell
28+
.\scripts\build-stage4.ps1
29+
```
30+
31+
Then run:
32+
33+
```powershell
34+
python tests\stage6_french_core.py
35+
node tests\stage3-smoke.js
36+
node tests\stage4-wasm.mjs
37+
node tests\stage5-static.js
38+
```

docs/release-checklist.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Release Checklist
2+
3+
Before publishing a release:
4+
5+
1. Rebuild generated artifacts.
6+
7+
```powershell
8+
.\scripts\build-stage4.ps1
9+
```
10+
11+
2. Run all local tests.
12+
13+
```powershell
14+
python tests\stage6_french_core.py
15+
node tests\stage3-smoke.js
16+
node tests\stage4-wasm.mjs
17+
node tests\stage5-static.js
18+
```
19+
20+
3. Serve the repository root.
21+
22+
```powershell
23+
python -m http.server 8788
24+
```
25+
26+
4. Open `http://localhost:8788/`.
27+
28+
5. Browser-check:
29+
30+
- gallery thumbnails render
31+
- all presets load
32+
- Wolfram/random/symmetric/totalistic generation works
33+
- JSON import/export works
34+
- PNG export works
35+
- browser console has no missing `module.wasm` or preset JSON errors
36+
37+
6. Push to GitHub and verify Actions.
38+
39+
7. Confirm GitHub Pages serves:
40+
41+
- root URL
42+
- `public/generated/automate_packed/module.wasm`
43+
- `examples/*.json`
44+
45+
8. Confirm generated files are not staged:
46+
47+
```powershell
48+
git status --short --ignored
49+
```
50+
51+
`public/generated/automate_packed/` and `public/generated/automate_universel.py` should remain ignored locally.

docs/stage4-runtime.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ public/generated/automate_packed/
2121
public/generated/automate_universel.py
2222
```
2323

24+
These generated files are intentionally ignored by Git and regenerated by GitHub Actions before deployment. The committed runtime loader is:
25+
26+
```text
27+
public/generated/automate_packed_runtime.mjs
28+
```
29+
2430
The browser loads `public/generated/automate_packed_runtime.mjs`, which instantiates `module.wasm` and installs `window.AutomaginariumPacked`. `public/automate-core.js` then calls generated Multilingual/WASM exports for narrow numeric primitives such as Wolfram and totalistic outputs, while retaining JavaScript fallback behavior for rich JSON table orchestration.
2531

2632
Regenerate artifacts with:
@@ -30,3 +36,5 @@ Regenerate artifacts with:
3036
```
3137

3238
Current limitation: the full JSON/dictionary/list-rich core compiles to generated Python but does not yet produce a browser WASM bundle with the current Multilingual WAT backend. The narrow ABI module is the deliberate bridge until richer data lowering is available.
39+
40+
The generated rich core is now exercised by `tests/stage6_french_core.py`, so CI verifies behavior that comes directly from `src/automate_universel.ml`.

public/automate-core.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ function normaliserConfiguration(configuration) {
2525
? configuration.alphabet_sortie
2626
: alphabetEntree;
2727
let tailleVoisinage = Number(configuration.taille_voisinage || 3);
28-
if (tailleVoisinage < 1) tailleVoisinage = 1;
29-
if (tailleVoisinage % 2 === 0) tailleVoisinage += 1;
28+
tailleVoisinage = Math.trunc(callPacked("taille_voisinage_normalisee", [tailleVoisinage], (
29+
tailleVoisinage < 1 ? 1 : (tailleVoisinage % 2 === 0 ? tailleVoisinage + 1 : tailleVoisinage)
30+
)));
3031
return {
3132
nom: configuration.nom || "Univers sans nom",
3233
alphabet_entree: alphabetEntree,
@@ -170,6 +171,26 @@ function callPacked(name, args, fallback) {
170171
return fallback;
171172
}
172173

174+
function codeVoisinageNumerique(voisinage, tailleAlphabet) {
175+
if (!voisinage.every((value) => Number.isInteger(Number(value)))) return null;
176+
const values = voisinage.map(Number);
177+
if (values.length === 3) {
178+
return Math.trunc(callPacked(
179+
"code_voisinage_3_base",
180+
[values[0], values[1], values[2], tailleAlphabet],
181+
values.reduce((code, value) => code * tailleAlphabet + value, 0),
182+
));
183+
}
184+
if (values.length === 5) {
185+
return Math.trunc(callPacked(
186+
"code_voisinage_5_base",
187+
[values[0], values[1], values[2], values[3], values[4], tailleAlphabet],
188+
values.reduce((code, value) => code * tailleAlphabet + value, 0),
189+
));
190+
}
191+
return values.reduce((code, value) => code * tailleAlphabet + value, 0);
192+
}
193+
173194
function toutesClesVoisinage(alphabet, taille) {
174195
const keys = [];
175196
function visit(prefix, depth) {
@@ -223,4 +244,5 @@ window.AutomaginariumCore = {
223244
cleVoisinage,
224245
toutesClesVoisinage,
225246
validerConfiguration,
247+
codeVoisinageNumerique,
226248
};

0 commit comments

Comments
 (0)