Skip to content

v6.7 Tranche 1: kanban_complete verification gates (#28, #62, #64) - #11

Merged
jarvis-stark-ops merged 3 commits into
mainfrom
kaipo/v6.7-completion-gates
Jun 10, 2026
Merged

v6.7 Tranche 1: kanban_complete verification gates (#28, #62, #64)#11
jarvis-stark-ops merged 3 commits into
mainfrom
kaipo/v6.7-completion-gates

Conversation

@jarvis-stark-ops

Copy link
Copy Markdown
Collaborator

Summary

Adds three pre-write-txn gates in complete_task that catch the failure modes the 2026-06-09 v6.7 build chain demonstrated. See hermes-jarvis#61 for the full case study — 9 tasks reported done in ~10 minutes with zero real deliverables.

Pattern mirrors the existing _verify_created_cards / HallucinatedCardsError flow at hermes_cli/kanban_db.py:3607. State unchanged on rejection; worker can retry after fixing the issue.

Gates

  • verify_runtime_floor (closes hermes-jarvis#64) — per-role floor on completed_at - started_at. build 5min, review 90s, orchestration 0. Catches Tony's 20s "approve" verdicts and Friday's 59s "implementation".
  • verify_workspace_diff (closes hermes-jarvis#62) — non-review workers on dir/worktree workspaces that claim implementation must produce a non-empty git diff against the tracking base. Catches Friday's empty branch + fabricated summary.
  • verify_no_stray_artifacts (closes hermes-jarvis#28) — rejects *evidence*, commit-hash*, triage/*, tmp-*, no-extension/no-shebang files. Catches the agent-dashboard PR schema: express conditional-required constraints for grok-style tool callers #1 "all prior block evidence files" mode.

Opt-outs

  • metadata.x_fast_justified → bypasses runtime floor
  • metadata.x_no_code → bypasses workspace-diff
  • metadata.x_stray_ok → bypasses hygiene gate

Opt-outs recorded on the completed event for audit.

Test plan

  • 28 new tests in tests/cli/test_kanban_completion_gates.py — each pin the exact 2026-06-09 failure modes plus clean-path passes and opt-outs
  • Wider regression: pytest tests/cli/ tests/tools/ -k 'kanban or complete or task' → 258 passed / 0 failed
  • Validation loop after merge: fresh swarm chain with intentional empty-diff/stray-file/fast-completion attempts; verify each rejected at kanban_complete

Why this PR alone (Tranche 1)

v6.7 has 11 total issues. This addresses the three that would have rejected 2026-06-09's chain on first attempt. Tranche 2: NousResearch#29/NousResearch#30/NousResearch#31 (verdict-field validation + auto-spawn integrative review + reviewer SOULs in hermes-jarvis). Tranche 3: NousResearch#32/NousResearch#33/NousResearch#34/NousResearch#63/NousResearch#65.

🤖 Generated with Claude Code

Adds three pre-write-txn gates that fire before complete_task transitions a
task to done. Mirrors the existing _verify_created_cards /
HallucinatedCardsError pattern: any violation is recorded as an audit event
and raised, so worker state is unchanged and the worker can retry after
fixing the underlying issue.

Closes hermes-jarvis#28 (repo hygiene gate)
Closes hermes-jarvis#62 (workspace-diff verification)
Closes hermes-jarvis#64 (per-role runtime floor)
Context: hermes-jarvis#61 (bootstrap-paradox case study)

## The three gates

1. verify_runtime_floor — per-role floor on completed_at - started_at.
   build roles 5min, review roles 90s, orchestration roles 0.
   Catches Tony's 20-second "approve" verdicts and Friday's 59-second
   "implemented 7 dispatcher gates" claims.

2. verify_workspace_diff — when a non-review worker on a dir/worktree
   workspace claims to have produced code, git diff against the tracking
   base must show actual changes. Catches Friday's "Wave A gates
   implemented" with an empty diff on the branch.

3. verify_no_stray_artifacts — rejects untracked or tracked artifacts
   matching patterns the swarm has historically committed by accident:
   *evidence*, commit-hash*, triage/*, tmp-*, and tracked files with
   no extension and no shebang (the "all prior block evidence files"
   failure mode from agent-dashboard PR #1).

## Opt-outs

Workers may bypass individual gates via per-call metadata keys:
  x_fast_justified  → allow_below_floor
  x_no_code         → allow_no_code
  x_stray_ok        → allow_stray

Opt-outs are recorded as part of the completed event for audit.

## Tests

28 new tests cover the exact 2026-06-09 failure modes (Tony 20s,
Friday 59s + empty diff, PR-1 "all prior block evidence files") plus
clean-path passes and opt-outs. 258 passed / 0 failed in the wider
kanban+complete+task test suite — zero regressions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Jarvis and others added 2 commits June 9, 2026 16:12
…, dead-code removal

Independent review of PR #11 surfaced two P0s and several P1s that would
have actively recreated the v6.7 failure mode the gates exist to
prevent. This commit addresses every finding.

Findings + fixes:

## P0 — Opt-outs were free keyword bypasses

`bool(metadata.get("x_fast_justified"))` accepted `True`, `"x"`, `"ok"`
— all truthy under bool(). A worker that learned the metadata key
could pass `{"x_fast_justified": true}` and bypass every gate. The
docstring also lied: it claimed "opt-outs are recorded as part of the
completed event for audit" but nothing in `complete_task` copied the
opt-out keys to any event.

Fix: new `_validate_opt_out` requires the value be a STRING of at
least 20 non-whitespace characters and raises `InvalidOptOutError` on
anything else. Accepted opt-outs are emitted as a
`completion_opt_out_used` event with verbatim reasons.

## P0 — Hygiene gate false-positived on legitimate tracked files

`verify_no_stray_artifacts` flagged `LICENSE`, `Dockerfile`,
`Makefile`, `Vagrantfile`, `README` because the no-extension rule was
applied universally. The `evidence` regex also matched legitimate
filenames like `optional-skills/security/oss-forensics/references/
evidence-types.md` and `scripts/evidence-store.py`. Verified by running
the gate against the hermes-agent repo itself: 15 stray paths, all
legitimate.

Fix:
- Tightened patterns: `evidence/` must be a directory segment;
  `*-evidence.<ext>` only matches with explicit artifact extensions
  (.json/.png/.log/.txt/.md/.yaml/.yml); `triage/` matches as a
  segment.
- No-extension+no-shebang rule now applies to UNTRACKED files only.
  Specific patterns (commit-hash.txt, triage/, tmp-*) still match
  tracked files too — a worker who actually committed those is just
  as wrong.
- Allowlist for well-known no-extension basenames (LICENSE, Dockerfile,
  Makefile, ...) as defense in depth.

## P1 — Workspace-diff was bypassable by avoiding trigger verbs

`_summary_claims_implementation` only triggered on a fixed verb list.
A worker who wrote "Per spec, the changes land in hermes_cli and tests
pass" had no trigger verb and bypassed the gate even with an empty
branch.

Fix: build-role + dir/worktree workspace ALWAYS requires a non-empty
diff. Workers who honestly produced no code should call kanban_block
with a reason, or opt out via x_no_code with a string justification
≥20 chars. Dead `_summary_claims_implementation` and
`_IMPLEMENTATION_CLAIM_PATTERNS` removed.

## P1 — Other production callers didn't catch the new errors

`complete_task` is also called from `hermes_cli/kanban.py:_cmd_complete`
(CLI) and `plugins/kanban/dashboard/plugin_api.py` (PATCH endpoints
×2). Without explicit catches, the new exceptions would have been
stack traces — to stderr in the CLI, to a 500 in the dashboard.

Fix: CLI prints the error and continues per task; dashboard endpoints
translate to HTTP 409 (single PATCH) or per-entry error (bulk).
Block-task callers updated for `FabricatedAuthClaimError` too.

## P1 — Pure-function tests missed integration regressions

Added `TestOptOutAudit` (5 tests) and `TestCompleteTaskIntegration`
(2 tests) that exercise the full `complete_task` → gate → event →
state-unchanged path. A wiring regression in
`_v6_7_run_completion_gates` would now fail in CI.

## Test results

40 passed in tests/cli/test_kanban_completion_gates.py — up from 28
in the original PR #11 (12 new + 1 replacing the verb-trigger test).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ce-diff gate

Empty/None summary on a build role with no diff previously crashed
`splitlines()[0]` before `verify_workspace_diff` could surface its
violation. The crash bubbled past the gate, skipped the
`completion_blocked_v6_7_gates` audit event, and surfaced as a 500
in the dashboard. Fix: guard the excerpt construction.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jarvis-stark-ops
jarvis-stark-ops merged commit a39b9df into main Jun 10, 2026
jarvis-stark-ops pushed a commit that referenced this pull request Jun 10, 2026
…1/N6 fixes

A second-pass independent review of the reviewer-fields PR found three
new findings that this commit addresses:

## N1 — Empty body crashed splitlines()[0]

Same shape as the workspace-diff crash bug fixed on PR #11. When
`body` was empty or None, `verify_reviewer_fields` raised IndexError
before constructing the violation. Real tasks with empty body columns
hit this. Fix: guard splitlines result.

## N2 — Inline prose ≥20 chars bypassed adversarial_pass gates

`adversarial_pass.env_vars: see above explanation about general env
safety` (51 chars of prose, zero structure) passed the gate because
the substantive check was character count. Same laundering shape as
the prose-evidence bypass we fixed in the previous self-review.

Fix: introduce `_has_adversarial_structure` requiring at least one
of: bullet item line, UPPER_SNAKE env-var token followed by colon,
path-like substring with a slash (e.g. `lib/ingest.ts`), or a source
file extension (.ts, .py, .yaml, etc.). Honest empty markers ([], none,
n/a) still accepted. Pure prose now correctly rejected.

## N6 — `evidence: none` bypassed citation discipline on code reviews

When the body indicated code-touching review (`app/api/...`, `route.ts`,
etc.), the previous gate accepted `evidence: none` as an honest-empty
declaration. But for a code review, "no test evidence" is exactly the
problem — Tony's job is to verify tests cover the deliverable.

Fix: `_field_present` now takes `code_change_context` and disallows
the honest-empty escape on `test_quality.evidence` when the body
triggers adversarial requirements. Non-code reviews (docs, design)
still accept `evidence: none`.

## Tests

7 new tests in `TestReviewerFieldsSelfReviewFixes`:
- empty body doesn't crash
- None body doesn't crash
- adversarial inline prose bypass rejected (the N2 exploit)
- structured inline values (ENV: bound, file.ts, path/like) pass
- evidence:none blocked when body triggers adversarial
- evidence:none allowed for pure docs review
- bullet list under adversarial fields is the canonical happy path

64 passed in tests/cli/test_kanban_completion_gates.py — up from 57.
87 passed across PR #12 + adjacent regression set; zero failures.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant