Skip to content

Roadmap tracking + Zig-FFI doc (#19) + hex/base64 encoding (#25) + Int-division codegen fix (#478) - #474

Merged
hyperpolymath merged 9 commits into
mainfrom
claude/peaceful-gates-bh2ae
May 31, 2026
Merged

Roadmap tracking + Zig-FFI doc (#19) + hex/base64 encoding (#25) + Int-division codegen fix (#478)#474
hyperpolymath merged 9 commits into
mainfrom
claude/peaceful-gates-bh2ae

Conversation

@hyperpolymath

@hyperpolymath hyperpolymath commented May 30, 2026

Copy link
Copy Markdown
Owner

Rebased onto origin/main (was 15 commits behind; clean replay, no conflicts). Built + tested locally with an apt-bootstrapped OCaml toolchain.

1 — Roadmap Tracking-section fixes (docs)

Replaced stale (TBD — opened alongside this PR) placeholders in the three satellite roadmap docs (landed in #410) with the live umbrellas + child issues:

Doc Umbrella Child model Filed
bindings-roadmap.adoc #446 pre-filed per-tier #450#454; kickoff #455
stdlib-roadmap.adoc #412 lazy (stdlib #N) #415
alib-roadmap.adoc #413 lazy (alib #N) #416

2 — Zig C-ABI FFI patterns doc (bindings #19)

docs/specs/zig-ffi-patterns.adoc — authoring recipe, DOC-DEDUP-scoped against SPEC §2.10 / STDLIB-EXTERN-AUDIT / codegen-environment. Row ◐ → ●.

3 — Hex + Base64 encoding (stdlib #25)

stdlib/encoding.affine: hex (to_hex/from_hex/to_hex_padded/hex_digit/hex_value) + RFC 4648 base64 (to_base64/to_base64_url/from_base64/from_base64_url), byte-oriented via two new compiler primitives string_char_code_at/string_from_char_code (resolve/typecheck/interp/codegen_deno). Verified by tests/codegen-deno/encoding_smoke. Row ○ → ◑.

4 — Integer-division codegen fix (#478)

Type-erased Deno-ESM lowered Int / Int to JS float division (255/16 → 15.9375), breaking math.affine's pow/sum_naturals/binomial/lcm/div_floor and for x in xs { x/k } over int arrays. Now a provably-Int a/b lowers to Math.trunc(a/b); everything else stays / (no float regression). Conservative classifier covers literals, Int params, let/assign-tracked locals, integer-closed arithmetic, JS bitwise, Int-returning calls, for-loop variables over Array<Int>, and xs[i] element reads. Regression: tests/codegen-deno/int_div.

Local verification (rebased state)

build-job step result
dune build bin/main.exe
dune runtest
codegen WASM
codegen Deno-ESM (incl. int_div, encoding)
face-transformer
check-no-extension-ts
check-doc-truthing (DOC-01..09)
dune build @fmt (formatting) verifying (ocamlformat 0.26.2 install blocked by proxy on non-github dep hosts; confirming OCaml edits are clean before merge)

Full dune build/@doc additionally need js_of_ocaml+odoc (LSP/doc paths), present in CI.

Refs #446, #412, #413, #478.

https://claude.ai/code/session_01DbDFzJZue7mMnKudvXSK4T

@hyperpolymath hyperpolymath changed the title docs(bindings-roadmap): fill in Tracking section with live issue links May 30, 2026
@hyperpolymath hyperpolymath changed the title docs(roadmaps): fill in Tracking sections with live umbrella + child links May 30, 2026
@hyperpolymath hyperpolymath changed the title docs: roadmap Tracking links + Zig C-ABI FFI patterns doc (bindings #19) May 30, 2026
@hyperpolymath hyperpolymath changed the title Roadmap tracking fixes + Zig-FFI patterns doc (#19) + hex encoding (#25) May 30, 2026
@hyperpolymath
hyperpolymath force-pushed the claude/peaceful-gates-bh2ae branch 2 times, most recently from e850e5c to 3e26b44 Compare May 31, 2026 05:30
@hyperpolymath
hyperpolymath force-pushed the claude/peaceful-gates-bh2ae branch from 3e26b44 to 3ca208a Compare May 31, 2026 06:27

Copy link
Copy Markdown
Owner Author

Formatting gate resolved — clean. Obtained ocamlformat 0.26.2 (the project-pinned version) and checked the OCaml changes two ways:

  1. dune build @fmt (the exact CI Check formatting step) → exit 0. Note: this repo has no root .ocamlformat (only .build/.ocamlformat for the nested build-tooling project), so dune reports "Ocamlformat disabled… no .ocamlformat found" for every .ml and formats only dune-files — i.e. the step can't fail on .ml content (consistent with style(lib/dune): apply ocamlformat to silence persistent build red #466, which fixed a lib/dune nit; this PR touches no dune file).
  2. Belt-and-suspenders: ocamlformat --check --profile=default --margin=100 --break-infix=fit-or-vertical --parse-docstrings directly on lib/codegen_deno.ml, lib/interp.ml, lib/resolve.ml, lib/typecheck.mlall CLEAN.

That was the last build-job step I couldn't verify locally. Full local matrix on the rebased + gitignore tip (823365f): dune build bin/main.exe, dune runtest, codegen-wasm, codegen-deno (incl. int_div + encoding), face-transformer, check-no-extension-ts, check-doc-truthing (DOC-01..09), and formatting — all green. CI runners are currently queued; will merge once the build job confirms green on the runner.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

Correction to my previous comment (re: the second verification method) — same conclusion, but I want the reasoning to be accurate.

My "direct ocamlformat --check → all CLEAN" claim was vacuously true: run from the repo root with no .ocamlformat in scope, ocamlformat self-disables ("Ocamlformat disabled… no [.ocamlformat] found") and exits 0 without checking anything. So that method proved nothing.

The correct proof that formatting is not a merge blocker (verified with ocamlformat 0.26.2, the pinned version):

  1. dune build @fmt self-disables for lib/ — no root .ocamlformat exists (only .build/.ocamlformat, and root dune excludes .build as vendored). It formats dune-files only; .ml content is untouched. Exit 0.
  2. origin/main itself passes dune build @fmt with zero reformat proposals. Since main is green and this branch only adds code in the same hand-authored style, the Check formatting step cannot newly fail on my .ml edits.
  3. Sanity that the intended .build/.ocamlformat config isn't the real gate: an untouched committed file (lib/error.ml) reports "would-reformat" under it too — i.e. the whole lib/ tree predates ocamlformat, so that config is not what CI enforces.

Net: formatting won't gate this PR. Apologies for the earlier imprecise claim — the merge bar remains a green build job on the runner, which I'm waiting on.


Generated by Claude Code

hyperpolymath pushed a commit that referenced this pull request May 31, 2026
…#474)

Records this session's work in all three appropriate forms:
- docs/history/BINDINGS-STDLIB-CODEGEN-2026-05-31.adoc — human narrative
  (trigger, what landed, the #478 bug, process notes, state-after)
- .a2ml companion — machine-readable change inventory per A2ML standard
- .machine_readable/6a2/STATE.a2ml — appended [[session-delta]] mirror
  entry (authoritative status stays in CAPABILITY-MATRIX + roadmap rows;
  no hard-coded live counts, per DOC-05/#176)

Covers: roadmap Tracking de-stale (×3), Zig-FFI doc (bindings #19),
hex+base64 (stdlib #25), byte primitives, and the Int-division codegen
fix (#478). check-doc-truthing (DOC-01..09) green.
claude added 9 commits May 31, 2026 08:01
…s (refs #446)

The Tracking section carried two '(TBD — opened alongside this PR)'
placeholders for the umbrella tracker and per-tier child issues. Those
issues now exist, so the placeholders were stale per the doc's own
'do not let the table drift' rule:

- Umbrella tracker: #446
- Per-tier child issues: #450 (Tier 1) .. #454 (Tier 5)
- Shipped kickoff: #455 (WASM-exports calling pattern, via PR #467)

Completes the canonical-tracking-link portion of the #446 umbrella's
STEP 1 deliverable.
…la links

Both sibling roadmap docs carried the same stale
'(TBD — opened alongside this PR)' placeholders for umbrella tracker
and per-tier/track child issues. Those umbrellas now exist, so the
placeholders were stale per each doc's 'do not let the table drift'
rule:

- stdlib-roadmap.adoc -> umbrella #412; lazy child model (stdlib #N);
  filed so far: #415 (stdlib #5, cross-file use; closed)
- alib-roadmap.adoc   -> umbrella #413; lazy child model (alib #N);
  filed so far: #416 (alib #10, alib.affine module; closed)

Reflects each campaign's actual lazy child-issue model (open issues as
work starts; do not seed all up front), distinct from the newer
bindings campaign (#446) which pre-files per-tier issues.
Adds docs/specs/zig-ffi-patterns.adoc — the canonical, task-oriented
recipe for binding a Zig C-ABI export to an AffineScript extern fn,
the deliverable for bindings #19 in docs/bindings-roadmap.adoc.

Scoped to avoid DOC-DEDUP overlap: SPEC §2.10 owns the grammar,
STDLIB-EXTERN-AUDIT owns the inventory, codegen-environment owns the
wasm codegen mechanics; this doc is the authoring recipe + per-backend
host contract that ties them together.

Grounded in the actual codegen:
- wasm: every extern fn -> (import "env" "<name>") (lib/codegen.ml)
- Deno-ESM: deno_builtins intrinsics emit a self-contained __as_* helper;
  declared externs lower to a same-named host symbol (mangle is identity
  except JS reserved words) (lib/codegen_deno.ml)
Worked example uses the existing hpm-json-rsr binding in stdlib/json.affine.

Bumps the #19 row in bindings-roadmap.adoc from a partial-scaffold status
to usable per the doc's own 'update the row in the same PR' rule.
Unblocks the RSR rewires #11 / #12 / #16.
Adds stdlib/encoding.affine — to_hex / from_hex / to_hex_padded /
hex_digit / hex_value: lowercase, non-negative, 32-bit hexadecimal
conversion built on the string-primitive layer (len / string_sub /
string_find / ++) plus integer bit-ops. Integer / is deliberately
avoided — it lowers to floating-point division on the Deno-ESM backend,
so nibble math uses & and >> instead.

Verified locally with a bootstrapped toolchain: the codegen-deno runner
compiles tests/codegen-deno/encoding_smoke.affine under --deno-esm and
the harness round-trips under Node; full suite green, no regressions.

Base64 (the other half of stdlib #25) is deferred pending a Bytes type
(#30). Bumps the #25 roadmap row to partial.
…verage

Adds RFC 4648 base64 to stdlib/encoding.affine: to_base64 / to_base64_url
/ from_base64 / from_base64_url, byte-oriented via the string_char_code_at
/ string_from_char_code primitives. As in the hex half, group/remainder
math uses bit-ops (no integer / — it lowers to float division on
Deno-ESM, see #478). Verified: tests/codegen-deno/encoding_smoke compiles
under --deno-esm and the harness round-trips the RFC 4648 §10 vectors
under Node; full suite green.
…itives

Adds two byte-oriented String<->Int builtins underpinning the base64
codec in stdlib/encoding.affine (#25). Wired across all four layers,
consistently:
  - resolve.ml      seed_builtins (name resolution)
  - typecheck.ml    register_builtins: String->Int->Int / Int->String
  - interp.ml       runtime impls (out-of-bounds read -> -1; from masks &0xff)
  - codegen_deno.ml __as_strCharCodeAt / __as_strFromCharCode + builtin map

Unlike string_get/int_to_char (Char-typed, ASCII-clamped on the
interpreter), these go String<->Int directly so a byte 0..255 round-trips
identically on the interpreter and Deno-ESM backends. This is the
compiler support the base64 half of the prior commit depends on.

Verified: dune build green; tests/codegen-deno/encoding_smoke round-trips
the RFC 4648 vectors under Node; full codegen-deno suite green.
…478)

JS `/` is floating-point, so the type-erased Deno-ESM backend lowered
integer `a / b` to a non-integer (255 / 16 -> 15.9375). Lower a provably
`Int / Int` to `Math.trunc(a / b)` (truncate toward zero, matching the
interpreter's OCaml `/` and wasm's i32.div_s); every other `/` stays
plain float division, so Float/Float is untouched.

Since codegen_deno is type-erased, a conservative classifier (expr_is_int
/ expr_is_int_array) reports Int only when provable:
  - int literals; Int-typed params; let/assign-tracked Int locals
  - integer-closed arithmetic (+ - * / %); JS bitwise results (int32)
  - calls to Int-returning fns/builtins
  - `for x in xs` loop variable when xs is a provable Array<Int>
  - `xs[i]` element read from a provable Array<Int>
Unknown operands keep `/`, so float division is never silently
truncated. int_vars/int_array_vars are reset per function (enter_fn_scope);
the let-binding and for-loop scopes are restored after their body so a
same-named outer Float is never affected; `x /= y` over ints truncates.

Fixes stdlib/math.affine integer fns (pow, sum_naturals, binomial, lcm,
div_floor) and `for x in xs { ... x / k ... }` over int arrays on the
Deno-ESM backend.

Verified locally (apt toolchain): dune build bin/main.exe clean;
tests/codegen-deno/int_div regression passes (truncation, toward-zero on
negatives, float preserved incl. Array<Float> loops, loop-mutated locals,
Int-returning-call operands, for-loop var + indexed Array<Int>, /=); full
codegen-deno + codegen-wasm suites and dune runtest green. (Full
`dune build`/@fmt need js_of_ocaml+ocamlformat, absent in this sandbox
but present in CI.)

Refs #478.
Claude Code worktree-isolated agents create per-agent git worktrees
under .claude/worktrees/. These are transient scratch checkouts and must
never be committed — committing a nested worktree would corrupt the
repo. Ignoring the path keeps the working tree clean while an agent runs.
…#474)

Records this session's work in all three appropriate forms:
- docs/history/BINDINGS-STDLIB-CODEGEN-2026-05-31.adoc — human narrative
  (trigger, what landed, the #478 bug, process notes, state-after)
- .a2ml companion — machine-readable change inventory per A2ML standard
- .machine_readable/6a2/STATE.a2ml — appended [[session-delta]] mirror
  entry (authoritative status stays in CAPABILITY-MATRIX + roadmap rows;
  no hard-coded live counts, per DOC-05/#176)

Covers: roadmap Tracking de-stale (×3), Zig-FFI doc (bindings #19),
hex+base64 (stdlib #25), byte primitives, and the Int-division codegen
fix (#478). check-doc-truthing (DOC-01..09) green.
@hyperpolymath
hyperpolymath merged commit fb7e855 into main May 31, 2026
15 of 24 checks passed
@hyperpolymath
hyperpolymath deleted the claude/peaceful-gates-bh2ae branch May 31, 2026 07:22
hyperpolymath added a commit that referenced this pull request May 31, 2026
…ngs #1) (#502)

## Summary

Extends the Tier-1 PixiJS binding (#446 row #1) with the 11
most-load-bearing accessors + on/off pointer-event registration. This is
the **largest single chunk** of idaptik's `src/bindings/Pixi.res`
surface still not bound — 215 `src/app/*.res` files depend on Container
transforms and FederatedPointerEvent handlers, so this PR is a forward
unblocker for the ReScript→AffineScript migration.

## What lands

`stdlib/Pixi.affine` (+46 lines): 11 new `extern fn`s.

| Surface | Externs |
|---|---|
| Container transforms | `pixiContainerSetScale`, `SetPivot`,
`SetRotation`, `SetAlpha`, `SetZIndex`, `SetSortableChildren`,
`SetEventMode`, `SetCursor` |
| FederatedPointerEvent registration | `pixiContainerOn`,
`pixiContainerOff` |
| Sprite | `pixiSpriteSetAnchor` |

`lib/codegen_deno.ml` (+22 lines): 11 `__as_*` prelude helpers + 11
entries in the existing `deno_builtins` dispatch block, matching the
existing wasmCall/motion/pixi pattern.

`tests/codegen-deno/pixi_smoke.{affine,harness.mjs}` (+80 lines
combined): new `smokeAccessorsFlow` exercises every new extern via the
existing harness pattern. `MockContainer` grows `scale`/`pivot` Point
mocks + handler `Map` + the new fields; asserts handler identity is
preserved across `on(...)` → `off(...)`.

`docs/bindings-roadmap.adoc` row #1 status note expanded — Container 8.x
transform-and-event surface promoted from "deferred" to "landed";
remaining deferred items (typed `FederatedPointerEvent` accessors,
`parent` read accessor with Option-null handling, Point/Rectangle/Circle
helper types, sprite atlases, filters, hitArea) listed explicitly.

## Design notes

**Why `pub extern fn pixiContainerSetEventMode(c, mode: String)` rather
than a sum type?** Pixi 8's `eventMode` values are open strings
(`"static"` / `"dynamic"` / `"passive"` / `"none"` / `"auto"`). A sum
type would either freeze the set or require codegen-tagged-variant
lowering that doesn't yet exist on the Deno-ESM backend (deferred to
json.affine v0.3, mirroring the `WasmValue` decision in #467). Matches
the existing pattern in `stdlib/PixiUI.affine` for `slider.orientation`.

**Why `handler: Json`?** The `FederatedPointerEvent` reaches the handler
as a JS object; AffineScript-side code uses existing `Json` accessors to
read `e.global.x`, `e.target`, etc. A typed `FederatedPointerEvent`
extern type with dedicated accessor `extern fn`s is the natural
follow-up — captured in the roadmap row as a deferred item, not in this
PR's scope. The Json handler avoids forcing every caller through a typed
surface they may not want.

**Anchor is on Sprite, not Container.** Pixi 8 keeps the same split as
7.x — `Container` has no `anchor`. The binding mirrors that with
`pixiSpriteSetAnchor` rather than putting it on
`pixiContainerSetAnchor`.

## Test plan

- [x] `dune build bin/main.exe` — clean (only the expected parser
warnings)
- [x] `dune runtest` — 354 tests pass
- [x] `tools/run_codegen_deno_tests.sh` — all 17 harnesses including
extended `pixi_smoke.harness.mjs` OK
- [ ] CI build job
- [ ] CI `tools/run_codegen_deno_tests.sh` job
- [ ] CI governance + Hypatia (known baselines per repo CLAUDE.md may be
red — those are not from this PR)

## Refs

- Umbrella: #446 (Tier 1 — idaptik blockers)
- Tier-1 sub-issue: #450
- Row updated: `docs/bindings-roadmap.adoc` row #1
- Prior PixiJS-related PRs for context: #429 (restart on Deno-ESM), #435
(@pixi/ui MVP), #436 (motion ●), #437 (@pixi/sound)
- Compile-time pattern doc: `docs/specs/zig-ffi-patterns.adoc` (PR #474
— non-conflicting siblings)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
hyperpolymath added a commit that referenced this pull request May 31, 2026
) (#506)

## Summary

Ships the first concrete surface for Tier-1 #9 of #446 — **IPC /
structuredClone** for host↔guest message passing. This is the binding
`idaptik-ums` Gossamer IPC for level I/O depends on, and the pattern any
embedded-engine binding in the estate needs.

## What lands

`stdlib/Ipc.affine` (+105 lines, new module): 2 extern types + 9 extern
fns covering MessageChannel construction, port handoff, post +
onmessage, start/close lifecycle, generic `targetPostMessage`, and
`structuredCloneValue`.

| Surface | Externs |
|---|---|
| Channel | `MessageChannel` / `MessagePort` opaque types;
`messageChannelNew` / `messageChannelPort1` / `messageChannelPort2` |
| Port | `messagePortPostMessage` / `messagePortOnMessage` /
`messagePortStart` / `messagePortClose` |
| Cross-context | `targetPostMessage` (Worker / iframe.contentWindow /
self-from-worker) |
| Deep-clone | `structuredCloneValue` |

`lib/codegen_deno.ml` (+23 lines): 9 `__as_*` prelude helpers + 9
dispatch entries adjacent to the pixiSound block. No consumer init —
`MessageChannel` / `MessagePort` / `structuredClone` are standard
web-platform globals.

`tests/codegen-deno/ipc_smoke.{affine,harness.mjs}` (+98 lines
combined): port-pair postMessage round-trip with handler-identity
preservation, standalone close lifecycle, target-post stub, and
structuredClone deep-copy with reference-distinctness assertions across
nested arrays + objects.

`docs/bindings-roadmap.adoc` row #9 promoted `○ → ◑`; deferred items
listed.

## Design notes

**Why is `MessagePort` an opaque `extern type` instead of a
record/tagged-union?** Same reason `WasmExports` and `WasmValue` (#467)
are opaque — the Deno-ESM backend doesn't yet have tagged-variant
codegen (deferred to json.affine v0.3), and a real `MessagePort` carries
internal worker-thread state that isn't usefully observable from
AffineScript anyway. The handler observes the `MessageEvent` as opaque
`Json` and reads `event.data` via the existing Json accessors. A typed
`MessageEvent` extern-type with dedicated accessor externs is the
natural follow-up axis, captured in the roadmap deferred-items list.

**Why is the host responsible for closing the ports?** Inline `close()`
calls in `smokeChannelFlow` would race the microtask-async delivery —
MessagePort drops queued messages on close. The fixture surfaces this as
a documented authoring pattern (it lives in a top-of-file comment) so
anyone writing IPC code with this binding doesn't get bitten.

**Why `setTimeout(50)` in the harness instead of
`setImmediate`/microtask flush?** Empirically verified — Node 20's
`worker_threads`-backed `MessageChannel` batches delivery beyond a
single setImmediate tick. The comment in the harness records the test
that surfaced it (a standalone `node` repl reproducer with the same
shape).

**Why no `transfer` list yet?** Owner directive at #455 (Option-B
kickoff scope) — ship the generic surface, layer typed-and-richer
variants as follow-ups once usage patterns crystallise. Same pattern as
`WasmValue` — opaque tagged scalar first, typed wrappers next.

## Test plan

- [x] `dune build bin/main.exe` — clean (only the expected parser
warnings)
- [x] `dune runtest` — 354 tests pass
- [x] `tools/run_codegen_deno_tests.sh` — all 18 harnesses including the
new `ipc_smoke.harness.mjs` OK
- [ ] CI build job
- [ ] CI `tools/run_codegen_deno_tests.sh` job
- [ ] CI governance + Hypatia (known baselines per repo CLAUDE.md may be
red — not from this PR)

## Refs

- Umbrella: #446 (Tier 1 — idaptik blockers)
- Tier-1 sub-issue: #450
- Row updated: `docs/bindings-roadmap.adoc` row #9
- Pattern siblings: #467 (`wasm_export_call` Option-B), #474 (Zig-FFI
patterns doc), #502 (PixiJS 8.x Container)
- Adjacent: Tier-3 #25 Web Workers — `Worker` constructors would consume
this surface

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@github-actions

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 83 issues detected

Severity Count
🔴 Critical 2
🟠 High 13
🟡 Medium 68

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Action perpolymath/standards/.github/workflows/governance-reusable.yml@main\n needs attention",
    "type": "unpinned_action",
    "file": "governance.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Action ons/checkout@v6\n    needs attention",
    "type": "unpinned_action",
    "file": "publish-jsr.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Action land/setup-deno@v2\n    needs attention",
    "type": "unpinned_action",
    "file": "publish-jsr.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in affine-vscode-publish.yml",
    "type": "missing_timeout_minutes",
    "file": "affine-vscode-publish.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in casket-pages.yml",
    "type": "missing_timeout_minutes",
    "file": "casket-pages.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in casket-pages.yml",
    "type": "missing_timeout_minutes",
    "file": "casket-pages.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in ci.yml",
    "type": "missing_timeout_minutes",
    "file": "ci.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in ci.yml",
    "type": "missing_timeout_minutes",
    "file": "ci.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in ci.yml",
    "type": "missing_timeout_minutes",
    "file": "ci.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in ci.yml",
    "type": "missing_timeout_minutes",
    "file": "ci.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants