From 0b25e7bc3970be65aa2f3558d0850d1c5c22c846 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Sun, 18 Oct 2026 13:34:49 +0100 Subject: [PATCH 1/4] Create devcontainer.json move to canonical ijson-jcs format, and creation of devcontainer (generic) Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> --- .devcontainer/devcontainer.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..b1cf3275 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1 @@ +{"build":{"context":"..","dockerfile":"Containerfile"},"containerEnv":{"EDITOR":"code --wait","HOME":"/home/nonroot","LANG":"C.UTF-8"},"containerUser":"nonroot","customizations":{"vscode":{"extensions":["EditorConfig.EditorConfig","eamodio.gitlens","streetsidesoftware.code-spell-checker","timonwong.shellcheck","tamasfe.even-better-toml","skellock.just","redhat.vscode-yaml","DavidAnson.vscode-markdownlint","asciidoctor.asciidoctor-vscode","usernamehw.errorlens"],"settings":{"[makefile]":{"editor.insertSpaces":false},"editor.formatOnSave":true,"editor.insertSpaces":true,"editor.tabSize":2,"files.insertFinalNewline":true,"files.trimFinalNewlines":true,"files.trimTrailingWhitespace":true}}},"name":"{{PROJECT_NAME}} (Codespaces)","postCreateCommand":"just deps","remoteUser":"nonroot","shutdownAction":"stopContainer","updateRemoteUserUID":false} From e73509bfbaff2d3720d7ef209010bcec4666e364 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Sun, 18 Oct 2026 13:02:31 +0000 Subject: [PATCH 2/4] chore(devcontainer): add Wolfi image and root deps recipe --- .devcontainer/Containerfile | 8 ++++++++ Justfile | 4 ++++ 2 files changed, 12 insertions(+) create mode 100644 .devcontainer/Containerfile diff --git a/.devcontainer/Containerfile b/.devcontainer/Containerfile new file mode 100644 index 00000000..9e0a8425 --- /dev/null +++ b/.devcontainer/Containerfile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: MPL-2.0 +FROM cgr.dev/chainguard/wolfi-base:latest + +RUN apk add --no-cache bash ca-certificates coreutils git just + +# Wolfi already provides nonroot with /home/nonroot. +ENV SHELL=/bin/bash +USER nonroot diff --git a/Justfile b/Justfile index 4945938e..91db3aad 100644 --- a/Justfile +++ b/Justfile @@ -10,6 +10,10 @@ default: @just --list +# Dependency setup for the root devcontainer; sub-projects manage their own deps. +deps: + @echo "No root package dependencies to install (specs only)." + # Run the workflow-staleness gate against a repo (default: this one) staleness-check path=".": @bash scripts/check-workflow-staleness.sh "{{path}}" From b0776b8b9bfa79a5baf70218167dc36f86318713 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Sun, 18 Oct 2026 13:04:04 +0000 Subject: [PATCH 3/4] fix(k9): Scope Hypatia allowances to spawnSync imports --- 1-formats/k9/tools/conformance-report.mjs | 4 +++- 1-formats/k9/tools/conformance-report.test.mjs | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/1-formats/k9/tools/conformance-report.mjs b/1-formats/k9/tools/conformance-report.mjs index 7d1cf8dd..3d45d339 100644 --- a/1-formats/k9/tools/conformance-report.mjs +++ b/1-formats/k9/tools/conformance-report.mjs @@ -4,7 +4,6 @@ import fs from 'node:fs'; import path from 'node:path'; import crypto from 'node:crypto'; -import { spawnSync } from 'node:child_process'; import { fileURLToPath } from 'node:url'; export const VERSION = 1; @@ -71,6 +70,9 @@ function walk(dir) { if (!fs.existsSync(dir)) return []; return fs.readdirSync(dir, { withFileTypes: true }).flatMap(e => e.isDirectory() ? walk(path.join(dir, e.name)) : [path.join(dir, e.name)]); } +// Keep this allowance outside Hypatia's file-wide header exemption window. +// hypatia: allow code_safety/js_exec_sync -- spawnSync passes argv arrays without shell evaluation. +import { spawnSync } from 'node:child_process'; function execute(root, command, args, env = {}) { const r = spawnSync(command, args, { cwd: root, env: { ...process.env, ...env }, encoding: 'utf8', timeout: 180000, maxBuffer: 32 * 1024 * 1024 }); return { code: r.error || r.signal ? null : r.status, output: clean((r.stdout ?? '') + (r.stderr ?? '') + (r.error ? `\n${r.error.message}` : '')) }; diff --git a/1-formats/k9/tools/conformance-report.test.mjs b/1-formats/k9/tools/conformance-report.test.mjs index 33188c2d..3c6fab9b 100644 --- a/1-formats/k9/tools/conformance-report.test.mjs +++ b/1-formats/k9/tools/conformance-report.test.mjs @@ -6,7 +6,6 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; -import { spawnSync } from 'node:child_process'; import { counts, state, checkedAssertions, corpusItems, render, delta, baseline } from './conformance-report.mjs'; const row = (status, advisory = false) => ({ id: 'x', status, advisory, reason: '' }); const json = (file, verdict = 'pass', findings = []) => JSON.stringify({ file, verdict, findings }); @@ -65,6 +64,9 @@ test('report escapes untrusted evidence and preserves a small valid baseline', ( assert.equal(baseline(body).sha, 'abc'); assert.equal(baseline(''), null); }); +// Keep this allowance outside Hypatia's file-wide header exemption window. +// hypatia: allow code_safety/js_exec_sync -- spawnSync runs fixed test programs with argv arrays and no shell evaluation. +import { spawnSync } from 'node:child_process'; test('the actual corpus shell gate rejects empty output and unattributed failure', () => { const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'k9-report-')); try { From 05cd7f330d92024a596c12ae66f4dd44182b9846 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Sun, 18 Oct 2026 13:08:00 +0000 Subject: [PATCH 4/4] chore(hypatia): baseline K9 reporter subprocess false positives --- .hypatia-baseline.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.hypatia-baseline.json b/.hypatia-baseline.json index b2ec1638..52c9d779 100644 --- a/.hypatia-baseline.json +++ b/.hypatia-baseline.json @@ -1,4 +1,18 @@ [ + { + "severity": "high", + "rule_module": "code_safety", + "type": "js_exec_sync", + "file": "1-formats/k9/tools/conformance-report.mjs", + "note": "FALSE POSITIVE (CI triage 2026-10-18): Hypatia 51ab6496 matches the node:child_process import itself. The reporter uses spawnSync(command, args) with separate argument arrays and shell disabled by default; no command string is evaluated by a shell. Keep argv-only execution when extending this reporter." + }, + { + "severity": "high", + "rule_module": "code_safety", + "type": "js_exec_sync", + "file": "1-formats/k9/tools/conformance-report.test.mjs", + "note": "FALSE POSITIVE (CI triage 2026-10-18): Hypatia 51ab6496 matches the node:child_process import itself. These tests use spawnSync with separate argument arrays and shell disabled by default to run git and Bash fixture scripts; no shell command interpolation occurs. The subprocesses verify that failed or missing validator evidence cannot pass." + }, { "severity": "high", "rule_module": "code_safety",