Skip to content

fix(ci): mythos-auto plumbing — slug ordering, unzip install#164

Merged
avrabe merged 1 commit into
mainfrom
fix/mythos-auto-plumbing
May 18, 2026
Merged

fix(ci): mythos-auto plumbing — slug ordering, unzip install#164
avrabe merged 1 commit into
mainfrom
fix/mythos-auto-plumbing

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented May 18, 2026

Summary

Three plumbing fixes for mythos-auto.yml, all surfaced by PR #163's first end-to-end run. None of these affect Mythos discover semantics — they all live in the workflow scaffolding around the action.

What broke on PR #163

14:32:12 Error: Unable to locate executable file: unzip. Please verify either the file path exists...
14:32:12 /var/lib/runners/runner5/_work/_temp/.../d9f8a6f8.sh: line 3: bun: command not found
14:32:12 ##[error]Process completed with exit code 127.
14:32:14 ##[error]No files were found with the provided path: mythos-out/.json. No artifacts will be uploaded.

Three discrete bugs cascaded:

# Bug Effect
1 unzip missing on rust-cpu runners oven-sh/setup-bun fails → claude-code-action's bun-based entrypoints exit 127
2 Slug step had no if: always() and ran AFTER discover When discover failed, slug was skipped; steps.slug.outputs.slug empty
3 Empty slug interpolated silently into mythos-out/.json path upload-artifact failed; no per-file result; aggregate ran on missing data

Fixes

Fix What it does
Move slug step BEFORE discover Slug is now always set regardless of discover outcome. No if: always() needed — slug + discover share the same precondition.
New Install unzip (required by setup-bun) step Best-effort apt install, continue-on-error: true. Mirrors the action's own subprocess-isolation install pattern. Non-Debian runners log a warning and proceed.
Read SLUG from env in save-step, fail loudly on empty Pulls slug out of ${{ }} interpolation into env var SLUG. Explicit [ -z "$SLUG" ] check writes a ::error:: log instead of silently producing mythos-out/.json.
Guard upload-artifact with steps.slug.outputs.slug != '' Even if save-step somehow runs with empty slug, upload-artifact won't try to use it as a name.

The placeholder-FINDING fallback that surfaced these issues (writes "discover step failed before emitting structured output" when RESULT_JSON is empty) is intentional and stays — it's what makes the gate block on workflow failures rather than silently passing.

Test plan

  • CI green
  • Mythos auto-runner fires end-to-end on this PR (touches .github/workflows/mythos-auto.yml — not a Tier-5 file, so the auto-runner's detect job will set any=false and the scan job will skip cleanly). To exercise the matrix path end-to-end we need the next Tier-5 PR.
  • Watch for: any new "::error::" logs from the SLUG-empty guard

Sequencing

This is PR #164 in the post-v0.8.1 cycle:

🤖 Generated with Claude Code

PR #163 was the first end-to-end test of mythos-auto.yml (added in
#162). It surfaced three plumbing issues:

1. The action's `oven-sh/setup-bun` step requires `unzip`, which is
   not installed by default on the rust-cpu runners. Without it the
   action's bun-based post-step entrypoints exit 127, and the whole
   scan-step exits failure before emitting structured output.

2. The `Slugify file path for artifact name` step sat AFTER the
   discover step with no `if: always()`. When discover failed, the
   slug step was skipped, leaving `steps.slug.outputs.slug` empty.
   Downstream `if: always()` steps then wrote
   `mythos-out/.json` (no slug) and `upload-artifact` complained
   "No files were found with the provided path: mythos-out/.json".

3. The `Save structured output as artifact` step embedded
   `${{ steps.slug.outputs.slug }}` in the run-block via direct
   interpolation. Silently substituting an empty slug into a file
   path is a footgun even if the slug step had run — better to read
   slug from an env var and fail loudly on empty.

Fixes:

- Slugify step moves BEFORE the discover step, so it always runs
  (no `if: always()` needed because both detect+slug are the
  precondition for everything below).
- New `Install unzip (required by setup-bun)` step, best-effort
  apt install mirroring the action's own subprocess-isolation
  install pattern. `continue-on-error: true` so non-Debian runners
  don't break the workflow.
- `Save structured output as artifact` reads slug from env (`SLUG`)
  rather than `${{ }}` interpolation; explicitly errors out if SLUG
  is empty rather than silently writing to a malformed path.
- `upload-artifact` step gains an extra `steps.slug.outputs.slug
  != ''` guard so it never tries to upload with an empty name.

The placeholder-FINDING fallback (the part that surfaced these
issues by writing "discover step failed before emitting structured
output" into the aggregate comment) is intentional and stays — it
guarantees the gate blocks on workflow failure rather than silently
passing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

LS-N verification gate

⚠️ 16/19 verified — 3 missing regression tests

count
Passed (≥1 test, all green) 16
Failed (≥1 test failure) 0
Missing (no ls_*_NN_* test found) 3

Approved loss-scenarios.yaml entries are expected to have a
regression test named ls_<letter>_<num>_* (e.g. LS-A-11
ls_a_11_*). The gate runs each prefix via cargo test --lib --no-fail-fast and aggregates pass/fail/missing.

Failed LS entries

(none)

Missing regression tests
  • LS-CP-4
  • LS-A-8
  • LS-A-9

Updated automatically by tools/post_verification_comment.py.
Source of truth: safety/stpa/loss-scenarios.yaml.

@avrabe avrabe merged commit 5ae7e8d into main May 18, 2026
14 checks passed
@avrabe avrabe deleted the fix/mythos-auto-plumbing branch May 18, 2026 16:29
avrabe added a commit that referenced this pull request May 19, 2026
The async-callback adapter at lines 3992-3998 of `fact.rs`
dispatches `[waitable-set-poll]` on `WAIT (2)` OR `POLL (3)` via
an `I32Const(WAIT) + I32Eq + LocalGet + I32Const(POLL) + I32Eq +
I32Or` instruction skeleton. A previous version of that branch
matched only `WAIT`, silently treating `POLL` as YIELD which sent
`(EVENT_NONE, 0, 0)` to `[callback]` and dropped any event the
host had ready (LS-A-9). The fix landed without a regression test;
the LS-N verification gate surfaced this gap as the next-to-last
missing entry.

Adds `ls_a_9_callback_adapter_dispatches_both_wait_and_poll`,
which:

1. Builds a minimal `MergedModule` fixture with the prerequisites
   the callback emitter requires:
   - One `() -> i32` lift function
   - The `[callback]<export_name>` companion export
   - A `[waitable-set-poll]` host import
2. Drives `generate_async_callback_adapter` to produce the adapter
3. Scans the emitted function body for the byte sequence
   `0x41 0x02 0x46 0x20` (i32.const WAIT(2) / i32.eq / local.get)
   followed by `0x41 0x03 0x46 0x72` (i32.const POLL(3) / i32.eq /
   i32.or), in order

Pin-by-substring is robust against unrelated body changes (locals
layout, surrounding control flow); a regression that drops the
POLL arm or reorders the comparisons would fail this test.

Gate verdict moves from 17/19 verified to **18/19**; remaining
missing entry is LS-A-8 (inner-list rep_func selection — surveyed
in task #52 at ~2-4h scope).

This is the **first PR to touch a Tier-5 source file** since the
mythos-auto.yml plumbing fixes (#164), so it also serves as the
auto-runner's first true end-to-end matrix-scan smoke test.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
avrabe added a commit that referenced this pull request May 21, 2026
P3 cross-component stream-pair detection foundation + a fully
operational Mythos delta-pass auto-runner. 12 commits since v0.8.1.

Headline changes:

- Cross-component stream<T> pairing detection (#141, ADR-3). The
  StreamPairGraph foundation for the in-module stream adapter: meld
  now inventories at resolve time which fused components form
  producer -> consumer stream pairings. The ring-buffer / copy-chain
  emitter is a runtime-verified follow-up (ADR-3 Path N).

- Mythos delta-pass auto-runner (#162, #164, #170, #173, #175). The
  AI-driven discover protocol now runs automatically on every
  Tier-5 PR by the maintainer, via claude-code-action on a Max-plan
  OAuth token. Five plumbing fixes brought it to a working
  end-to-end state: scan -> NO_FINDINGS verdict -> sticky comment ->
  mythos-pass-done label.

- LS-N verification gate (#161, #165). Every approved loss-scenario
  in safety/stpa/loss-scenarios.yaml is now enforced to have a
  matching ls_<letter>_<num>_* regression test; 19/19 verified.

- DWARF / witness-mapping discovery (#131) — Phase 1 of the #130
  epic; pins today's lossy passthrough as the green-to-red oracle
  for the Phase 2 remap work.

- Regression coverage for LS-A-8/9/19 and LS-CP-4 (#163/165/166/169)
  — closed every missing-test entry the LS-N gate surfaced.

- CI footprint reduction (#171) — bench/fuzz/ci skip on docs- and
  safety-only PRs; meld is a leaner consumer of the shared fleet.

- fuzz.yml musl-target drop (#170, closes #168) — fixes the
  recurring "sanitizer incompatible with statically linked libc"
  fuzz failures.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
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.

1 participant