harness-everything 0.41.3 → 0.42.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +18 -0
- package/benchmarks/results/codex-pr-metadata-2026-10-26/README.md +68 -0
- package/benchmarks/results/codex-pr-metadata-2026-10-26/green-final.log +162 -0
- package/benchmarks/results/codex-pr-metadata-2026-10-26/green.log +158 -0
- package/benchmarks/results/codex-pr-metadata-2026-10-26/live-installed-runtime-rejection.json +31 -0
- package/benchmarks/results/codex-pr-metadata-2026-10-26/luna-action-family-cross-product.js +143 -0
- package/benchmarks/results/codex-pr-metadata-2026-10-26/luna-action-family-cross-product.log +7 -0
- package/benchmarks/results/codex-pr-metadata-2026-10-26/luna-codex-action-gate-prehook-smoke.js +78 -0
- package/benchmarks/results/codex-pr-metadata-2026-10-26/luna-codex-action-gate-prehook-smoke.log +8 -0
- package/benchmarks/results/codex-pr-metadata-2026-10-26/luna-review.md +151 -0
- package/benchmarks/results/codex-pr-metadata-2026-10-26/original-rejection.json +31 -0
- package/benchmarks/results/codex-pr-metadata-2026-10-26/red.log +158 -0
- package/benchmarks/results/codex-pr-metadata-2026-10-26/review-descriptor-green.log +192 -0
- package/benchmarks/results/codex-pr-metadata-2026-10-26/review-descriptor-red.log +192 -0
- package/benchmarks/results/codex-pr-metadata-2026-10-26/review-family-green.log +206 -0
- package/benchmarks/results/codex-pr-metadata-2026-10-26/review-family-red.log +206 -0
- package/benchmarks/results/codex-pr-metadata-2026-10-26/review-hints-green.log +174 -0
- package/benchmarks/results/codex-pr-metadata-2026-10-26/review-hints-red.log +174 -0
- package/benchmarks/results/codex-pr-metadata-2026-10-26/verification.md +31 -0
- package/benchmarks/results/doc-evidence-e1/README.md +68 -0
- package/benchmarks/results/doc-evidence-e1/evidence.json +360 -0
- package/benchmarks/results/doc-evidence-e1/pilot-report.json +175 -0
- package/benchmarks/results/h1-provider-independence-qualification/README.md +95 -0
- package/benchmarks/results/live-host/opencode-d1-d2-2026-10-25/README.md +30 -0
- package/benchmarks/results/live-host/opencode-d1-d2-2026-10-25/evidence.json +128 -0
- package/ci/action-gate.test.js +86 -0
- package/ci/mechanism-2aa-codex-action-gate-policy.test.js +47 -0
- package/ci/mechanism-325-3b-h1-qualification.test.js +206 -0
- package/ci/mechanism-341-opencode-lane.test.js +465 -0
- package/ci/mechanism-task-git-authorization.test.js +12 -0
- package/docs/codex-action-gate.md +27 -1
- package/docs/doc-workflow-reconciliation.md +4 -3
- package/docs/document-lifecycle.md +3 -3
- package/docs/platform-capabilities.md +8 -2
- package/hooks/scripts/action-gate.js +35 -8
- package/hooks/scripts/lib/doc-reconciliation-pilot.js +40 -10
- package/hooks/scripts/lib/doc-reconciliation-provider.js +159 -11
- package/hooks/scripts/workflow-stop-gate.js +4 -1
- package/opencode-plugin/index.mjs +77 -5
- package/opencode-plugin/plugin.json +1 -1
- package/package.json +1 -1
- package/plugins/harness-everything/.codex-plugin/plugin.json +1 -1
- package/plugins/harness-everything/hooks/scripts/action-gate.js +35 -8
- package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-pilot.js +40 -10
- package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-provider.js +159 -11
- package/plugins/harness-everything/hooks/scripts/workflow-stop-gate.js +4 -1
- package/plugins/harness-everything/plugin.json +1 -1
- package/sbom.cdx.json +7 -7
package/benchmarks/results/codex-pr-metadata-2026-10-26/luna-codex-action-gate-prehook-smoke.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const cp = require('child_process');
|
|
6
|
+
const repoRoot = path.resolve(process.argv[2] || process.cwd());
|
|
7
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'luna-hook-boundary-'));
|
|
8
|
+
const hook = path.join(repoRoot, 'hooks/scripts/codex-action-gate-pre.js');
|
|
9
|
+
const env = {
|
|
10
|
+
...process.env,
|
|
11
|
+
HARNESS_ACTION_GATE_HOST: 'codex',
|
|
12
|
+
HARNESS_STATE_HOME: root,
|
|
13
|
+
HARNESS_ACTION_GATE_STDIN_TIMEOUT_MS: '2000',
|
|
14
|
+
};
|
|
15
|
+
const input = { repository_full_name: 'acme/repo', pr_number: 376, body: 'fixture' };
|
|
16
|
+
const cases = [
|
|
17
|
+
['metadata', { tool_input: input }],
|
|
18
|
+
['required', { tool_input: input, workflowPlan: { actionGate: { required: true } } }],
|
|
19
|
+
['descriptor-read-shell', { tool_input: input, action_descriptor: { action: 'read', toolFamily: 'shell' } }],
|
|
20
|
+
['unsafe-state-null-required', { tool_input: { ...input, state: null }, action_descriptor: { action: 'read', toolFamily: 'shell' }, actionGate: { required: true } }],
|
|
21
|
+
['delete-shell', { tool_input: input, action_descriptor: { action: 'delete', toolFamily: 'shell' } }],
|
|
22
|
+
['near-name', { tool_name: 'mcp__demo__update_pull_requests', tool_input: input }],
|
|
23
|
+
['conflicting-harness-required', {
|
|
24
|
+
tool_input: input,
|
|
25
|
+
actionGate: { required: false },
|
|
26
|
+
workflowPlan: { actionGate: { required: false } },
|
|
27
|
+
routerContract: { workflowPlan: { actionGate: { required: false } } },
|
|
28
|
+
harness: { workflowPlan: { actionGate: { required: true } } },
|
|
29
|
+
}],
|
|
30
|
+
];
|
|
31
|
+
function files(dir) {
|
|
32
|
+
return fs.readdirSync(dir, { withFileTypes: true }).flatMap(entry =>
|
|
33
|
+
entry.isDirectory() ? files(path.join(dir, entry.name)) : [path.join(dir, entry.name)]);
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
console.log(`Node ${process.version}; repo ${repoRoot}`);
|
|
37
|
+
for (let i = 0; i < cases.length; i++) {
|
|
38
|
+
const [label, extra] = cases[i];
|
|
39
|
+
const toolUseId = `hook-${i}`;
|
|
40
|
+
const payload = {
|
|
41
|
+
hook_event_name: 'PreToolUse',
|
|
42
|
+
session_id: `hook-review-${i}`,
|
|
43
|
+
turn_id: 'hook-review',
|
|
44
|
+
tool_use_id: toolUseId,
|
|
45
|
+
tool_name: 'mcp__codex_apps__github__update_pull_request',
|
|
46
|
+
...extra,
|
|
47
|
+
};
|
|
48
|
+
const result = cp.spawnSync(process.execPath, [hook], {
|
|
49
|
+
cwd: root,
|
|
50
|
+
env,
|
|
51
|
+
input: JSON.stringify(payload),
|
|
52
|
+
encoding: 'utf8',
|
|
53
|
+
timeout: 20000,
|
|
54
|
+
});
|
|
55
|
+
const audit = files(root).filter(file => file.endsWith('.json')).map(file => {
|
|
56
|
+
try { return JSON.parse(fs.readFileSync(file, 'utf8')); } catch { return null; }
|
|
57
|
+
}).find(record => record?.toolUseId === toolUseId);
|
|
58
|
+
const summary = {
|
|
59
|
+
label,
|
|
60
|
+
exitCode: result.status,
|
|
61
|
+
stdout: result.stdout.trim(),
|
|
62
|
+
matchedRule: audit?.matchedRule || null,
|
|
63
|
+
disposition: audit?.disposition || null,
|
|
64
|
+
action: audit?.actionDescriptor?.action || null,
|
|
65
|
+
family: audit?.actionDescriptor?.toolFamily || null,
|
|
66
|
+
classification: audit?.actionDescriptor?.classification || null,
|
|
67
|
+
required: audit?.routerActionGate?.required ?? null,
|
|
68
|
+
};
|
|
69
|
+
console.log(JSON.stringify(summary));
|
|
70
|
+
if (result.error || result.status === null) throw result.error || new Error(`${label}: no process status`);
|
|
71
|
+
const expectedAllow = label === 'metadata' || label === 'descriptor-read-shell';
|
|
72
|
+
if (expectedAllow ? result.status !== 0 : result.status !== 2) throw new Error(`${label}: unexpected exit ${result.status}`);
|
|
73
|
+
if (expectedAllow && (audit?.actionDescriptor?.action !== 'mutate' || audit?.actionDescriptor?.toolFamily !== 'mcp')) throw new Error(`${label}: expected audited MCP mutation`);
|
|
74
|
+
if (!expectedAllow && result.status === 2 && !audit) throw new Error(`${label}: missing block audit`);
|
|
75
|
+
}
|
|
76
|
+
} finally {
|
|
77
|
+
fs.rmSync(root, { recursive: true, force: true });
|
|
78
|
+
}
|
package/benchmarks/results/codex-pr-metadata-2026-10-26/luna-codex-action-gate-prehook-smoke.log
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Node v24.22.1; repo /Users/daniel.chang/Desktop/Skills/Harness-codex-pr-metadata
|
|
2
|
+
{"label":"metadata","exitCode":0,"stdout":"","matchedRule":"routine-pr-metadata-update","disposition":"deferred-to-host","action":"mutate","family":"mcp","classification":"gated","required":null}
|
|
3
|
+
{"label":"required","exitCode":2,"stdout":"","matchedRule":"structured-mutate","disposition":"rejected","action":"mutate","family":"mcp","classification":"gated","required":true}
|
|
4
|
+
{"label":"descriptor-read-shell","exitCode":0,"stdout":"","matchedRule":"routine-pr-metadata-update","disposition":"deferred-to-host","action":"mutate","family":"mcp","classification":"gated","required":null}
|
|
5
|
+
{"label":"unsafe-state-null-required","exitCode":2,"stdout":"","matchedRule":"structured-mutate","disposition":"rejected","action":"mutate","family":"mcp","classification":"gated","required":true}
|
|
6
|
+
{"label":"delete-shell","exitCode":2,"stdout":"","matchedRule":"structured-delete","disposition":"rejected","action":"delete","family":"mcp","classification":"gated","required":null}
|
|
7
|
+
{"label":"near-name","exitCode":2,"stdout":"","matchedRule":"structured-mutate","disposition":"rejected","action":"mutate","family":"mcp","classification":"gated","required":null}
|
|
8
|
+
{"label":"conflicting-harness-required","exitCode":2,"stdout":"","matchedRule":"structured-mutate","disposition":"rejected","action":"mutate","family":"mcp","classification":"gated","required":true}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Independent cold review: Codex PR metadata action gate
|
|
2
|
+
|
|
3
|
+
## Scope and evidence
|
|
4
|
+
|
|
5
|
+
- Repository: `/Users/daniel.chang/Desktop/Skills/Harness-codex-pr-metadata`
|
|
6
|
+
- Base: `b733cadec17542b9ae30aabb50c1ba3481a58d74`
|
|
7
|
+
- Final core SHA reviewed: `c170a96cf856295200d2d1a62c15a552c3cb2b37`
|
|
8
|
+
- Current repository HEAD: `a2edf4ed2204a414dd085635d2d9bf4464c59e9e` (evidence-only commit after the core review); current worktree has two additional evidence-only paths described below.
|
|
9
|
+
- The code path was cold-reviewed at `e160e00`, then re-reviewed through fixes `ff796c9`, `e9344de`, and `c170a96`. Final core behavior was independently exercised at `c170a96`.
|
|
10
|
+
- Requested model/effort: coordinator reports that the agent was routed with `model=gpt-6-luna`, `reasoning_effort=xhigh`. This agent has no host-issued runtime attestation, so actual model/effort identity remains unverified.
|
|
11
|
+
- Read independently: repository `AGENTS.md`, `docs/codex-action-gate.md`, code-review skill/playbook, issue [#110](https://github.com/dyphn1/Harness-everything/issues/110), issue [#122](https://github.com/dyphn1/Harness-everything/issues/122), issue [#135](https://github.com/dyphn1/Harness-everything/issues/135), complete base-to-HEAD diff, original worktree diff, and retained evidence logs/artifacts.
|
|
12
|
+
- Scope clauses, verbatim from the review task:
|
|
13
|
+
- C1 僅 Codex 精確 update_pull_request title/body metadata-only 例外,必須實查參數;
|
|
14
|
+
- C2 state/base_branch/maintainer_can_modify/unknown/mixed risk 不得豁免(包含 null);
|
|
15
|
+
- C3 actionGate.required=true 必須 gate;
|
|
16
|
+
- C4 保持 mutate/gated,無 Codex permissionDecision ask/allow、Host/task scope/GitHub authorization 仍生效;
|
|
17
|
+
- C5 create_pull_request 與 merge/close/delete/force-push/publish/deploy/send 既有行為不變;
|
|
18
|
+
- C6 不擴其他 Host、canonical/plugin parity,hash/redacted audit provenance/executed success+failure/rejected/integrity 行為保持;
|
|
19
|
+
- C7 RED→GREEN→regression 必須自行執行證明,live-host 不可從 unit/mechanism 宣稱 PASS;
|
|
20
|
+
- C8 無 #376 governance 實作、#341 E1/#320 授權擴張、禁自動 merge/繞 gate。
|
|
21
|
+
|
|
22
|
+
### Paths reviewed in `base..a2edf4e`
|
|
23
|
+
|
|
24
|
+
- `CHANGELOG.md`
|
|
25
|
+
- `benchmarks/results/codex-pr-metadata-2026-10-26/README.md`
|
|
26
|
+
- `benchmarks/results/codex-pr-metadata-2026-10-26/green-final.log`
|
|
27
|
+
- `benchmarks/results/codex-pr-metadata-2026-10-26/green.log`
|
|
28
|
+
- `benchmarks/results/codex-pr-metadata-2026-10-26/original-rejection.json`
|
|
29
|
+
- `benchmarks/results/codex-pr-metadata-2026-10-26/red.log`
|
|
30
|
+
- `benchmarks/results/codex-pr-metadata-2026-10-26/review-descriptor-green.log`
|
|
31
|
+
- `benchmarks/results/codex-pr-metadata-2026-10-26/review-descriptor-red.log`
|
|
32
|
+
- `benchmarks/results/codex-pr-metadata-2026-10-26/review-family-green.log`
|
|
33
|
+
- `benchmarks/results/codex-pr-metadata-2026-10-26/review-family-red.log`
|
|
34
|
+
- `benchmarks/results/codex-pr-metadata-2026-10-26/review-hints-green.log`
|
|
35
|
+
- `benchmarks/results/codex-pr-metadata-2026-10-26/review-hints-red.log`
|
|
36
|
+
- `benchmarks/results/codex-pr-metadata-2026-10-26/luna-action-family-cross-product.js`
|
|
37
|
+
- `benchmarks/results/codex-pr-metadata-2026-10-26/luna-action-family-cross-product.log`
|
|
38
|
+
- `benchmarks/results/codex-pr-metadata-2026-10-26/luna-codex-action-gate-prehook-smoke.js`
|
|
39
|
+
- `benchmarks/results/codex-pr-metadata-2026-10-26/luna-codex-action-gate-prehook-smoke.log`
|
|
40
|
+
- `benchmarks/results/codex-pr-metadata-2026-10-26/verification.md` (current untracked evidence)
|
|
41
|
+
- `benchmarks/results/codex-pr-metadata-2026-10-26/luna-review.md` (current untracked copied report)
|
|
42
|
+
- `benchmarks/results/codex-pr-metadata-2026-10-26/live-installed-runtime-rejection.json` (current untracked installed-runtime evidence)
|
|
43
|
+
- `ci/action-gate.test.js`
|
|
44
|
+
- `ci/mechanism-2aa-codex-action-gate-policy.test.js`
|
|
45
|
+
- `ci/mechanism-task-git-authorization.test.js`
|
|
46
|
+
- `docs/codex-action-gate.md`
|
|
47
|
+
- `docs/platform-capabilities.md`
|
|
48
|
+
- `hooks/scripts/action-gate.js`
|
|
49
|
+
- `plugins/harness-everything/hooks/scripts/action-gate.js`
|
|
50
|
+
|
|
51
|
+
The current uncommitted worktree delta is evidence-only: README status and installed-runtime provenance, `verification.md`, the copied report, and `live-installed-runtime-rejection.json`. The README now records core PASS and the independent review, while keeping candidate live-host UNCHECKED. Its linked `luna-review.md` copy still predates this final evidence adjudication and must be refreshed from this `/tmp` report before commit. No repository files were changed by this reviewer. Temporary snapshots and scripts/logs were created under `/tmp`; the two retained Luna scripts/logs were byte-compared with those files.
|
|
52
|
+
|
|
53
|
+
## Findings and dispositions
|
|
54
|
+
|
|
55
|
+
### [BLOCKER, resolved] Earlier optional hint hid a later required hint
|
|
56
|
+
|
|
57
|
+
- **Location:** `hooks/scripts/action-gate.js:380-392` @ `e160e00d265a2b427cdf6eb25783744470b0cb81`
|
|
58
|
+
- **Trigger:** Codex `PreToolUse` for exact `mcp__codex_apps__github__update_pull_request`, metadata input `{repository_full_name:"acme/repo",pr_number:376,body:"fixture"}`, top-level `actionGate:{required:false}`, and `workflowPlan.actionGate:{required:true}`.
|
|
59
|
+
- **Behavior → impact:** `routerActionGateHint` selected the first object. The new metadata branch saw `required:false`, returned `allow`/`deferred-to-host`, and bypassed an explicitly required gate.
|
|
60
|
+
- **Violates:** C3.
|
|
61
|
+
- **Witness:** Base `b733cade` blocked this mutation; `e160e00` exited 0 with empty stdout. Positive controls: plain metadata exited 0; a single required hint exited 2. The actual Codex PreToolUse stdin entrypoint reproduced the same outcomes.
|
|
62
|
+
- **Evidence tier:** executed/reproduced under Node 24.22.1.
|
|
63
|
+
- **Correction / regression:** `ff796c9` now prioritizes any supported `required:true` hint. The RED test from `1e77c26` failed 9 assertions on `e160e00`; the GREEN test passed. The retained test covers all four supported hint envelopes with conflicting optional hints.
|
|
64
|
+
- **Disposition:** resolved at `ff796c9`, rechecked at `c170a96`.
|
|
65
|
+
|
|
66
|
+
### [MAJOR, resolved] Read/unknown action descriptors bypassed required gating and mixed-risk checks
|
|
67
|
+
|
|
68
|
+
- **Location:** `hooks/scripts/action-gate.js:156-159` @ `e160e00d265a2b427cdf6eb25783744470b0cb81`
|
|
69
|
+
- **Trigger:** exact Codex PR update with `tool_input` containing `state:"closed"` and `action_descriptor:{action:"read"}`, plus `workflowPlan.actionGate.required:true`.
|
|
70
|
+
- **Behavior → impact:** `structuredRule` returned early for a descriptor classified `safe`, before checking the required hint or the metadata allowlist. The hook returned allow with no audit; a mixed high-risk input escaped the intended metadata-only check.
|
|
71
|
+
- **Violates:** C2 and C3.
|
|
72
|
+
- **Witness:** Starting state: this behavior existed at base. Expected: block because `state` is an additional high-risk field and the workflow requires a gate. Actual: `allow`, exit 0, no decision record. Positive controls: replacing `read` with `delete` or removing the explicit descriptor blocks with exit 2.
|
|
73
|
+
- **Evidence tier:** executed across base, `e160e00`, and `ff796c9`; actual external reachability of an `action_descriptor` parameter depends on the active tool schema/adapter and was not established. The Codex PR connector schema recorded in the evidence does not list that input field.
|
|
74
|
+
- **Correction / regression:** `e9344de` normalizes read/unknown descriptor actions to `mutate` for exact Codex PR-update operations before the early safe branch. The RED test from `06a66c2` failed 11 assertions on `ff796c9`; GREEN passed. Final action/family cross-product and stdin smoke confirm `mutate`/`gated` audit provenance and rejection of mixed fields.
|
|
75
|
+
- **Disposition:** resolved for exact Codex PR update at `e9344de`, rechecked at `c170a96`. The pre-existing behavior for unrelated tools/hosts was not changed.
|
|
76
|
+
|
|
77
|
+
### [MAJOR, resolved] Explicit shell family disguised an MCP PR update
|
|
78
|
+
|
|
79
|
+
- **Location:** `hooks/scripts/action-gate.js:156-159` @ `e9344de` (same early shell-family return in `e160e00`)
|
|
80
|
+
- **Trigger:** exact Codex PR update with `action_descriptor:{toolFamily:"shell",action:"delete"}` and otherwise metadata-only arguments.
|
|
81
|
+
- **Behavior → impact:** explicit descriptor family overrode the actual `mcp__...` tool identity; `structuredRule` returned at its shell branch without gating the `delete` action.
|
|
82
|
+
- **Violates:** C2, C3 and C4.
|
|
83
|
+
- **Witness:** Expected: a `delete` descriptor on a GitHub MCP update must be blocked and audited as MCP. Actual before the family fix: `allow`, exit 0, no record. Positive control: the same descriptor with `toolFamily:"mcp"` blocked with exit 2. The direct mechanism case was reproduced at the intermediate `e9344de` state.
|
|
84
|
+
- **Evidence tier:** executed at mechanism level; external reachability is subject to the same tool-schema boundary above.
|
|
85
|
+
- **Correction / regression:** `c170a96` derives the family from exact Codex PR tool identity, ignores a descriptor's family downgrade, and preserves `delete`/`publish`/`deploy`/`send` classifications. The RED test from `16f5e20` failed 14 assertions on `e9344de`; GREEN passed.
|
|
86
|
+
- **Disposition:** resolved at `c170a96`.
|
|
87
|
+
|
|
88
|
+
### [MINOR, resolved in README; copied report refresh pending] README review status was stale
|
|
89
|
+
|
|
90
|
+
- **Location:** `benchmarks/results/codex-pr-metadata-2026-10-26/README.md` (uncommitted worktree delta)
|
|
91
|
+
- **Trigger:** The report and independent checks are now complete, while the README still says `Independent review | Pending Luna xhigh cold review`.
|
|
92
|
+
- **Behavior → impact:** The evidence index understates completed review status.
|
|
93
|
+
- **Violates:** C7 evidence-record accuracy.
|
|
94
|
+
- **Witness:** Starting state/input: README pending row plus completed `/tmp/luna-pr-metadata-review.md`. Expected: row updated to review result. Actual: pending text remains.
|
|
95
|
+
- **Evidence tier:** source-traced.
|
|
96
|
+
- **Minimal correction:** Update the status row with the final core review result and retain the separate full-regression/live-host boundaries.
|
|
97
|
+
- **Regression:** Negative: status remains pending after report is accepted; positive control: the same README correctly labels candidate live-host as UNCHECKED.
|
|
98
|
+
- **Disposition:** resolved in the current README, which now links the core PASS result. Refresh the copied `luna-review.md` so it does not retain the old pending statement; this is evidence-copy synchronization only, not a runtime blocker.
|
|
99
|
+
|
|
100
|
+
## Independent verification
|
|
101
|
+
|
|
102
|
+
All local Node commands below explicitly used `/Users/daniel.chang/.nvm/versions/node/v24.22.1/bin` (`v24.22.1`).
|
|
103
|
+
|
|
104
|
+
| Check | Result / evidence |
|
|
105
|
+
| --- | --- |
|
|
106
|
+
| `node ci/action-gate.test.js` at `c170a96` | PASS, 0 failures |
|
|
107
|
+
| `node ci/mechanism-2aa-codex-action-gate-policy.test.js` at `c170a96` | PASS |
|
|
108
|
+
| `node ci/mechanism-task-git-authorization.test.js` at `c170a96` | PASS |
|
|
109
|
+
| `npm run test:plugin:openai` at `c170a96` | PASS; canonical/package parity and runtime checks |
|
|
110
|
+
| `npm run test:consistency` at `e160e00`; final `verify:all` at `c170a96` | PASS in both reviewed evidence runs |
|
|
111
|
+
| `npm run test:platform:compatibility` at `e160e00`; final `verify:all` at `c170a96` | PASS in both reviewed evidence runs |
|
|
112
|
+
| `npm run test:plugin:submission` at `e160e00`; final `verify:all` at `c170a96` | PASS in both reviewed evidence runs |
|
|
113
|
+
| Original RED: base archive `b733cade` + `db6c29b:ci/action-gate.test.js` | 12 expected failures; preceding baseline/dependency controls passed |
|
|
114
|
+
| Required-hint RED: `e160e00` archive + `1e77c26:ci/action-gate.test.js` | 9 expected failures |
|
|
115
|
+
| Descriptor RED: `ff796c9` archive + `06a66c2:ci/action-gate.test.js` | 11 expected failures |
|
|
116
|
+
| Family RED: `e9344de` archive + `16f5e20:ci/action-gate.test.js` | 14 expected failures |
|
|
117
|
+
| Final GREEN: `node ci/action-gate.test.js` at `c170a96` | PASS, 0 failures |
|
|
118
|
+
| Independent action × family × descriptor-envelope × required-hint/unsafe-field cross-product | PASS: 2,709 cases, 4,729 assertions, 0 failures; `/tmp/luna-action-family-cross-product-final.log` |
|
|
119
|
+
| Independent Codex PreToolUse stdin smoke | PASS: 7 subprocess cases; `/tmp/luna-codex-action-gate-prehook-smoke-final.log` |
|
|
120
|
+
| Base-versus-candidate controls: create, merge, close, delete, force-push, publish, deploy, send | Same outcomes; create remained host-deferred/mutate, all risky controls blocked |
|
|
121
|
+
| Original rejection hash provenance | PASS: parsed the cited transcript `CommandExecution.aggregated_output` (1,840 chars), reconstructed sorted compact JSON for repository/pr/body, SHA-256 matched audit `b9bda711…c87b` |
|
|
122
|
+
| Full `npm run verify:all` at final core SHA | PASS: exit 0, 13 PASS / 0 FAIL / 3 UNCHECKED (local Node 22 lanes); log SHA-256 `630159501b19d1d0178683262f0bfe7c0ec9cacb29a336057bb95094481129f4` |
|
|
123
|
+
| Candidate live-host behavior | UNCHECKED. The retained `live-installed-runtime-rejection.json` is an old installed runtime rejection, not candidate evidence. |
|
|
124
|
+
|
|
125
|
+
## Contract review summary
|
|
126
|
+
|
|
127
|
+
- C1/C2: exact Codex operation plus strict parameter allowlist; additional fields including null remain gated; metadata descriptor stays `mutate`/`gated`; high-risk action descriptors remain gated.
|
|
128
|
+
- C3: any `required:true` hint across supported envelopes wins; audit preserves the required hint.
|
|
129
|
+
- C4: the prehook emits no Codex `permissionDecision` allow/ask for the deferred metadata call. Host task scope, Codex permissions, and GitHub authorization remain the execution authorities.
|
|
130
|
+
- C5: create-PR behavior and risky controls matched the base; regression tests retain the explicit required-gate case.
|
|
131
|
+
- C6: canonical/plugin byte parity, redacted audit, exact payload hash, execution success/failure, rejection, and integrity behavior passed mechanism tests. No other Host was widened.
|
|
132
|
+
- C7: RED/GREEN was independently reproduced at each correction boundary; no package/mechanism result is called a candidate live-host PASS.
|
|
133
|
+
- C8: reviewed changes contain no #376 governance implementation, #341 E1 credit, #320 authorization expansion, auto-merge, or gate bypass.
|
|
134
|
+
|
|
135
|
+
## Final recommendation
|
|
136
|
+
|
|
137
|
+
No open runtime/code blocker remains at `c170a96`; the three code findings were fixed and rechecked. The final Node 24 full suite passed, with only the three explicit Node 22 lanes UNCHECKED. Candidate live-host behavior remains UNCHECKED. The README review-status minor is fixed in the current README; refresh the copied report before committing the evidence package.
|
|
138
|
+
|
|
139
|
+
## Final evidence-only adjudication
|
|
140
|
+
|
|
141
|
+
- Raw log `/tmp/pr-metadata-verify-final.log`: independently hashed to `630159501b19d1d0178683262f0bfe7c0ec9cacb29a336057bb95094481129f4` (matches `verification.md`). Header pins core `c170a96cf856295200d2d1a62c15a552c3cb2b37`, Node `v24.22.1`, Darwin, default full gate set. Process exit is `0`.
|
|
142
|
+
- Summary verified from the raw log: 13 PASS, 0 FAIL, 3 UNCHECKED. The three unchecked lanes are Node 22 self-regression smoke, installer roundtrip smoke, and `npm ci` install; optional Waza readiness passed.
|
|
143
|
+
- `verification.md` matches the raw log hash, header, per-gate results, and summary.
|
|
144
|
+
- Current README closes the earlier pending-review row, reports the full-suite summary, preserves the `gpt-6-luna`/`xhigh` routing request with no host-issued runtime attestation, and keeps candidate live-host status UNCHECKED. It does not claim final-head CI is all green; its PR workflow reference is explicitly the initial run and says final-head status must be checked separately.
|
|
145
|
+
- No runtime or plugin path changed after frozen core `c170a96`; the post-core commit `a2edf4e` and worktree delta are evidence-only. The old installed runtime rejection audit points to installed runtime `0.42.0-f51078676b56`; it is not candidate live proof.
|
|
146
|
+
- Candidate live-host execution remains UNCHECKED. No new destructive remote operation was attempted by this reviewer.
|
|
147
|
+
- The copied `luna-review.md` currently contains the pre-final pending text and must be recopied from this report before the evidence commit.
|
|
148
|
+
|
|
149
|
+
Skipped: no Node 22 lane rerun and no candidate live-host execution. Risk: those evidence boundaries remain unverified; final core Node 24 gates passed.
|
|
150
|
+
|
|
151
|
+
STATUS: DONE
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"toolName": "mcp__codex_apps__github__update_pull_request",
|
|
4
|
+
"toolUseId": "exec-8e76e1be-e5a3-493d-807b-2ad6cdbc7c31",
|
|
5
|
+
"commandHash": "b9bda7116fb01c045edd71a6b4fc3091c0ab707e0b797f1b4efca6e7a4edc87b",
|
|
6
|
+
"actionDescriptor": {
|
|
7
|
+
"schemaVersion": 1,
|
|
8
|
+
"toolFamily": "mcp",
|
|
9
|
+
"toolName": "mcp__codex_apps__github__update_pull_request",
|
|
10
|
+
"action": "mutate",
|
|
11
|
+
"resource": "dyphn1/Harness-everything",
|
|
12
|
+
"payloadHash": "b9bda7116fb01c045edd71a6b4fc3091c0ab707e0b797f1b4efca6e7a4edc87b",
|
|
13
|
+
"classification": "gated",
|
|
14
|
+
"reasonCodes": [
|
|
15
|
+
"tool-identity-inference"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
"matchedRule": "structured-mutate",
|
|
19
|
+
"ruleReason": "Structured mutate action requires pre-action authorization.",
|
|
20
|
+
"disposition": "rejected",
|
|
21
|
+
"host": "codex",
|
|
22
|
+
"permissionMode": "bypassPermissions",
|
|
23
|
+
"gatePolicy": "defer-to-host",
|
|
24
|
+
"routerActionGate": null,
|
|
25
|
+
"ruleTableSource": "/Users/daniel.chang/.codex/harness-everything/compat-hooks/runtime/0.42.0-f51078676b56/hooks/scripts/action-gate-rules.json",
|
|
26
|
+
"degradedRuleTable": false,
|
|
27
|
+
"degradationReason": null,
|
|
28
|
+
"createdAt": "2026-10-26T01:12:15.045Z",
|
|
29
|
+
"updatedAt": "2026-10-26T01:12:15.045Z",
|
|
30
|
+
"rejectionReason": "host-ask-decision-unverified-or-unsupported"
|
|
31
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
=== Issue #85 Phase 5 — Pre-action gate ===
|
|
2
|
+
PASS production action-gate rule table loads without fallback
|
|
3
|
+
PASS production rule table is non-empty and keeps the destructive baseline
|
|
4
|
+
PASS rule table contains git-force-push
|
|
5
|
+
PASS rule table contains git-reset-hard
|
|
6
|
+
PASS rule table contains git-clean-force-delete
|
|
7
|
+
PASS rule table contains recursive-delete
|
|
8
|
+
PASS rule table contains powershell-recursive-force-delete
|
|
9
|
+
PASS rule table contains sql-destructive-ddl
|
|
10
|
+
PASS rule table contains package-publish
|
|
11
|
+
PASS rule table contains github-release-create
|
|
12
|
+
PASS rule table contains production-deploy
|
|
13
|
+
PASS Claude force-push defers to the host permission flow without forcing a prompt
|
|
14
|
+
PASS deferred decision still names the matched rule
|
|
15
|
+
PASS matched Claude action is audited as deferred-to-host
|
|
16
|
+
PASS audit records matched rule
|
|
17
|
+
PASS audit hashes the exact command payload
|
|
18
|
+
PASS always-ask policy restores the forced Claude prompt
|
|
19
|
+
PASS ask decision uses Claude PreToolUse hookSpecificOutput
|
|
20
|
+
PASS ask reason names the matched rule
|
|
21
|
+
PASS always-ask action is audited as pending-approval
|
|
22
|
+
PASS git status passes untouched
|
|
23
|
+
PASS safe unmatched command creates no gate audit record
|
|
24
|
+
PASS permission_mode=default defers to the host without a forced prompt
|
|
25
|
+
PASS audit records permission_mode=default
|
|
26
|
+
PASS permission_mode=acceptEdits defers to the host without a forced prompt
|
|
27
|
+
PASS audit records permission_mode=acceptEdits
|
|
28
|
+
PASS permission_mode=plan defers to the host without a forced prompt
|
|
29
|
+
PASS audit records permission_mode=plan
|
|
30
|
+
PASS permission_mode=auto defers to the host without a forced prompt
|
|
31
|
+
PASS audit records permission_mode=auto
|
|
32
|
+
PASS permission_mode=dontAsk defers to the host without a forced prompt
|
|
33
|
+
PASS audit records permission_mode=dontAsk
|
|
34
|
+
PASS permission_mode=bypassPermissions defers to the host without a forced prompt
|
|
35
|
+
PASS audit records permission_mode=bypassPermissions
|
|
36
|
+
PASS permission_mode=missing defers to the host without a forced prompt
|
|
37
|
+
PASS audit records permission_mode=missing
|
|
38
|
+
PASS command classification gates destructive action even when router hint says not required
|
|
39
|
+
PASS router actionGate hint is recorded without controlling enforcement
|
|
40
|
+
PASS safe command is not gated solely because prompt router predicted risk
|
|
41
|
+
PASS structured MCP delete is gated before execution
|
|
42
|
+
PASS audit retains normalized structured action identity
|
|
43
|
+
PASS structured action audit binds to exact payload hash
|
|
44
|
+
PASS structured action audit does not persist raw secret arguments
|
|
45
|
+
PASS read-only MCP fixture passes without a false gate
|
|
46
|
+
PASS obvious structured mutation is classified from tool identity
|
|
47
|
+
PASS non-shell local-function destructive fixture uses the same structured gate
|
|
48
|
+
PASS unknown structured action fails closed when workflow requires a gate
|
|
49
|
+
PASS unknown structured action is not fabricated as destructive without a gate requirement
|
|
50
|
+
PASS changed structured payload cannot reuse a prior approval/audit decision
|
|
51
|
+
PASS PowerShell recursive force delete outside scratch is gated
|
|
52
|
+
PASS PowerShell recursive force delete inside session scratch is exempt
|
|
53
|
+
PASS rm -rf outside scratch is gated
|
|
54
|
+
PASS rm -rf inside OS temp is exempt
|
|
55
|
+
PASS git reset --hard HEAD matches git-reset-hard
|
|
56
|
+
PASS git clean -fd matches git-clean-force-delete
|
|
57
|
+
PASS psql -c "DROP TABLE users" matches sql-destructive-ddl
|
|
58
|
+
PASS npm publish matches package-publish
|
|
59
|
+
PASS gh release create v1.2.3 matches github-release-create
|
|
60
|
+
PASS npm run deploy matches production-deploy
|
|
61
|
+
PASS host without verified ask-style decision blocks with exit 2
|
|
62
|
+
PASS non-ask host block reason names the matched rule
|
|
63
|
+
PASS non-ask host block is audited as rejected
|
|
64
|
+
PASS internal action-gate error on Claude defers to the host instead of allowing or forcing a prompt
|
|
65
|
+
PASS internal error is shown to the user as a systemMessage without a permission decision
|
|
66
|
+
PASS internal error on Claude is audited as deferred-to-host
|
|
67
|
+
PASS internal action-gate error under always-ask fails closed to ask
|
|
68
|
+
PASS internal error on host without ask fails closed to block
|
|
69
|
+
PASS missing/invalid rule table visibly falls back to built-in defaults
|
|
70
|
+
PASS built-in fallback still classifies and audits destructive action
|
|
71
|
+
PASS fallback degradation is shown to the user as a systemMessage
|
|
72
|
+
PASS valid empty rule table does not silently activate built-in defaults
|
|
73
|
+
PASS empty-table mutation control disables detection, proving production non-empty assertion is meaningful
|
|
74
|
+
PASS null-prototype serialization preserves an own __proto__ key
|
|
75
|
+
PASS own __proto__ key changes the full-input digest
|
|
76
|
+
PASS PostToolUse closes a deferred payload as executed
|
|
77
|
+
PASS executed audit keeps exact approved payload hash
|
|
78
|
+
PASS PostToolUseFailure records attempted execution without pretending success
|
|
79
|
+
PASS post-tool payload mismatch is never accepted as the approved command
|
|
80
|
+
PASS Stop closes unexecuted deferred and pending payloads
|
|
81
|
+
PASS unexecuted deferred payload is audited as rejected
|
|
82
|
+
PASS unexecuted always-ask approval is audited as rejected
|
|
83
|
+
PASS hook process returns no decision for a matched command under the default policy
|
|
84
|
+
PASS hook process audits the deferred command with its permission mode
|
|
85
|
+
PASS HARNESS_ACTION_GATE_POLICY=always-ask makes the hook process emit ask
|
|
86
|
+
PASS Claude hook manifest wires action-gate to shell and MCP pre-action surfaces
|
|
87
|
+
PASS Claude hook manifest audits successful tool execution
|
|
88
|
+
PASS Claude hook manifest audits failed tool execution
|
|
89
|
+
PASS Claude hook manifest closes unresolved approvals on Stop
|
|
90
|
+
PASS OpenAI plugin preserves the attribution-aware Codex shell action-gate adapter
|
|
91
|
+
PASS OpenAI plugin packages an isolated structured MCP pre-action adapter without widening unrelated hooks
|
|
92
|
+
PASS OpenAI plugin packages an isolated structured MCP post-action audit adapter
|
|
93
|
+
PASS Codex plugin does not declare unsupported PostToolUseFailure lifecycle event
|
|
94
|
+
PASS Codex plugin infers action-gate outcome from supported PostToolUse
|
|
95
|
+
PASS Codex PostToolUse maps zero exit code to success
|
|
96
|
+
PASS Codex PostToolUse maps non-zero exit code to failure
|
|
97
|
+
PASS Codex PostToolUse conservatively recognizes failure stderr without exit code
|
|
98
|
+
PASS OpenAI plugin closes pending approvals at Stop
|
|
99
|
+
PASS canonical and plugin action-gate rule tables are byte-identical
|
|
100
|
+
PASS OpenAI plugin packages action-gate runtime
|
|
101
|
+
FAIL update_pull_request body defers without a permission decision
|
|
102
|
+
PASS metadata remains a non-safe mutation
|
|
103
|
+
FAIL update_pull_request title defers without a permission decision
|
|
104
|
+
PASS metadata remains a non-safe mutation
|
|
105
|
+
FAIL update_pull_request title,body defers without a permission decision
|
|
106
|
+
PASS metadata remains a non-safe mutation
|
|
107
|
+
FAIL mcp__github__update_pull_request body defers without a permission decision
|
|
108
|
+
PASS metadata remains a non-safe mutation
|
|
109
|
+
FAIL mcp__github__update_pull_request title defers without a permission decision
|
|
110
|
+
PASS metadata remains a non-safe mutation
|
|
111
|
+
FAIL mcp__github__update_pull_request title,body defers without a permission decision
|
|
112
|
+
PASS metadata remains a non-safe mutation
|
|
113
|
+
FAIL mcp__codex_apps__github__update_pull_request body defers without a permission decision
|
|
114
|
+
PASS metadata remains a non-safe mutation
|
|
115
|
+
FAIL mcp__codex_apps__github__update_pull_request title defers without a permission decision
|
|
116
|
+
PASS metadata remains a non-safe mutation
|
|
117
|
+
FAIL mcp__codex_apps__github__update_pull_request title,body defers without a permission decision
|
|
118
|
+
PASS metadata remains a non-safe mutation
|
|
119
|
+
FAIL mcp__codex_apps__github_update_pull_request body defers without a permission decision
|
|
120
|
+
PASS metadata remains a non-safe mutation
|
|
121
|
+
FAIL mcp__codex_apps__github_update_pull_request title defers without a permission decision
|
|
122
|
+
PASS metadata remains a non-safe mutation
|
|
123
|
+
FAIL mcp__codex_apps__github_update_pull_request title,body defers without a permission decision
|
|
124
|
+
PASS metadata remains a non-safe mutation
|
|
125
|
+
PASS metadata with {"state":"closed"} remains gated
|
|
126
|
+
PASS metadata with {"state":"open"} remains gated
|
|
127
|
+
PASS metadata with {"state":null} remains gated
|
|
128
|
+
PASS metadata with {"base_branch":"other"} remains gated
|
|
129
|
+
PASS metadata with {"maintainer_can_modify":false} remains gated
|
|
130
|
+
PASS metadata with {"maintainer_can_modify":null} remains gated
|
|
131
|
+
PASS metadata with {"unknown":true} remains gated
|
|
132
|
+
PASS metadata with {"title":"mixed","state":"closed"} remains gated
|
|
133
|
+
PASS metadata with {"draft":true} remains gated
|
|
134
|
+
PASS metadata with {"base":"other"} remains gated
|
|
135
|
+
PASS metadata with {"action_descriptor":{"action":"delete"}} remains gated
|
|
136
|
+
PASS missing or malformed metadata remains gated
|
|
137
|
+
PASS missing or malformed metadata remains gated
|
|
138
|
+
PASS missing or malformed metadata remains gated
|
|
139
|
+
PASS missing or malformed metadata remains gated
|
|
140
|
+
PASS missing or malformed metadata remains gated
|
|
141
|
+
PASS missing or malformed metadata remains gated
|
|
142
|
+
PASS missing or malformed metadata remains gated
|
|
143
|
+
PASS missing or malformed metadata remains gated
|
|
144
|
+
PASS mcp__demo__update_pull_requests receives no metadata exception
|
|
145
|
+
PASS mcp__demo__foo_update_pull_request receives no metadata exception
|
|
146
|
+
PASS mcp__demo__update_pull_request_and_delete receives no metadata exception
|
|
147
|
+
PASS mcp__codex_apps__github_update_pull_request_extra receives no metadata exception
|
|
148
|
+
PASS mcp__demo__merge_pull_request receives no metadata exception
|
|
149
|
+
PASS mcp__demo__close_pull_request receives no metadata exception
|
|
150
|
+
PASS claude retains existing mutation rule
|
|
151
|
+
PASS opencode retains existing mutation rule
|
|
152
|
+
PASS unknown retains existing mutation rule
|
|
153
|
+
PASS explicit required metadata gate cannot be bypassed
|
|
154
|
+
PASS explicit required metadata gate cannot be bypassed
|
|
155
|
+
PASS explicit required metadata gate cannot be bypassed
|
|
156
|
+
PASS explicit required metadata gate cannot be bypassed
|
|
157
|
+
|
|
158
|
+
FAIL: action-gate phase 5 (12 failures)
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
=== Issue #85 Phase 5 — Pre-action gate ===
|
|
2
|
+
PASS production action-gate rule table loads without fallback
|
|
3
|
+
PASS production rule table is non-empty and keeps the destructive baseline
|
|
4
|
+
PASS rule table contains git-force-push
|
|
5
|
+
PASS rule table contains git-reset-hard
|
|
6
|
+
PASS rule table contains git-clean-force-delete
|
|
7
|
+
PASS rule table contains recursive-delete
|
|
8
|
+
PASS rule table contains powershell-recursive-force-delete
|
|
9
|
+
PASS rule table contains sql-destructive-ddl
|
|
10
|
+
PASS rule table contains package-publish
|
|
11
|
+
PASS rule table contains github-release-create
|
|
12
|
+
PASS rule table contains production-deploy
|
|
13
|
+
PASS Claude force-push defers to the host permission flow without forcing a prompt
|
|
14
|
+
PASS deferred decision still names the matched rule
|
|
15
|
+
PASS matched Claude action is audited as deferred-to-host
|
|
16
|
+
PASS audit records matched rule
|
|
17
|
+
PASS audit hashes the exact command payload
|
|
18
|
+
PASS always-ask policy restores the forced Claude prompt
|
|
19
|
+
PASS ask decision uses Claude PreToolUse hookSpecificOutput
|
|
20
|
+
PASS ask reason names the matched rule
|
|
21
|
+
PASS always-ask action is audited as pending-approval
|
|
22
|
+
PASS git status passes untouched
|
|
23
|
+
PASS safe unmatched command creates no gate audit record
|
|
24
|
+
PASS permission_mode=default defers to the host without a forced prompt
|
|
25
|
+
PASS audit records permission_mode=default
|
|
26
|
+
PASS permission_mode=acceptEdits defers to the host without a forced prompt
|
|
27
|
+
PASS audit records permission_mode=acceptEdits
|
|
28
|
+
PASS permission_mode=plan defers to the host without a forced prompt
|
|
29
|
+
PASS audit records permission_mode=plan
|
|
30
|
+
PASS permission_mode=auto defers to the host without a forced prompt
|
|
31
|
+
PASS audit records permission_mode=auto
|
|
32
|
+
PASS permission_mode=dontAsk defers to the host without a forced prompt
|
|
33
|
+
PASS audit records permission_mode=dontAsk
|
|
34
|
+
PASS permission_mode=bypassPermissions defers to the host without a forced prompt
|
|
35
|
+
PASS audit records permission_mode=bypassPermissions
|
|
36
|
+
PASS permission_mode=missing defers to the host without a forced prompt
|
|
37
|
+
PASS audit records permission_mode=missing
|
|
38
|
+
PASS command classification gates destructive action even when router hint says not required
|
|
39
|
+
PASS router actionGate hint is recorded without controlling enforcement
|
|
40
|
+
PASS safe command is not gated solely because prompt router predicted risk
|
|
41
|
+
PASS structured MCP delete is gated before execution
|
|
42
|
+
PASS audit retains normalized structured action identity
|
|
43
|
+
PASS structured action audit binds to exact payload hash
|
|
44
|
+
PASS structured action audit does not persist raw secret arguments
|
|
45
|
+
PASS read-only MCP fixture passes without a false gate
|
|
46
|
+
PASS obvious structured mutation is classified from tool identity
|
|
47
|
+
PASS non-shell local-function destructive fixture uses the same structured gate
|
|
48
|
+
PASS unknown structured action fails closed when workflow requires a gate
|
|
49
|
+
PASS unknown structured action is not fabricated as destructive without a gate requirement
|
|
50
|
+
PASS changed structured payload cannot reuse a prior approval/audit decision
|
|
51
|
+
PASS PowerShell recursive force delete outside scratch is gated
|
|
52
|
+
PASS PowerShell recursive force delete inside session scratch is exempt
|
|
53
|
+
PASS rm -rf outside scratch is gated
|
|
54
|
+
PASS rm -rf inside OS temp is exempt
|
|
55
|
+
PASS git reset --hard HEAD matches git-reset-hard
|
|
56
|
+
PASS git clean -fd matches git-clean-force-delete
|
|
57
|
+
PASS psql -c "DROP TABLE users" matches sql-destructive-ddl
|
|
58
|
+
PASS npm publish matches package-publish
|
|
59
|
+
PASS gh release create v1.2.3 matches github-release-create
|
|
60
|
+
PASS npm run deploy matches production-deploy
|
|
61
|
+
PASS host without verified ask-style decision blocks with exit 2
|
|
62
|
+
PASS non-ask host block reason names the matched rule
|
|
63
|
+
PASS non-ask host block is audited as rejected
|
|
64
|
+
PASS internal action-gate error on Claude defers to the host instead of allowing or forcing a prompt
|
|
65
|
+
PASS internal error is shown to the user as a systemMessage without a permission decision
|
|
66
|
+
PASS internal error on Claude is audited as deferred-to-host
|
|
67
|
+
PASS internal action-gate error under always-ask fails closed to ask
|
|
68
|
+
PASS internal error on host without ask fails closed to block
|
|
69
|
+
PASS missing/invalid rule table visibly falls back to built-in defaults
|
|
70
|
+
PASS built-in fallback still classifies and audits destructive action
|
|
71
|
+
PASS fallback degradation is shown to the user as a systemMessage
|
|
72
|
+
PASS valid empty rule table does not silently activate built-in defaults
|
|
73
|
+
PASS empty-table mutation control disables detection, proving production non-empty assertion is meaningful
|
|
74
|
+
PASS null-prototype serialization preserves an own __proto__ key
|
|
75
|
+
PASS own __proto__ key changes the full-input digest
|
|
76
|
+
PASS PostToolUse closes a deferred payload as executed
|
|
77
|
+
PASS executed audit keeps exact approved payload hash
|
|
78
|
+
PASS PostToolUseFailure records attempted execution without pretending success
|
|
79
|
+
PASS post-tool payload mismatch is never accepted as the approved command
|
|
80
|
+
PASS Stop closes unexecuted deferred and pending payloads
|
|
81
|
+
PASS unexecuted deferred payload is audited as rejected
|
|
82
|
+
PASS unexecuted always-ask approval is audited as rejected
|
|
83
|
+
PASS hook process returns no decision for a matched command under the default policy
|
|
84
|
+
PASS hook process audits the deferred command with its permission mode
|
|
85
|
+
PASS HARNESS_ACTION_GATE_POLICY=always-ask makes the hook process emit ask
|
|
86
|
+
PASS Claude hook manifest wires action-gate to shell and MCP pre-action surfaces
|
|
87
|
+
PASS Claude hook manifest audits successful tool execution
|
|
88
|
+
PASS Claude hook manifest audits failed tool execution
|
|
89
|
+
PASS Claude hook manifest closes unresolved approvals on Stop
|
|
90
|
+
PASS OpenAI plugin preserves the attribution-aware Codex shell action-gate adapter
|
|
91
|
+
PASS OpenAI plugin packages an isolated structured MCP pre-action adapter without widening unrelated hooks
|
|
92
|
+
PASS OpenAI plugin packages an isolated structured MCP post-action audit adapter
|
|
93
|
+
PASS Codex plugin does not declare unsupported PostToolUseFailure lifecycle event
|
|
94
|
+
PASS Codex plugin infers action-gate outcome from supported PostToolUse
|
|
95
|
+
PASS Codex PostToolUse maps zero exit code to success
|
|
96
|
+
PASS Codex PostToolUse maps non-zero exit code to failure
|
|
97
|
+
PASS Codex PostToolUse conservatively recognizes failure stderr without exit code
|
|
98
|
+
PASS OpenAI plugin closes pending approvals at Stop
|
|
99
|
+
PASS canonical and plugin action-gate rule tables are byte-identical
|
|
100
|
+
PASS OpenAI plugin packages action-gate runtime
|
|
101
|
+
PASS update_pull_request body defers without a permission decision
|
|
102
|
+
PASS metadata remains a non-safe mutation
|
|
103
|
+
PASS update_pull_request title defers without a permission decision
|
|
104
|
+
PASS metadata remains a non-safe mutation
|
|
105
|
+
PASS update_pull_request title,body defers without a permission decision
|
|
106
|
+
PASS metadata remains a non-safe mutation
|
|
107
|
+
PASS mcp__github__update_pull_request body defers without a permission decision
|
|
108
|
+
PASS metadata remains a non-safe mutation
|
|
109
|
+
PASS mcp__github__update_pull_request title defers without a permission decision
|
|
110
|
+
PASS metadata remains a non-safe mutation
|
|
111
|
+
PASS mcp__github__update_pull_request title,body defers without a permission decision
|
|
112
|
+
PASS metadata remains a non-safe mutation
|
|
113
|
+
PASS mcp__codex_apps__github__update_pull_request body defers without a permission decision
|
|
114
|
+
PASS metadata remains a non-safe mutation
|
|
115
|
+
PASS mcp__codex_apps__github__update_pull_request title defers without a permission decision
|
|
116
|
+
PASS metadata remains a non-safe mutation
|
|
117
|
+
PASS mcp__codex_apps__github__update_pull_request title,body defers without a permission decision
|
|
118
|
+
PASS metadata remains a non-safe mutation
|
|
119
|
+
PASS mcp__codex_apps__github_update_pull_request body defers without a permission decision
|
|
120
|
+
PASS metadata remains a non-safe mutation
|
|
121
|
+
PASS mcp__codex_apps__github_update_pull_request title defers without a permission decision
|
|
122
|
+
PASS metadata remains a non-safe mutation
|
|
123
|
+
PASS mcp__codex_apps__github_update_pull_request title,body defers without a permission decision
|
|
124
|
+
PASS metadata remains a non-safe mutation
|
|
125
|
+
PASS provider-neutral selectors support metadata updates
|
|
126
|
+
PASS provider-neutral selectors support metadata updates
|
|
127
|
+
PASS own __proto__ field cannot escape the argument allowlist
|
|
128
|
+
PASS explicit higher-risk action cannot inherit metadata deferral
|
|
129
|
+
PASS metadata with {"state":"closed"} remains gated
|
|
130
|
+
PASS metadata with {"state":"open"} remains gated
|
|
131
|
+
PASS metadata with {"state":null} remains gated
|
|
132
|
+
PASS metadata with {"base_branch":"other"} remains gated
|
|
133
|
+
PASS metadata with {"maintainer_can_modify":false} remains gated
|
|
134
|
+
PASS metadata with {"maintainer_can_modify":null} remains gated
|
|
135
|
+
PASS metadata with {"unknown":true} remains gated
|
|
136
|
+
PASS metadata with {"title":"mixed","state":"closed"} remains gated
|
|
137
|
+
PASS metadata with {"draft":true} remains gated
|
|
138
|
+
PASS metadata with {"base":"other"} remains gated
|
|
139
|
+
PASS metadata with {"action_descriptor":{"action":"delete"}} remains gated
|
|
140
|
+
PASS missing or malformed metadata remains gated
|
|
141
|
+
PASS missing or malformed metadata remains gated
|
|
142
|
+
PASS missing or malformed metadata remains gated
|
|
143
|
+
PASS missing or malformed metadata remains gated
|
|
144
|
+
PASS missing or malformed metadata remains gated
|
|
145
|
+
PASS missing or malformed metadata remains gated
|
|
146
|
+
PASS missing or malformed metadata remains gated
|
|
147
|
+
PASS missing or malformed metadata remains gated
|
|
148
|
+
PASS mcp__demo__update_pull_requests receives no metadata exception
|
|
149
|
+
PASS mcp__demo__foo_update_pull_request receives no metadata exception
|
|
150
|
+
PASS mcp__demo__update_pull_request_and_delete receives no metadata exception
|
|
151
|
+
PASS mcp__codex_apps__github_update_pull_request_extra receives no metadata exception
|
|
152
|
+
PASS mcp__demo__merge_pull_request receives no metadata exception
|
|
153
|
+
PASS mcp__demo__close_pull_request receives no metadata exception
|
|
154
|
+
PASS claude retains existing mutation rule
|
|
155
|
+
PASS opencode retains existing mutation rule
|
|
156
|
+
PASS unknown retains existing mutation rule
|
|
157
|
+
PASS explicit required metadata gate cannot be bypassed
|
|
158
|
+
PASS explicit required metadata gate cannot be bypassed
|
|
159
|
+
PASS explicit required metadata gate cannot be bypassed
|
|
160
|
+
PASS explicit required metadata gate cannot be bypassed
|
|
161
|
+
PASS known Codex PR mutation cannot be downgraded to read
|
|
162
|
+
PASS downgrade refusal remains an audited mutation
|
|
163
|
+
PASS known Codex PR mutation cannot be downgraded to read
|
|
164
|
+
PASS downgrade refusal remains an audited mutation
|
|
165
|
+
PASS known Codex PR mutation cannot be downgraded to read
|
|
166
|
+
PASS downgrade refusal remains an audited mutation
|
|
167
|
+
PASS input read descriptor cannot hide a required PR mutation gate
|
|
168
|
+
PASS known Codex PR mutation cannot be downgraded to unknown
|
|
169
|
+
PASS downgrade refusal remains an audited mutation
|
|
170
|
+
PASS known Codex PR mutation cannot be downgraded to unknown
|
|
171
|
+
PASS downgrade refusal remains an audited mutation
|
|
172
|
+
PASS known Codex PR mutation cannot be downgraded to unknown
|
|
173
|
+
PASS downgrade refusal remains an audited mutation
|
|
174
|
+
PASS input unknown descriptor cannot hide a required PR mutation gate
|
|
175
|
+
PASS provider namespace read token cannot downgrade exact PR mutation
|
|
176
|
+
PASS claude explicit descriptor behavior remains unchanged
|
|
177
|
+
PASS opencode explicit descriptor behavior remains unchanged
|
|
178
|
+
PASS unknown explicit descriptor behavior remains unchanged
|
|
179
|
+
PASS required hint envelope 0 wins over optional envelopes
|
|
180
|
+
PASS audit retains required hint instead of a conflicting optional hint
|
|
181
|
+
PASS PR creation still honors the documented explicit required gate
|
|
182
|
+
PASS required hint envelope 1 wins over optional envelopes
|
|
183
|
+
PASS audit retains required hint instead of a conflicting optional hint
|
|
184
|
+
PASS PR creation still honors the documented explicit required gate
|
|
185
|
+
PASS required hint envelope 2 wins over optional envelopes
|
|
186
|
+
PASS audit retains required hint instead of a conflicting optional hint
|
|
187
|
+
PASS PR creation still honors the documented explicit required gate
|
|
188
|
+
PASS required hint envelope 3 wins over optional envelopes
|
|
189
|
+
PASS audit retains required hint instead of a conflicting optional hint
|
|
190
|
+
PASS PR creation still honors the documented explicit required gate
|
|
191
|
+
|
|
192
|
+
PASS: action-gate phase 5 (0 failures)
|