Skip to content

fix(ui-ci): adopt AffineScript compile-verify; retire dead ReScript pipeline - #102

Merged
hyperpolymath merged 3 commits into
mainfrom
fix/ui-ci-affinescript
Sep 22, 2026
Merged

hyperpolymath merged 3 commits into
mainfrom
fix/ui-ci-affinescript

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

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

Broken piece Failure
build:res = cd ui && bunx rescript ui/rescript.json already deleted → exit 2 on every run
build:web bundles ui/src/Main.res.js file no longer exists
4/8 ui/tests/*.test.js wrappers import undeproducible *.res.js artefacts
package.json deps zombie rescript + @rescript/* + react(-dom)

Changes

  • ui-ci.yml: ReScript step → estate-canonical AffineScript Verify job (standards split gate, COMPILER_REF SHA-pinned d2875a5): added .affine files 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.
  • package.json: zombie deps + build:res*/build:web/dev scripts removed; build = build:wasm; bun.lock regenerated (verified --frozen-lockfile install locally).
  • Deleted: 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.
  • Recorded: 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 offers affinescript check). No deployment depends on web/dist (casket-pages builds the docs site via its Haskell SSG).
  • actions.lock: registers ocaml/setup-ocaml (SHA pin) used by the verify job — keeps the estate workflow-security linter green.
  • Wikis (Developer/Glossary/Home) + TEST-NEEDS.adoc + stale biome .res.js exclusions 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 Verify job should appear (skipping on this push if no .affine files changed — which is correct behaviour), and wasm core + bun tests should 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.

…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.
@coderabbitai

coderabbitai Bot commented Sep 22, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 33 minutes.

Check out review usage here.

View limit details

Limit 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.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: dd672d35-fc4e-4d0c-b512-2773b601953e

📥 Commits

Reviewing files that changed from the base of the PR and between 4dc2793 and 4ca93cb.

⛔ Files ignored due to path filters (2)
  • .github/workflows/actions.lock is excluded by !**/*.lock
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (15)
  • .github/workflows/ui-ci.yml
  • Justfile
  • TEST-NEEDS.adoc
  • biome.json
  • docs/decisions/ui-web-bundle-deferred-2026-09-22.adoc
  • docs/wikis/Developer.md
  • docs/wikis/Glossary.md
  • docs/wikis/Home.md
  • package.json
  • scripts/build.js
  • scripts/dev.js
  • ui/tests/graphlayout.test.js
  • ui/tests/navigation.test.js
  • ui/tests/update.test.js
  • ui/tests/wasmstore.test.js

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

with:
repository: ${{ env.COMPILER_REPO }}
ref: ${{ env.COMPILER_REF }}
path: .affinescript-compiler
@github-actions

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 70 issues detected

Severity Count
🔴 Critical 6
🟠 High 27
🟡 Medium 37

⚠️ Action Required: Critical security issues found!

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

@github-actions

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 70 issues detected

Severity Count
🔴 Critical 6
🟠 High 27
🟡 Medium 37

⚠️ Action Required: Critical security issues found!

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)
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@hyperpolymath
hyperpolymath merged commit d9e6e17 into main Sep 22, 2026
30 of 33 checks passed
@hyperpolymath
hyperpolymath deleted the fix/ui-ci-affinescript branch September 22, 2026 11:15
@github-actions

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 70 issues detected

Severity Count
🔴 Critical 6
🟠 High 27
🟡 Medium 37

⚠️ Action Required: Critical security issues found!

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

hyperpolymath added a commit that referenced this pull request Sep 22, 2026
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants