ci(hermes): qualify the fixture Node interpreter

Remove group/world write bits from the dedicated CI job's Node interpreter,
matching the protected paid workflow setup. Preserve the Rust launch verifier
and record the first Linux fixture result and interrupted PR checks.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-08 12:28:11 -05:00
1 parent 6cf6cef34a
commit 3561e1edca
3 files changed
+25

No files matched your search

@@ -46,6 +46,17 @@ jobs:
with:
version: 9.15.4
- name: Qualify the job's provider Node interpreter
run: |
node <<'NODE'
const fs = require('node:fs');
const mode = fs.statSync(process.execPath).mode & 0o777;
fs.chmodSync(process.execPath, mode & ~0o022);
if ((fs.statSync(process.execPath).mode & 0o022) !== 0) {
throw new Error('provider Node interpreter remains group- or world-writable');
}
NODE
- name: Install workspace dependencies
run: |
set -euo pipefail
@@ -403,6 +403,18 @@ excluding private native homes. Its actual execution result must be checked;
the workflow declaration alone is not Linux proof. The protected paid workflow
and its default-branch authorization remain unchanged by this addition.
The first Linux CI attempt provisioned the exact pinned closure and passed the
native ACPX fixture in 94.21 seconds, including native command tools, planning,
images, questions, controls, memory and strict recovery. The Rust fixture failed
before native launch because GitHub's Node interpreter was group-writable.
The workflow now removes only group/world write bits from its own interpreter,
matching the existing paid workflow's setup step. The launch verifier is
unchanged; both native fixtures must pass on a new attempt. The corresponding
ordinary PR run recorded a timeout in the unchanged chat retry denial-feedback
browser test, followed by simultaneous runner shutdowns across other jobs.
Their failures remain recorded and need fresh CI. Repository-wide typecheck
and build pass on startup runtime head `2cf45fa7ff52b08215c726cf10b7d8353e69892a`.
The three draft PRs had green CI and fresh Greptile 5/5 at routines
`3745f3c5a46bda7778ee132682d1b7ae23b088c1`, native
`0dea682031f8e35631faee7a05519ed4dce80d07`, and qualification
@@ -27,6 +27,8 @@ describe("public repository paid workflow security", () => {
expect(fixtures).toContain("PAPERCLIP_HERMES_QUALIFY=1");
expect(fixtures).not.toMatch(/(?:API_KEY|TOKEN|AUTH_JSON|KEEP)/);
expect(workflow.indexOf("Provision the pinned Python closure")).toBeLessThan(workflow.indexOf("Run native fixtures"));
expect(workflow.indexOf("Qualify the job's provider Node interpreter")).toBeLessThan(workflow.indexOf("Run native fixtures"));
expect(workflow).toContain("fs.chmodSync(process.execPath, mode & ~0o022)");
expect(workflow).toContain("no paid model, browser or Daytona proof");
const upload = workflow.slice(workflow.indexOf(" - name: Upload fixture evidence"));
expect(upload).toContain("hermes-native-evidence/");