agentsclimarketplace

Night market completion integrity campaign

Skill athola/claude-night-market/.claude/skills/night-market-completion-integrity-campaign

23 Claude Code plugins: TDD enforcement hooks, git/PR workflows, spec-driven development, code review, project lifecycle, fix-from-error, maintenance automation, context optimization, research, and multi-LLM delegation. 186 skills, 128 commands, 54 agents.

Install
npx -y skills add athola/claude-night-market --skill night-market-completion-integrity-campaign

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

What its author says it does

Copied from the file, not written here

Bind loop 'done' to unfakeable gates. Use to harden egregore/herald loops or promote completion_integrity. Not for QA gates; use night-market-validation-and-qa.

SKILL.md

27.6 KB, as published. Nobody here has run it

Night Market Completion-Integrity Campaign

This is an executable campaign, phased and decision-gated, against the hardest live problem in this repository: making "done" in autonomous loops mean something the agent cannot fake, and earning the promotion of completion_integrity from default-off to default-on. Every command below was run against the repo on 2026-07-02 (v1.9.15) unless marked candidate. Run the phases in order. Each phase ends at a gate with expected observations and branch instructions.

Definitions

TermMeaning
Autonomous loopA session that keeps working without a human turn: egregore's orchestrator (/egregore:summon), the externally installed ralph-wiggum loop, herald's auto-continue Stop hook
Stop hookA Claude Code hook fired when the agent tries to end its turn. It prints {"decision": "approve"} (allow stop) or {"decision": "block", "reason": ...} (keep working)
Completion integrityThe property that a loop's "done" signal is bound to a verifier the agent does not control, instead of the agent's own say-so
False stopThe loop halts while verifiable work remains, or accepts a claimed completion that a check would have rejected
False continueThe loop keeps working (blocks the stop) on a turn that was genuinely finished
VerdictThe egregore quality-gate outcome: pass, pass-with-warnings, or fix-required (computed after a 3-attempt auto-fix loop)

Problem statement

Three assets exist today. None of them, alone, binds "done" to an unfakeable gate:

AssetWhat it doesDefaultKey commits
plugins/egregore/scripts/config.py field PipelineConfig.completion_integrityWhen true, a fix-required verdict counts as a step failure (the item cannot reach completed with blocking findings) and merge is held for human review regardless of auto_mergeFalse83281337 (gate), cd903cbf (raw-JSON opt-in test)
plugins/herald/hooks/double_shot_latte.py (Stop hook)Deterministic continue/stop judge over the last assistant message, with an opt-in LLM second shot for the single ambiguous outcomeDeterministic only268cff89 (timeout cap + gating)
plugins/imbue/skills/proof-of-work/modules/verifier-integrity.mdThe theory: a gate earns trust only if the spec is validated separately from the code and the check is proven able to failProse guidance29081fda

The load-bearing weakness, verified by reading commit 83281337: the completion_integrity flag is real code with a tested load path, but its enforcement lives in agent instructions (plugins/egregore/agents/orchestrator.md, the egregore:quality-gate skill, and skills/summon/modules/pipeline.md). No Python code path blocks a pipeline transition. The manifest that records item status (.egregore/manifest.json) is written by the same agent the gate is supposed to bind. The campaign exists to close that gap with evidence.

Evidence bar

Success is measured, never judged by eye. The standing rules are drawn from the two 2026-07-01 research syntheses in docs/research/ (gitignored and machine-local, so absent on fresh clones; the load-bearing claims are therefore inlined below) and the imbue:proof-of-work verifier-integrity module:

  • State the numbers a hypothesis predicts BEFORE running the measurement. A threshold chosen after seeing the data is not a gate.
  • One mechanism must explain all observations, including the negative ones.
  • Never let the generator be its own judge: LLM self-verification is measurably unreliable and self-critique can degrade output, so verdicts come from an independent verifier (prover-verifier separation; local synthesis: docs/research/2026-07-01-prover-verifier-loops-formal-verification.md).
  • A green check proves spec satisfaction, never correctness. Every gate you add must itself be proven able to go red (verifier-integrity Guard 2: mutation or revert test).

Campaign map

PhaseQuestion it answersGate to pass
P0Do today's gate and judge suites pass as documented?Exact pass counts reproduced
P1What does the gate log when enabled on real work?Opt-in path exercised on a bounded item, logs captured
P2What are the false-stop and false-continue rates?Pre-registered numbers met
P3Can the loop satisfy the gate without doing the work?Refutation attempts run, holes documented or closed
P4Is the default flip earned?Change control passed

P0: baseline the gate and judge suites

Run every suite from inside its plugin directory. Root pytest sets norecursedirs = plugins/*, so running from the repo root silently collects nothing (or raises ImportPathMismatchError). Every cd in this skill is relative to the repo root: start each command block from there.

cd plugins/egregore
uv run pytest tests/ -q

Expected (2026-07-02): 477 passed in about 2 seconds, preceded by a coverage table.

cd plugins/egregore
uv run pytest tests/test_config.py tests/test_quality_gate.py -q

Expected: 27 passed. tests/test_config.py alone is 13 passed and includes the two completion-integrity guards: test_completion_integrity_opt_in_roundtrip and test_completion_integrity_loads_from_raw_json (the real user opt-in path, added in cd903cbf. It also guards the field against silent removal, because _filter_fields would drop the key).

cd plugins/herald
uv run pytest tests/ -q

Expected: 105 passed in under 2 seconds. This suite contains test_llm_timeout_fits_within_hook_timeout, which asserts LLM_TIMEOUT_SECONDS (8) is strictly below the Stop-hook timeout registered in plugins/herald/hooks/hooks.json (10).

cd plugins/imbue
uv run pytest tests/unit/skills/test_proof_of_work.py -q

Expected: 17 passed. Note: imbue's pytest addopts force coverage artifacts on every run. There is no dedicated test for the verifier-integrity module itself (verified 2026-07-02 by grepping plugins/imbue/tests/ for verifier-integrity): the module is prose, covered only by the skill-structure test above.

Smoke-test the herald judge directly. All three probes below were run and their outputs captured verbatim on 2026-07-02:

echo '{"session_id":"probe","transcript_path":"/nonexistent"}' \
  | python3 plugins/herald/hooks/double_shot_latte.py

Expected:

{"decision": "approve", "reason": "Double Shot Latte: No transcript available; allowing stop."}
D=$(mktemp -d)
printf '%s\n' '{"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"Now let me fix the failing tests."}]}}' \
  > "$D/t.jsonl"
echo "{\"session_id\":\"p1\",\"transcript_path\":\"$D/t.jsonl\"}" \
  | python3 plugins/herald/hooks/double_shot_latte.py

Expected:

{"decision": "block", "reason": "Double Shot Latte: Assistant stated explicit intent to keep working."}

Gate P0 branches:

  • Pass counts lower than stated, or any failure: the repo has drifted since 2026-07-02. Stop the campaign. Triage with night-market-debugging-playbook, then update the counts in this skill's Provenance section before proceeding.
  • ImportPathMismatchError or no tests ran: you ran pytest from the wrong directory. Re-run from inside the plugin.
  • Hook probe emits nothing or a traceback: the hook contract is broken (it must always exit 0 and print a decision). That is a P0 incident, not a campaign step. File it.

P1: shadow observation, then opt-in on a bounded item

P1a: shadow read (no behavior change)

Verdicts are recorded in the manifest even with the flag off (the egregore:quality-gate skill records every verdict as a decision entry {"step": ..., "chose": ..., "why": ...}). So the flag-off world already contains the shadow data: items that advanced to completed despite a fix-required verdict. Count them in any repo where egregore has run:

python3 - <<'EOF'
import json
from pathlib import Path

path = Path(".egregore/manifest.json")
if not path.exists():
    print(json.dumps({"error": "no manifest; egregore has not run here"}))
    raise SystemExit(0)
data = json.loads(path.read_text())
items = data.get("work_items") or data.get("items") or []
flagged = [
    {"id": i.get("id"), "status": i.get("status")}
    for i in items
    if any(d.get("chose") == "fix-required" for d in i.get("decisions", []))
]
print(json.dumps(
    {"total_items": len(items), "items_with_fix_required": flagged},
    indent=2,
))
EOF

Expected: a JSON summary. Any entry with "status": "completed" in items_with_fix_required is a shadow-mode false completion: the exact event the gate exists to prevent. Record the count as the P2 baseline.

Branch: no manifest exists in this repo's root (egregore is typically summoned in target repos, and .egregore/ state lives where it ran). If you have no manifest anywhere, skip to P1b and generate one.

P1b: enable the gate on a bounded run

The opt-in path is hand-editing the config JSON. This exact shape is what test_completion_integrity_loads_from_raw_json covers: unspecified pipeline fields keep their defaults.

mkdir -p .egregore
cat > .egregore/config.json <<'EOF'
{"pipeline": {"completion_integrity": true}}
EOF

Warning: if .egregore/config.json already exists, edit the existing pipeline object instead of overwriting the file, or you will reset overseer and alert settings to defaults.

Then run a small, disposable work item in bounded mode (bounded mode stops when the time window expires, so the loop cannot run away while you observe):

/egregore:summon "<one small, well-specified task>" --bounded --window 5h

Before summoning, read "Stopping and relaunch machinery" at the end of this section: bounded mode expires on its own, but the watchdog and SessionStart hook can still resurrect the loop.

What it logs and where:

  • .egregore/manifest.json: per-item status (active, paused, pending count as unfinished for the Stop hook, while completed and failed are terminal), attempts, max_attempts (default 3), and the decisions array holding each quality verdict.
  • .egregore/relaunch-prompt.md: the re-injection prompt the egregore Stop hook (plugins/egregore/hooks/stop_hook.py) uses when it blocks an exit with active work remaining.
  • Overseer alerts per .egregore/config.json (pipeline_failure fires when an item exhausts attempts).

Expected observations with the flag on, per the documented contract in plugins/egregore/skills/quality-gate/SKILL.md and agents/orchestrator.md:

  1. A fix-required verdict routes to failure handling: the item retries in place, and after max_attempts it is marked failed with the overseer alerted. It is never silently completed.
  2. Merge is held for human review regardless of auto_merge: the PR is prepared but left open.
  3. The loop itself does not halt: it continues with the next active item.

Gate P1 branches:

  • An item reaches completed with an unresolved fix-required decision while the flag is true: the orchestrator ignored its instructions. This confirms the prompt-level enforcement gap in the problem statement. Record the manifest as evidence and carry it into P3. The finding argues for solution (a) or (b) below, which move enforcement out of the prompt.
  • The item loops in retry forever: max_attempts is not being incremented. That is an orchestrator bug, not a gate result. File it with the manifest attached.

Stopping and relaunch machinery

Know the stop path before you summon. The loop runs indefinitely by default and never stops on its own (plugins/egregore/commands/dismiss.md).

  • /egregore:dismiss is the only sanctioned stop. It pauses all active items in the manifest, cancels the orchestrator's cron jobs, and removes the pidfile (.egregore/pid).
  • The pidfile is what the watchdog daemon polls. If /egregore:install-watchdog has run on the machine, plugins/egregore/scripts/watchdog.sh fires every 5 minutes via launchd or systemd and relaunches a session whenever the manifest has unfinished work, the budget allows it, and no pidfile marks a live session. Killing a session without dismissing therefore gets you silently relaunched sessions.
  • A SessionStart hook (matcher startup|resume in plugins/egregore/hooks/hooks.json) auto-resumes orchestration in new and resumed sessions while egregore state is active. Closing the terminal is not a stop either.
  • .egregore/budget.json bounds spend. The watchdog checks it before relaunching, so an exhausted budget halts relaunches even without a dismiss.

P2: measure false-stop and false-continue rates

Fix the acceptance numbers before running anything. The numbers below are candidates recorded at authoring time. Whoever executes P2 must confirm or amend them, in writing, before the first measurement run.

MetricDefinitionCandidate gate
Egregore false completionsItems completed with an unresolved fix-required verdict, flag on0 over N >= 20 work items
Egregore false failuresItems failed whose findings a human reviewer judges non-blocking<= 2 of 20 (candidate)
Herald false continueJudge blocks a stop on a turn a human labels finished<= 5% over N >= 30 labeled transcripts (candidate)
Herald false stopJudge approves a stop on a turn with explicit stated intent to continue<= 10% over the same set (candidate)

The asymmetry is deliberate: herald's false continue burns tokens and nags a finished session, while its false stop merely hands control to the human. The judge is biased to stop by design, so tolerate more false stops than false continues.

Herald measurement harness (candidate, offline and read-only): collect real session transcripts, hand-label the final assistant message of each as finished / awaiting-user / continuing, then score the deterministic judge against the labels:

for t in "$HOME"/.claude/projects/*/*.jsonl; do
  verdict=$(printf '{"session_id":"m","transcript_path":"%s"}' "$t" \
    | python3 plugins/herald/hooks/double_shot_latte.py)
  echo "$t $verdict"
done

Notes for the harness: the event omits stop_hook_active, so the throttle counter is not consulted, and DOUBLE_SHOT_LATTE_LLM unset keeps the run deterministic and network-free. Compute the confusion matrix against your labels by hand or with a 20-line script. Commit the labeled set alongside the numbers so the measurement is reproducible.

Egregore measurement: repeat P1b across N >= 20 items (candidate N) and tally the manifest with the P1a script. Do not curate which items go in. Take a contiguous slice of real backlog.

Gate P2 branches:

  • Numbers met: proceed to P3.
  • Herald false-continue rate blows the gate: inspect which _CONTINUE_PATTERNS regex fired on finished turns and tighten it. That is deterministic gate expansion, solution (a); re-run the same labeled set after the change.
  • Egregore false completions are nonzero: enforcement is not binding. Do not tune thresholds to pass. Go to P3 and then to solution (a) or (b).

P3: adversarial self-test (design the refutation)

The question: can the loop satisfy the gate without doing the work? Run each attack, record the result, and either close the hole or document it as accepted residual risk with an owner.

Attack A: talk your way past the herald judge

Verified on 2026-07-02: a transcript whose final assistant message is "Everything is done and verified, tests passing green." gets

{"decision": "approve", "reason": "Double Shot Latte: Assistant signaled the work is complete."}

with zero checks run. The judge is a conversation-state classifier over the last 800 characters of assistant text (TAIL_CHARS), by design. It answers "does the agent intend to continue?", never "is the work actually done?". Conclusion, standing: herald's verdict must never be used as completion proof. Any design that treats a Stop-hook approve as evidence of completion fails this attack by construction.

Attack B: fake the egregore manifest

With completion_integrity true, hand-edit one work item in .egregore/manifest.json from active to completed while its decisions still contain a fix-required. Then feed the egregore Stop hook a stop event:

echo '{}' | python3 plugins/egregore/hooks/stop_hook.py

Expected (run from a directory whose walk-up finds that manifest): the hook checks only status in ("active", "paused", "pending") via has_active_work and prints {"decision": "approve"}. Nothing cross-checks decisions against status. This demonstrates the residual hole: the manifest is agent-writable state, so an orchestrator that lies in the manifest defeats the gate. Candidate hardening (unbuilt): teach the Stop hook to refuse completed status on items whose most recent quality decision is fix-required, which moves one enforcement point out of the prompt and into code the agent does not author mid-loop. Treat that as a P4 prerequisite discussion item, not a given.

Attack C: mutation-prove every gate you add

Any new deterministic check earns trust only by going red on a real break (verifier-integrity Guard 2). For each check added during this campaign, record evidence in the module's format:

[V1] Check: <the test or gate>
     Encodes requirement: <observable behavior, stated from intent>
     Fake-resistance: <mutation applied> -> <check went RED: yes/no>
     Independence: <executable / who verified>
     Passing run: <command + output reference>

A single surviving mutation is a hole in the gate, not a rounding error.

Solution menu, ranked

Ranked by fake-resistance. Each carries a theory obligation the implementation must discharge.

  1. Deterministic gate expansion (a). Grow the executable side of the verdict: convention checks, tests, lints, result artifacts that run outside the agent's narrative. Obligation: every check mutation-proven (Guard 2) and, where a property exists, asserted as a property rather than pinned examples (Guard 4). The principle from the harness research: the agent "can still cut a corner, it just can't cut this one past a check it doesn't control."
  2. Separated verifier agent (b). A second session, with no access to the producer's reasoning, evaluates the diff against the acceptance criteria and returns localized findings. Obligation: prover-verifier separation (the generator never judges itself: LLM self-verification is measurably unreliable), localized feedback piped back for targeted repair, and a hard attempt cap after which the failure is reported instead of forced green. Status: candidate, no implementation in this repo yet.
  3. LLM judge second shot (d). Acceptable only as a tiebreaker for a single ambiguous outcome, exactly as herald gates it: the LLM is consulted only when the deterministic verdict is the default-stop reason, its subprocess timeout stays strictly below the registered hook budget with a guard test, and a recursion-guard env var stops the judge's own Stop hook from spawning judges. Obligation: never let it override a confident deterministic verdict.
  4. Human checkpoint (c). Hold the merge open for human review, which is what completion_integrity already does. Open question, on record in docs/research/2026-07-01-the-coming-loop-agentic-harness-guardrails.md: whether the discipline of keeping a human judge survives competitive and security pressure is the contested point between Ronacher and his critics. Keep the human checkpoint as the backstop, and never count it as the automated gate.

Known wrong paths (fenced off)

Wrong pathEvidenceWhat happened
Subprocess timeout at or above the registered hook budget268cff89, and the guard test test_llm_timeout_fits_within_hook_timeoutherald's LLM call outlived the registered hook budget, so the harness killed the hook before it printed any decision at all (full record: night-market-failure-archaeology SB7). Cap child timeouts strictly below the registered budget and pin the relation with a test
Letting the generator judge its own outputdocs/research/2026-07-01-prover-verifier-loops-formal-verification.mdSelf-verification is frequently no better than generation and self-critique can degrade output. Verdicts must come from an independent verifier
Assuming hook payloads arrive in env varsCHANGELOG 1.9.14 ("Hooks read the tool payload from stdin, not unset env vars")Hooks reading CLAUDE_TOOL_* were silent no-ops for months (full record: night-market-failure-archaeology SB9). Payload is JSON on stdin. Use shared/hook_io.read_hook_payload
Shipping an optional branch no test exercises268cff89 added 81 test lines for the LLM pathThe deterministic suite was green while the opt-in LLM branch was broken by construction. Every opt-in branch needs at least one test that walks it
Treating "done" text as a completion gateAttack A above, plus the harness research: a completion promise must pair with an iteration cap and manual abortString-matched completion is trivially fakeable and herald proves it live
Prompt-only enforcement of a code-level guaranteeP1/P3 findings in this campaignThe flag flips real code, but nothing in code blocks the transition, so a non-compliant orchestrator defeats it. Move at least one enforcement point into a hook or script

P4: promotion through change control

Flipping completion_integrity to default-on changes the documented posture of every egregore deployment. It routes through night-market-change-control. Do not shortcut it.

Preconditions, all required:

  • P2 numbers met at the pre-registered thresholds, raw data committed.
  • P3 attacks run, with Attack B either closed by a code-side check or formally accepted in the ADR with an owner.
  • The promotion decision drafted as a numbered ADR in docs/adr/ (next free number: ADR-0017 is the highest as of 2026-07-02), because this reverses a deliberate recorded default.

Implementation order (Iron Law: failing test first):

  1. Branch per convention: <topic>-<version>, from master.

  2. Turn the default's tests red first: in plugins/egregore/tests/test_config.py, change test_pipeline_defaults to expect completion_integrity is True and run it. Expected: 1 failure, proving the test binds the default.

  3. Flip the default in plugins/egregore/scripts/config.py (PipelineConfig.completion_integrity: bool = True) and re-run:

    cd plugins/egregore
    uv run pytest tests/test_config.py tests/test_quality_gate.py -q
    
  4. Update every document that states the default is off. Verified list as of 2026-07-02 (re-derive with the rg command in Provenance): plugins/egregore/scripts/config.py (comment), plugins/egregore/tests/test_config.py (comment), plugins/egregore/agents/orchestrator.md, plugins/egregore/skills/quality-gate/SKILL.md, plugins/egregore/skills/summon/modules/pipeline.md, plugins/egregore/README.md.

  5. Add a CHANGELOG entry under [Unreleased] in Keep a Changelog format. Never rewrite historical entries.

  6. Check the diff against the 200-line AI-commit cap (CONSTITUTION rule 2). The code flip is tiny, but the doc sweep plus ADR may exceed it: if so, the ADR itself is the required planning doc; reference it in the commit body.

  7. Run the standard gates before committing (make lint, make typecheck, plugin tests) and follow the PR flow in night-market-operations.

Rollback: the flag remains user-overridable either way ({"pipeline": {"completion_integrity": false}} in .egregore/config.json), so promotion is reversible per-deployment without a code change. State this in the ADR.

When NOT to use

  • Routine test, lint, or release execution: use night-market-operations.
  • General evidence standards and coverage thresholds outside the loop problem: use night-market-validation-and-qa.
  • Hook mechanics, timeouts, and registration syntax: use claude-code-plugin-reference.
  • The history of why these guards exist (SB7, SB9, and friends): use night-market-failure-archaeology.
  • Classifying and gating the promotion change itself: this skill routes there, but the authority is night-market-change-control.
  • Open research directions beyond this campaign (for example hook-side manifest cross-checks as a general pattern): use night-market-research-frontier.

Exit Criteria

  • P0 pass counts reproduced from inside each plugin directory (egregore full suite, herald suite, imbue proof-of-work test) and all three herald smoke probes emit the documented JSON verdicts.
  • P1b executed at least once: a bounded egregore run with pipeline.completion_integrity true, with the resulting .egregore/manifest.json captured as evidence.
  • P2 thresholds written down and dated BEFORE the measurement runs, and the labeled data plus confusion matrix committed alongside the computed rates.
  • P3 Attacks A and B executed with recorded outcomes, and every gate added during the campaign has a [V1]-format fake-resistance record showing a mutation went red.
  • Promotion either completed through P4 (ADR merged, default flipped, docs and CHANGELOG updated, tests green) or explicitly parked with the blocking metric named in the ADR draft.
  • No step of the campaign treated a Stop-hook approve or an agent's completion message as evidence of completed work.

Provenance and maintenance

Compiled 2026-07-02 against repo v1.9.15, branch state discussions-fix-1.9.14. "Stopping and relaunch machinery" subsection added to P1b on 2026-07-03. Volatile facts and how to re-verify them:

  • Test pass counts (477 egregore, 27 config+quality, 13 config alone, 105 herald, 17 imbue proof-of-work) date from 2026-07-02. Re-run the P0 commands and update this file when they drift.
  • Gate implementation and defaults: rg -n "completion_integrity" plugins/egregore/ should list config.py, test_config.py, orchestrator.md, quality-gate SKILL.md, pipeline.md, and README.md. A new hit means new enforcement surface to fold into P4 step 4.
  • Herald timeout relation: rg -n "LLM_TIMEOUT_SECONDS" \ plugins/herald/hooks/double_shot_latte.py (expect 8) and the "timeout" value in plugins/herald/hooks/hooks.json (expect 10).
  • Herald judge env switches: DOUBLE_SHOT_LATTE_LLM=1 enables the second shot, DOUBLE_SHOT_LATTE_MODEL picks the model (default haiku), DOUBLE_SHOT_LATTE_MAX_CONTINUATIONS overrides the cap of 10 per 300-second window. Re-verify with rg -n "os.environ" plugins/herald/hooks/double_shot_latte.py.
  • Stop and relaunch machinery: re-verify with head -30 plugins/egregore/commands/dismiss.md, head -25 plugins/egregore/scripts/watchdog.sh (manifest, budget, and pidfile paths), and rg -n "startup|resume" plugins/egregore/hooks/hooks.json (SessionStart matcher). Verified 2026-07-03.
  • Key commits: git show --stat 83281337 cd903cbf 268cff89 29081fda.
  • Research grounding: the two files matching ls docs/research/2026-07-01-*.md. docs/research/ is gitignored and machine-local, so expect no matches on a fresh clone; the claims this campaign relies on are inlined in the evidence bar.
  • Highest ADR number: ls docs/adr/ | sort | tail -1 (0017 as of compilation).
  • Candidate items in this file (P2 thresholds and N values, the P2 herald harness loop, the Attack B hook-side hardening, solution (b) verifier agent) are unproven by definition. Remove the label only with committed evidence.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.