fix(ui-ci): adopt AffineScript compile-verify; retire dead ReScript pipeline - #102
Conversation
…ipeline ui-ci has failed on every run since PR #76 ported the UI ReScript -> AffineScript but left the tooling pointed at the old toolchain: * build:res ran `cd ui && bunx rescript` with ui/rescript.json already deleted (exit 2: "No such file or directory"). * build:web bundled ui/src/Main.res.js, which no longer exists. * 4 of 8 ui/tests/*.test.js wrappers imported *.res.js artefacts that cannot be produced (dead import failures). * package.json carried zombie deps (rescript, @rescript/core/react, react, react-dom). Changes: * ui-ci.yml: replace the ReScript step with the estate-canonical AffineScript Verify job (standards split gate; COMPILER_REF pinned to d2875a5; added .affine files BLOCKING, modified legacy advisory, toolchain failures loudly advisory). Surviving wasm core build + the four live bun suites (agents/contract/exchange/wikilink) + biome lint are unchanged. * package.json: remove zombie deps + build:res* / build:web / dev scripts; build now = build:wasm. bun.lock regenerated. * Delete scripts/build.js, scripts/dev.js and the four dead test wrappers (runtime coverage lives in the wasm-contract suites; type coverage of the ported modules, including *Tests.affine, lives in the verify job). * Record the trade in docs/decisions/ui-web-bundle-deferred-2026-09-22.adoc: UI web bundling is deferred until AffineScript ships a web UI emitter (compiler currently offers `affinescript check` only). Nothing deploys web/dist today (casket-pages builds the docs site independently). * actions.lock: register ocaml/setup-ocaml (SHA-pinned) used by the new verify job. * Wikis (Developer/Glossary/Home) and TEST-NEEDS.adoc updated to the AffineScript reality; stale biome .res.js exclusions removed. ADRs 0001/0002/0004 deliberately untouched - they are historical records of decisions at the time, not current-state claims.
|
Warning Review limit reachedNext included review available in 33 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (15)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| with: | ||
| repository: ${{ env.COMPILER_REPO }} | ||
| ref: ${{ env.COMPILER_REF }} | ||
| path: .affinescript-compiler |
🔍 Hypatia Security ScanFindings: 70 issues detected
View findings[
{
"reason": "Required workflow `scorecard.yml` is absent from .github/workflows/. The estate baseline expects it; without it this repository is unscanned for whatever that workflow covers, and its absence is silent — no job fails, because no job runs.",
"type": "missing_workflow",
"file": "scorecard.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Workflow executes remote script directly (curl/wget piped to shell). Download, verify checksum/signature, then execute.",
"type": "download_then_run",
"file": "ui-ci.yml",
"action": "verify_download_integrity",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Job `trigger-boj` in boj-build.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "boj-build.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "trigger-boj"
},
{
"reason": "Job `build` in casket-pages.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "build"
},
{
"reason": "Job `deploy` in casket-pages.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "deploy"
},
{
"reason": "Job `analyze` in codeql.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "codeql.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "analyze"
},
{
"reason": "Job `a2ml-validate` in dogfood-gate.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "a2ml-validate"
},
{
"reason": "Job `dogfood-summary` in dogfood-gate.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "dogfood-summary"
},
{
"reason": "Job `k9-validate` in dogfood-gate.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "k9-validate"
},
{
"reason": "Job `scan` in hypatia-scan.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "hypatia-scan.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "scan"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
🔍 Hypatia Security ScanFindings: 70 issues detected
View findings[
{
"reason": "Required workflow `scorecard.yml` is absent from .github/workflows/. The estate baseline expects it; without it this repository is unscanned for whatever that workflow covers, and its absence is silent — no job fails, because no job runs.",
"type": "missing_workflow",
"file": "scorecard.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Workflow executes remote script directly (curl/wget piped to shell). Download, verify checksum/signature, then execute.",
"type": "download_then_run",
"file": "ui-ci.yml",
"action": "verify_download_integrity",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Job `trigger-boj` in boj-build.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "boj-build.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "trigger-boj"
},
{
"reason": "Job `build` in casket-pages.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "build"
},
{
"reason": "Job `deploy` in casket-pages.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "deploy"
},
{
"reason": "Job `analyze` in codeql.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "codeql.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "analyze"
},
{
"reason": "Job `a2ml-validate` in dogfood-gate.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "a2ml-validate"
},
{
"reason": "Job `dogfood-summary` in dogfood-gate.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "dogfood-summary"
},
{
"reason": "Job `k9-validate` in dogfood-gate.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "k9-validate"
},
{
"reason": "Job `scan` in hypatia-scan.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "hypatia-scan.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "scan"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
- run: loud-fails with a pointer instead of invoking the removed 'dev' script - build: comment corrected (= wasm core until AffineScript web emit lands) - test: comment corrected (live suites import wasm bindings, not *.res.js)
|
🔍 Hypatia Security ScanFindings: 70 issues detected
View findings[
{
"reason": "Required workflow `scorecard.yml` is absent from .github/workflows/. The estate baseline expects it; without it this repository is unscanned for whatever that workflow covers, and its absence is silent — no job fails, because no job runs.",
"type": "missing_workflow",
"file": "scorecard.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Workflow executes remote script directly (curl/wget piped to shell). Download, verify checksum/signature, then execute.",
"type": "download_then_run",
"file": "ui-ci.yml",
"action": "verify_download_integrity",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Job `trigger-boj` in boj-build.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "boj-build.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "trigger-boj"
},
{
"reason": "Job `build` in casket-pages.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "build"
},
{
"reason": "Job `deploy` in casket-pages.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "deploy"
},
{
"reason": "Job `analyze` in codeql.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "codeql.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "analyze"
},
{
"reason": "Job `a2ml-validate` in dogfood-gate.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "a2ml-validate"
},
{
"reason": "Job `dogfood-summary` in dogfood-gate.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "dogfood-summary"
},
{
"reason": "Job `k9-validate` in dogfood-gate.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "k9-validate"
},
{
"reason": "Job `scan` in hypatia-scan.yml has no `timeout-minutes:` declaration. Default is 6 hours — a stuck codeload fetch or runner hang can burn budget. Add `timeout-minutes: 10` (or proportional).",
"type": "missing_timeout_minutes",
"file": "hypatia-scan.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium",
"recipe_id": "recipe-add-workflow-timeout-minutes",
"job": "scan"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
…ging jobs) (#103) ## Summary Fixes the two remaining job failures, both root-caused during the post-#94 triage: | Job | Failure | Fix | |---|---|---| | Code quality + docs / Check documentation | `Missing required documentation: CONTRIBUTING` — repo had only `.github/CONTRIBUTING.md`; estate convention (rsr-template-repo) is root `CONTRIBUTING.adoc` | new accurate root `CONTRIBUTING.adoc`; `.github/CONTRIBUTING.md` becomes a pointer | | Guix packaging policy | `no packaging found` — the 2026-05-18 Guix-primary ruling requires a genuine artefact (`guix.scm`/`manifest.scm`/`channels.scm`/`.guix-channel` or sealed container) | real `guix.scm` | ## Details - **`guix.scm`**: estate-pattern native dev shell (`rust`, `pkg-config`, `openssl`, `git`) — `guix shell -D -f guix.scm`. Header comments honestly scope it: **Bun** and the **wasm32 target** are added via the pinned installers exactly as CI does (neither is packaged in Guix upstream). Bonus: the old contributing file *claimed* a `guix.scm` existed — now it does. - **`CONTRIBUTING.adoc`**: corrected for the AffineScript port (no ReScript tooling/zombie deps), references the deferred-UI-bundling decision, documents workflow rules (`gh actions-lock`, SPDX headers, SHA pins) and estate language constraints (Bun/Rust/bash/AffineScript only). - **`.github/CONTRIBUTING.md`**: pointer at the root file — one contributing document, not two diverging ones. Independent of #102 (merge either order). Co-authored-by: Arena Agent <agent@arena.ai>




Summary
ui-ci has failed on every run since PR #76 ported the UI ReScript → AffineScript: sources moved to
.affine, but the tooling was left pointing at the old ReScript pipeline. This PR completes the port at the tooling layer, the estate-canonical way.Root causes fixed
build:res=cd ui && bunx rescriptui/rescript.jsonalready deleted → exit 2 on every runbuild:webbundlesui/src/Main.res.jsui/tests/*.test.jswrappers*.res.jsartefactspackage.jsondepsrescript+@rescript/*+react(-dom)Changes
COMPILER_REFSHA-pinnedd2875a5): added.affinefiles gate blocking, modified legacy files advisory until the port backlog clears, toolchain failure = loudly-advisory skip (never a silent green). wasm core build + the four live bun suites (agents/contract/exchange/wikilink) + biome lint unchanged.build:res*/build:web/devscripts removed;build=build:wasm;bun.lockregenerated (verified--frozen-lockfileinstall locally).scripts/build.js,scripts/dev.js, 4 dead test wrappers. Runtime coverage lives in the wasm-contract suites; compile coverage of ported modules (incl.*Tests.affine) lives in the verify job.docs/decisions/ui-web-bundle-deferred-2026-09-22.adoc— UI web bundling deferred until AffineScript ships a web UI emitter (today the compiler only offersaffinescript check). No deployment depends onweb/dist(casket-pages builds the docs site via its Haskell SSG).ocaml/setup-ocaml(SHA pin) used by the verify job — keeps the estate workflow-security linter green.TEST-NEEDS.adoc+ stale biome.res.jsexclusions updated to reality. ADRs 0001/0002/0004 intentionally untouched (historical records).Verification
Local:
bun install --frozen-lockfile✅,biome lint✅, no dangling references to anything removed ✅.CI on this PR is the live proof:
AffineScript Verifyjob should appear (skipping on this push if no.affinefiles changed — which is correct behaviour), andwasm core + bun testsshould pass with the four live suites.Part of the #49 CI-honesty sweep follow-ups — this class ("tooling claims a toolchain that no longer exists") is exactly what the integrity presets are designed to surface.