diff --git a/.github/workflows/mythos-auto.yml b/.github/workflows/mythos-auto.yml index 423e388..f6c295c 100644 --- a/.github/workflows/mythos-auto.yml +++ b/.github/workflows/mythos-auto.yml @@ -101,6 +101,7 @@ jobs: "meld-core/src/rewriter.rs" "meld-core/src/component_wrap.rs" "meld-core/src/p3_async.rs" + "meld-core/src/p3_stream.rs" "meld-core/src/adapter/" "meld-core/src/resource_graph.rs" "meld-core/src/segments.rs" @@ -317,18 +318,35 @@ jobs: printf '%s' "$body" > /tmp/mythos-body.md echo "verdict=$verdict" >> "$GITHUB_OUTPUT" - # Sticky-comment upsert: find by marker, PATCH if found - # else POST. Marker is the literal HTML comment string. + # Sticky-comment upsert via the GitHub REST API with `curl`. + # `gh` (GitHub CLI) is NOT installed on the `light` runner — + # the prior `gh api` form exited 127. `curl` and `jq` are + # universally present. Marker is the literal HTML comment. + # + # `jq -Rs '{body: .}'` reads the whole markdown file as one + # raw string and JSON-encodes it — newlines, quotes, emoji, + # backticks are all escaped, so nothing in the model-authored + # hypothesis text can break out of the JSON request body. marker='' - existing=$(gh api "repos/${REPO}/issues/${PR_NUMBER}/comments" \ - --paginate --jq ".[] | select(.body | contains(\"${marker}\")) | .id" | head -n1) + api="https://api.github.com" + auth="Authorization: Bearer ${GH_TOKEN}" + accept="Accept: application/vnd.github+json" + jq -Rs '{body: .}' < /tmp/mythos-body.md > /tmp/mythos-body.json + + existing=$(curl -fsS -H "$auth" -H "$accept" \ + "${api}/repos/${REPO}/issues/${PR_NUMBER}/comments?per_page=100" \ + | jq -r --arg m "$marker" \ + 'map(select(.body | contains($m))) | .[0].id // empty') + if [ -n "$existing" ]; then - gh api -X PATCH "repos/${REPO}/issues/comments/${existing}" \ - -f body="@/tmp/mythos-body.md" >/dev/null + curl -fsS -X PATCH -H "$auth" -H "$accept" \ + "${api}/repos/${REPO}/issues/comments/${existing}" \ + -d @/tmp/mythos-body.json >/dev/null echo "updated comment $existing" else - gh api -X POST "repos/${REPO}/issues/${PR_NUMBER}/comments" \ - -f body="@/tmp/mythos-body.md" >/dev/null + curl -fsS -X POST -H "$auth" -H "$accept" \ + "${api}/repos/${REPO}/issues/${PR_NUMBER}/comments" \ + -d @/tmp/mythos-body.json >/dev/null echo "posted new comment" fi @@ -337,8 +355,16 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} PR_NUMBER: ${{ github.event.pull_request.number }} + REPO: ${{ github.repository }} run: | - gh pr edit "$PR_NUMBER" --add-label mythos-pass-done + # `curl` rather than `gh pr edit` — `gh` is absent on the + # light runner. The labels endpoint adds without clobbering + # existing labels. + curl -fsS -X POST \ + -H "Authorization: Bearer ${GH_TOKEN}" \ + -H "Accept: application/vnd.github+json" \ + "https://api.github.com/repos/${REPO}/issues/${PR_NUMBER}/labels" \ + -d '{"labels":["mythos-pass-done"]}' >/dev/null - name: Fail job on FINDING verdict if: steps.compose.outputs.verdict == 'FAIL' diff --git a/.github/workflows/mythos-gate.yml b/.github/workflows/mythos-gate.yml index 385c708..d182b5f 100644 --- a/.github/workflows/mythos-gate.yml +++ b/.github/workflows/mythos-gate.yml @@ -60,6 +60,7 @@ jobs: "meld-core/src/rewriter.rs" "meld-core/src/component_wrap.rs" "meld-core/src/p3_async.rs" + "meld-core/src/p3_stream.rs" "meld-core/src/adapter/" "meld-core/src/resource_graph.rs" "meld-core/src/segments.rs" diff --git a/CHANGELOG.md b/CHANGELOG.md index 3418cec..9e3d217 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,25 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Fixed + +- **mythos-auto aggregate job: `gh` → `curl`** + (`.github/workflows/mythos-auto.yml`). The `aggregate` job composed + the sticky PR comment and applied the `mythos-pass-done` label via + `gh api` / `gh pr edit`, but the GitHub CLI is not installed on the + `light` runner — the step exited 127 (`gh: command not found`), + blocking the label even when the Mythos scan returned NO_FINDINGS. + Rewrites both the comment upsert and the label apply with `curl` + against the REST API (`curl` + `jq` are universally present). The + markdown body is JSON-encoded with `jq -Rs '{body: .}'` so nothing + in the model-authored hypothesis text can break the request. Also + registers `meld-core/src/p3_stream.rs` in the Mythos Tier-5 path + lists (`mythos-gate.yml`, `mythos-auto.yml`) — deferred from #173, + which could not modify `mythos-auto.yml` and still be scanned by + it (claude-code-action self-validates the invoking workflow against + `main`). This PR touches only the workflow files, so its own + auto-runner detect job finds no Tier-5 source and skips the scan. + ### Added - **Cross-component `stream` pairing detection** (issue #141,