Failure 75. The claim and the refusal.
Updated September 2026.
Failure Corpus record 75. Corpus JSON.
- Record
- 75
- First documented
- 09-13-2026
- Kind
- verification-gap
- Title in the corpus
- An alarm with a catch-all arm files the case it was built for as unexplained, and a verdict with no reason is a log entry, not a record: an agent closed a run reporting every guard green, the harness's own gauntlet refused the tree, and the refusal reached no reader, because the outcome row carried no reason, the failing guard's name lived only in the job log, and the failure alarm had no arm for the most common way a run ends red
- Countermeasure path
__tests__/scripts/seat-workflow-generation.test.ts
The claim
All guards green, all 5,858 tests passing
Autonomous Content run 34710543133, Sep, 12 2026. The test count is the agent's claim. Lesson 75 says the site suite and build behind the failing guard did not run.
Source: docs/lessons-learned.md:320. Commit 527baea7c.
The refusal
The guard printed [blog-standards] FAIL. The isolate step exited with code 1 and the tree was discarded. The completion marker had already set RUN_OUTCOME=agent_done.
Source: docs/lessons-learned.md:320. Commit 527baea7c.
The blast radius
Lesson 75 reports 10 issues across 5 seats from August 29 through Sep, 12 2026. It lists issues 123, 130, 132, 135, 138, 139, 152, 153, 155 and 161. The search was gh issue list --search '"does not know how to explain" in:body'. The repository and issues are private.
Source: docs/lessons-learned.md:320. Commit 527baea7c.
The correction
packages/collective/actions/org-agent/action.yml
Commit 527baea7c. Commit date . Selected diff lines.
+ guard_refused() {
+ echo "GUARD_REFUSED=$1" >> "$GITHUB_ENV"
+ echo "::error::guard refused the tree at stage $1"
+ exit 1
+ }
+ node scripts/check-dashes.cjs || guard_refused builtin-dashes
+ node packages/collective/src/org-secrets.mjs || guard_refused builtin-secrets
+ node packages/collective/src/check-org-memory.mjs --staged || guard_refused builtin-memory
if [ -n "${{ inputs.guard-command }}" ]; then
echo "Running caller guard-command."
- bash -c "${{ inputs.guard-command }}"
+ bash -c "${{ inputs.guard-command }}" 2>&1 | tee /tmp/guard-output.txt || guard_refused caller
fipackages/collective/actions/org-agent/action.yml
Commit 527baea7c. Commit date . Selected diff lines.
if [ "${{ steps.push.outputs.committed }}" != "true" ] && [ "${{ steps.push.outputs.committed }}" != "none" ]; then
OUTCOME="rejected"
+ if [ -n "${GUARD_REFUSED:-}" ]; then
+ REASON="guard-refused"
+ REFUSED_BY="${GUARD_REFUSED}"
+ fi
fipackages/collective/actions/org-agent/action.yml
Commit 527baea7c. Commit date . Selected diff lines.
- --producing-step "outcome" --reason "${REASON:-}" \
+ --producing-step "outcome" --reason "${REASON:-}" --refused-by "${REFUSED_BY:-}" \.github/workflows/autonomous-content.yml
Commit 527baea7c. Commit date . Selected diff lines.
+ no_sentinel) WHAT="OBSERVED: the agent completed normally (exit 0, a non-error subtype, under its turn cap) and its result carried no terminal sentinel, so its OUTPUT was refused before any guard ran and the run is recorded as rejected. Read the transcript tail for what it did instead of finishing; nothing below is a guard finding." ;;
+ agent_done) WHAT="OBSERVED: the agent declared completion (its sentinel was present and the completion gate passed) and the harness did not land the tree${STAGE:+, refused at guard stage '$STAGE'}. The closing self-report in the transcript tail is the agent's CLAIM about the tree; the guard output tail is the MEASUREMENT. Read the guard's own summary line first, then the stats row (reason guard-refused, refused_by). A report of green beside a measured red is the finding, not a mystery. If no guard stage is named, the refusal came before the guards or the push failed; the job log says which." ;;The paired inputs
Both inputs end in a refusal. The first omits GUARD_REFUSED; the second sets it to caller. The displayed fields show whether the row and alarm name the refusing stage.
Source: __tests__/scripts/org-agent-shell-contract.test.ts. Commit 527baea7c.
Failing input. Before the correction.
Input
{
"RUN_OUTCOME": "agent_done"
}Outcome row fields
{
"outcome": "rejected"
}Alarm text
OBSERVED: outcome reported as 'agent_done', which this alarm does not know how to explain. That is itself worth looking at.
Source: .github/workflows/autonomous-content.yml. Commit caee0c489.
Passing input. Envelope v6.
Input
{
"RUN_OUTCOME": "agent_done",
"GUARD_REFUSED": "caller"
}Outcome row fields
{
"outcome": "rejected",
"reason": "guard-refused",
"refused_by": "caller"
}Alarm text
OBSERVED: the agent declared completion (its sentinel was present and the completion gate passed) and the harness did not land the tree, refused at guard stage 'caller'. The closing self-report in the transcript tail is the agent's CLAIM about the tree; the guard output tail is the MEASUREMENT. Read the guard's own summary line first, then the stats row (reason guard-refused, refused_by). A report of green beside a measured red is the finding, not a mystery. If no guard stage is named, the refusal came before the guards or the push failed; the job log says which.
Source: .github/workflows/autonomous-content.yml. Commit 527baea7c.
The dated result
Reported passing date: .
The correction authored on Sep, 13 2026 reports passing checks for the alarm arms. It records a failing check after removing the agent_done arm and regenerating the workflows. The exact first passing test time is not recorded.
Source: __tests__/scripts/seat-workflow-generation.test.ts. Commit 527baea7c.
The test and its negative control
Source: __tests__/scripts/seat-workflow-generation.test.ts. Commit 527baea7c.
Test commit date: . Selected test blocks.
it("STAYS QUIET on every committed seat workflow", () => {
const dir = path.join(REPO, ".github", "workflows");
const alarmed = fs.readdirSync(dir).filter((n) => n.endsWith(".yml"))
.filter((n) => fs.readFileSync(path.join(dir, n), "utf8").includes("On failure, open an issue"));
// Every seat spec renders the alarm; a lock over zero workflows is no lock.
expect(alarmed.length).toBe(fs.readdirSync(SEATS_DIR).filter((f) => f.endsWith(".json")).length);
for (const f of alarmed) {
expect(missing(fs.readFileSync(path.join(dir, f), "utf8")), `${f} has outcome words with no arm`).toEqual([]);
}
});
it("goes LOUD when an arm is removed from a rendered workflow", () => {
const rendered = fs.readFileSync(path.join(REPO, ".github", "workflows", "autonomous-content.yml"), "utf8");
const without = rendered.replace(/^\s*agent_done\) WHAT=.*\n/m, "");
expect(without).not.toBe(rendered);
expect(missing(without)).toEqual(["agent_done"]);
});The recurrence
Lesson 61 records two test isolation failures on Sep, 15 2026. One test inherited GUARD_REFUSED=caller and misclassified a failed push. Another replaced the live receipt with an older row from another seat. That row reached the uploaded artifact; the current row did not reach main because the commit was refused.
Source: docs/lessons-learned.md:236. Commit feaf02048.
The limits
This record publishes selected diff lines and outcome fields. It does not publish the full job log or the issue bodies. The issue count and seat count remain the lesson's report, not a public recount.
Source: docs/lessons-learned.md:320. Commit 527baea7c.
These examples show the original correction. Envelope v7 later marked a stop without a named guard as infrastructure, with reason harness-fault. The current alarm test checks that case.
Source: __tests__/scripts/content-alarm-names-its-cause.test.ts. Commit bfb892257.
Lesson 75 leaves the claim register unfinished. A record of the refusal does not establish that this failure class stopped recurring.
Source: docs/lessons-learned.md:320. Commit 527baea7c.