Release: SDD discipline triad + per-PR review pipeline + dep bumps + Trivy refresh#264
Merged
nikolanovoselec merged 21 commits intomainfrom May 3, 2026
Merged
Release: SDD discipline triad + per-PR review pipeline + dep bumps + Trivy refresh#264nikolanovoselec merged 21 commits intomainfrom
nikolanovoselec merged 21 commits intomainfrom
Conversation
Bumps [hono](https://github.com/honojs/hono) from 4.12.14 to 4.12.15. - [Release notes](https://github.com/honojs/hono/releases) - [Commits](honojs/hono@v4.12.14...v4.12.15) --- updated-dependencies: - dependency-name: hono dependency-version: 4.12.15 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [oxlint](https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint) from 1.61.0 to 1.62.0. - [Release notes](https://github.com/oxc-project/oxc/releases) - [Changelog](https://github.com/oxc-project/oxc/blob/main/npm/oxlint/CHANGELOG.md) - [Commits](https://github.com/oxc-project/oxc/commits/oxlint_v1.62.0/npm/oxlint) --- updated-dependencies: - dependency-name: oxlint dependency-version: 1.62.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [jsdom](https://github.com/jsdom/jsdom) from 29.0.2 to 29.1.0. - [Release notes](https://github.com/jsdom/jsdom/releases) - [Commits](jsdom/jsdom@v29.0.2...v29.1.0) --- updated-dependencies: - dependency-name: jsdom dependency-version: 29.1.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [oxlint](https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint) from 1.59.0 to 1.62.0. - [Release notes](https://github.com/oxc-project/oxc/releases) - [Changelog](https://github.com/oxc-project/oxc/blob/main/npm/oxlint/CHANGELOG.md) - [Commits](https://github.com/oxc-project/oxc/commits/oxlint_v1.62.0/npm/oxlint) --- updated-dependencies: - dependency-name: oxlint dependency-version: 1.62.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.9 to 8.0.10. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v8.0.10/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-version: 8.0.10 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [knip](https://github.com/webpro-nl/knip/tree/HEAD/packages/knip) from 6.6.1 to 6.11.0. - [Release notes](https://github.com/webpro-nl/knip/releases) - [Commits](https://github.com/webpro-nl/knip/commits/knip@6.11.0/packages/knip) --- updated-dependencies: - dependency-name: knip dependency-version: 6.9.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…ish (#263) * test: scaffold for workflow-upgrade (RED) Static-assertion test suite covering every change in the v3.1 plan. At this commit, every assertion fails because the implementations are still pending. Subsequent commits 2-11 turn assertions green progressively as each piece of the workflow upgrade lands. Mirrors entrypoint-hooks-merge.test.js style: node:test + assert/strict, static grep against actual preseed file contents. Refs #251, #252, #253. * docs(preseed): add documentation-discipline.md sibling rule (#252) New always-loaded rule file enforced by doc-updater. Defines what may NOT appear in documentation/, per-file line budgets (architecture.md 350, api-reference.md 600, configuration.md 200, deployment.md 200), per-element caps (≤50-word table cells, ≤15-line code snippets), lane separation between architecture/api-reference/configuration/ deployment, four enforcement passes (per-cell, per-file, prose detection, lane violation), and pattern 13 (dual-narrative ADRs). Mirrors spec-discipline.md style. Escape hatch <!-- doc-allow-large --> for legitimate exceptions. Refs #252. * docs(preseed): spec-discipline patterns 11/12/14 (#252) - Pattern 11 — run-on AC bullets (>150 words / 3+ semicolons) - Pattern 12 — mechanism leakage in AC bullets (cookie attrs, header names, middleware names — observable consequence in AC, mechanism in documentation/security.md) - Pattern 14 — changelog drift (entry without corresponding AC delta) - Cross-reference to new sibling documentation-discipline.md Refs #252. * docs(preseed): doc-updater per-cell + per-file budget passes (#251) doc-updater now runs four enforcement passes per PR-boundary trigger: 1. per-cell word budget (≤50 words / table cell) 2. per-file line budget (architecture 350, api-reference 600, configuration 200, deployment 200; <!-- doc-allow-large --> opt-out) 3. implementation-prose detection (must/shall heuristics → suggest moving to sdd/) 4. lane-violation detection + pattern 13 (dual-narrative ADRs) Trigger language switched from "after every push" to PR-boundary (gh pr create OR open PR detected via gh pr view). Sibling rule file documentation-discipline.md referenced explicitly. Refs #251. * docs(skill): /sdd init template doc-discipline directives (#253) Adds template-conventions section to SKILL.md describing one-line table cells, embedded doc-discipline directive comments, per-file budgets, lane separation, and pre-wired REQ backlinks. Embeds <!-- doc-discipline: ... --> comments at the top of the architecture, api-reference, configuration, and deployment templates so the user editing the file sees the budget and conventions before they expand sections. Refs #253. * feat(hooks): warn-direct-push-to-shared.sh non-blocking warning New PostToolUse hook that informs the user when they push directly to a protected branch (default: main, master). Direct pushes bypass the PR-boundary trigger that gates the SDD review pipeline. Reads sdd_review.protected_branches and sdd_review.warn_on_direct_push from sdd/config.yml. Emits additionalContext only — never blocks the push. Skips silently if the branch already has an open PR (review will fire) or if warn_on_direct_push is disabled. Pushes to develop are intentionally NOT warned about — the expected workflow is feature → PR → develop → PR → main, and develop pushes get caught by the develop→main PR. Fail-safe: any unexpected error → exit 0. * feat(hooks): git-push-review-reminder PR-aware detection Switches from per-push trigger to per-PR-boundary trigger: - gh pr create → PR-OPEN trigger (always fires review pipeline) - git push to a branch with an open PR → PR-SYNC trigger (fires) - git push to a branch with no open PR → DEFERRED (skip silently; review fires when the PR opens later) gh pr view results cached at .git/sdd-pr-cache (60s TTL) so rapid pushes don't hammer the GitHub API. Updates the directive's diff-fetch hint to use the PR base ref (gh pr view --json baseRefName) instead of always assuming origin/main. Cuts the cost model from per-push (~1264 review spawns/session in the worst case observed) to per-PR (~50-100 spawns/session for the same coverage). * feat(hooks): enforce-review-spawn v5 — PR HEAD SHA checkpoint Migrates the Stop hook from v4 (timestamp checkpoint at .git/sdd-last-ack-push) to v5 (PR HEAD SHA checkpoint at .git/sdd-last-ack-pr-head). PR-boundary trigger semantics: - No open PR for current branch → exit 0 (deferred; review fires when PR opens, handled by git-push-review-reminder) - Open PR + CURRENT_PR_HEAD == LAST_ACK → exit 0 (already reviewed at this PR state) - Open PR + CURRENT_PR_HEAD != LAST_ACK → enforce: require code-reviewer + spec-reviewer (parallel) + doc-updater (after spec) spawned with timestamps after the candidate push line Migration: deletes the legacy v4 checkpoint file on first v5 run. Keeps: - Vibe-coding gate (sdd/README.md must exist) - Three USER-ONLY bypasses (sentinel, magic phrase, 3-strike circuit breaker — circuit breaker now keyed by PR HEAD SHA instead of push timestamp) - Reflog mention as documentation reference (PR HEAD SHA is a stricter unfakeable signal than reflog) * fix(hooks): address code-reviewer findings on PR-aware hooks git-push-review-reminder.sh: - Switch from set -e to set +e for fail-safe parity with the other hooks (any unexpected error → exit 0 instead of locking the user out) - INPUT read becomes tolerant via 2>/dev/null || exit 0 - Distinguish "definitely no PR" (gh exit 1, empty output) from "transient gh failure" — only cache trustworthy results so a network blip doesn't mask 60s of legitimate review triggers warn-direct-push-to-shared.sh: - YAML parser now correctly distinguishes top-level keys (column 0) from indented keys (no longer prematurely exits the sdd_review: block on a nested field) - Added multi-line list form support for protected_branches: protected_branches: - main - master alongside the existing inline form [main, master] * docs(preseed): agent prompts and git-workflow PR-boundary semantics spec-reviewer.md: - Trigger language switched from "after every push" to PR-boundary semantics (PR open OR push to branch with open PR) - Phase 2 checks 13/14/15 added: pattern 11 (run-on AC bullets), pattern 12 (mechanism leakage in ACs), pattern 14 (changelog drift) code-reviewer.md: - Trigger language switched to PR-boundary - Diff resolution uses gh pr view --json baseRefName so feature branches PR'd into develop diff against develop, not main git-workflow.md (rules/common/): - Replaces "Pre-Push" section with PR-boundary trigger table - Documents the recommended feature → develop → main workflow - Clarifies direct push to develop is fine (caught by develop→main PR); direct push to main surfaces a non-blocking warning - New section explaining warn-direct-push-to-shared.sh behavior * spec(agents): PR-boundary trigger semantics + sdd_review config sdd/agents.md: - REQ-AGENT-021 AC#4 rewritten — PR-boundary trigger semantics (PR open OR push to branch with open PR), direct-push to protected_branches surfaces warn-direct-push-to-shared.sh, warn_on_direct_push toggle, vibe-coding mode unchanged - REQ-AGENT-005 AC#4 — hook list expanded with the new warn-direct-push-to-shared.sh PostToolUse entry alongside the PR-boundary classifier, Stop entry for enforce-review-spawn v5 sdd/config.yml: - New sdd_review section with protected_branches: [main, master] and warn_on_direct_push: true sdd/changes.md: - 2026-05-03 entry summarizing the workflow shift entrypoint.sh: - SETTINGS_CONFIG PostToolUse array now registers two hooks (git-push-review-reminder + warn-direct-push-to-shared) preseed/agents/claude/manifest.json: - Adds warn-direct-push-to-shared.sh and documentation-discipline.md with modes: ["advanced"] * build: regenerate agent-seed for workflow-upgrade Picks up: - New rules/documentation-discipline.md - Updated rules/spec-discipline.md (patterns 11/12/14) - Updated rules/common/git-workflow.md (PR-boundary semantics) - Updated agents/{spec-reviewer,doc-updater,code-reviewer}.md - New plugins/codeflare-hooks/scripts/warn-direct-push-to-shared.sh - Updated git-push-review-reminder.sh + enforce-review-spawn.sh - Skill template directives (architecture/api-reference/configuration/ deployment templates and SKILL.md template-conventions section) Run `node scripts/generate-agent-seed.mjs` reproduces this file. * docs: calibration pass against new doc-discipline rules Findings from doc-updater's survey against the new documentation-discipline.md: HIGH (addressed): - documentation/decisions/README.md (517 lines, 44 ADRs in one file) → opt-out comment with rationale (splitting would break inbound AD-N references throughout the codebase) - documentation/authentication.md (909 lines, 3.6x default budget) → opt-out comment with rationale (auth/billing cross-references too dense to split cleanly today) MEDIUM (addressed): - documentation/architecture.md (581 lines, 1.66x of 350) → opt-out comment with TWO follow-ups noted: (1) move Container DO internal-method docs to container.md, (2) move Backend Libraries error-class status-code mapping to api-reference.md - token-scopes.md missing from documentation/README.md routing table → added as "Token Scopes" entry (Operators audience) - ADR count in routing table corrected from 42 to 44 LOW deferred: - security.md (306 lines), mobile.md (282 lines), memory.md (246 lines) — within LOW tier of soft budget, no action this pass - Missing inline (REQ-X-N) backlinks in architecture.md → follow-up sweep * fix(hooks): code-reviewer findings on git-push-review-reminder MEDIUM — asymmetric cache TTL. gh exits 1 both for "no PR found" AND for transient errors (network, rate limit, auth lapse) — indistinguishable from the script. Cache the result either way to avoid hammering gh, but expire negative (empty) results after 10s while keeping positive (OPEN) results for the full 60s. Bounds the worst-case window where a transient gh failure suppresses PR-SYNC reminders. The Stop hook still re-checks gh pr view at turn end, so the worst case remains a brief window of missing silent-spawn directives — never a missed enforcement. LOW — diff directive uses bare branch name. gh pr view --json baseRefName -q .baseRefName returns the bare branch name ("develop") not "origin/develop". Fresh clones / CI runners may not have the base branch as a local ref. Directive now emits 'git diff origin/$(gh pr view ...)...HEAD' so the diff target resolves to a remote-tracking ref. Regenerated agent-seed to pick up the hook content. * refactor: drop warn-direct-push hook; lean on branch protection The warn-direct-push-to-shared.sh hook + sdd_review config section were over-engineered. They tried to compensate at the hook layer for something the upstream platform already enforces (GitHub branch protection: require PR before merge). The hook fired AFTER the push, couldn't prevent anything, and was nagware on the rare deliberate direct-to-main flows that are exactly its target audience. Changes: - Delete warn-direct-push-to-shared.sh - Drop sdd_review section (protected_branches, warn_on_direct_push) from sdd/config.yml — universal hardcoded list (main, master) is fine, no need for project-level config - Drop manifest entry + entrypoint.sh PostToolUse registration - REQ-AGENT-021 AC#4: defer direct-push-to-main bypass to GitHub branch protection rather than describing a hook-level workaround - REQ-AGENT-005 AC#4: hook list reduced (one PostToolUse, one Stop) - 2026-05-03 changelog entry rewritten to match - git-workflow.md: new "Branch protection on main" section instructing the agent to PROACTIVELY surface branch protection during CI setup (don't wait for the user to ask), with concrete gh api command and recommended branch-protection.json fields Backstop for the case where the user opts out of branch protection (their workflow choice): on direct push to main/master with no open PR, git-push-review-reminder.sh emits an informational directive that asks the agent to offer manual verification ONCE — never auto-spawn. The user has agency; the agent asks once, respects the answer. Test scaffold updated: removes the deleted-feature assertions and adds new ones for the branch-protection guidance and the ask-once-don't-auto-spawn discipline. * fix(hooks): gate ask-once directive on definitive PR-state answer Code-reviewer LOW finding: when gh is unavailable AND the cache is empty/expired, PR_STATE stays empty and the script would fall into the *) arm of the case statement, emitting the ask-once directive on main/master even though we never confirmed the absence of a PR. Add an early exit when neither cache nor gh produced a definitive answer. The Stop hook re-checks at turn end, so a real PR push still gets caught — the worst case is a brief window of missed silent directives, not a missed enforcement. * fix(hooks): drop ask-once directive on direct-push-to-main Misread your earlier message: "user has to trigger verification manually" meant the user invokes reviews themselves, not the agent prompting them via a hook directive. The case-3 ask-once was a nag-warning in different clothing. Removed: - The case-3 emission block in git-push-review-reminder.sh - The matching "ask the user" prose in git-workflow.md - The CACHE_VALID/GH_OK transient-failure guard (now unused — the hook just exits silently on the deferred path) - Test assertions for the directive that no longer fires Behavior now: - Direct push to main with no PR → hook exits silently - User wants reviews? They invoke the agents manually - Branch protection (recommended) prevents this scenario entirely PostToolUse hook fires only on (1) gh pr create, (2) push to branch with open PR. Stop hook fires only when current branch has an open PR with un-acked HEAD. Symmetric and minimal. * docs(preseed): pattern 15 (big-O jargon) — issue #252 extension Missed in the original sweep. Pattern 15 was in the issue extension comments. Adding to documentation-discipline.md alongside the forbidden-content row and as a named pattern with detection signals and fix guidance. - Forbidden content table row: big-O notation + plain-language complexity nouns (logarithmic time, amortized constant, etc.) - Pattern 15 section: detection regex (O\(...\) in prose, plain- language complexity terms as load-bearing nouns, hand-wavy claims with no measurable backing); fix paths (target number from REQ, plain English, or delete filler); MEDIUM severity - Test scaffold updated to assert pattern 15 presence --------- Co-authored-by: Nikola Novoselec <nikolanovoselec@users.noreply.github.com>
CI failure on PR #264 (test: agent-seed-ecc-rules.test.ts:111). The "non-memory codeflare rules have default+advanced modes" assertion expected every rule directly under .claude/rules/ to be in both default and advanced modes; documentation-discipline.md (added on the workflow-upgrade branch) is intentionally advanced-only — sibling to spec-discipline.md, same Pro-mode SDD workflow gate. - Add the rule to ADVANCED_ONLY_CODEFLARE_RULES exemption list - Add a parallel "documentation-discipline rule is advanced-only" assertion mirroring the existing memory + spec-discipline tests - ECC count of 19 unaffected (file is in codeflareRules, not eccRules)
Trivy scan on the integration deploy of develop@f5e1769 flagged: - CVE-2026-4878 (libcap2 1:2.66-4+deb12u2+b2): TOCTOU privilege escalation in cap_set_file(). Container-init-only library; no application code path passes untrusted paths. - CVE-2026-33845 (libgnutls30 3.7.9-2+deb12u6): DTLS DoS via zero-length fragment. No DTLS/UDP TLS service exposed. - CVE-2026-35386 (openssh-client 1:9.2p1-2+deb12u9): shell metacharacter command injection via username. Codeflare uses git-over-HTTPS exclusively, so openssh-client binary is unused. All three are Debian bookworm system libs with no fix available upstream yet. Suppressions follow existing .trivyignore pattern with rationale comments. Review monthly and remove when patches land.
…er prompt tune
Fixes 9 issues surfaced during integration testing of the v4→v5 SDD
review pipeline migration, plus a code-reviewer prompt tune.
enforce-review-spawn.sh:
- Local short-circuit before gh pr view: compare $LAST_ACK_PR_HEAD
against git rev-parse @{u} (cheap, no network) and exit 0 when they
match. Saves a 200-500ms gh round-trip on every Stop event during
the post-review tail of a session.
- Tighten PUSH_LINE awk: structural match on the .input.command field
with shell-separator awareness instead of substring grep on the
whole line. No longer false-positives on echo "... git push ...".
- Add explicit $PUSH_TS validity check so transcript-schema drift
fails closed (exit 0 — consistent with rest of hook) instead of
silently disabling enforcement via awk's ts > '' string semantics.
- Shorten both REASON= block messages to ~180 chars (down from ~580),
preserve user-bypass instructions, drop the 'do not create
sentinel yourself' boilerplate (already in spec-discipline.md).
git-push-review-reminder.sh:
- Rewrite cache-gate comment to accurately describe what the code
does: legitimate gh results (exit 0 with PR_STATE OR exit 1 = no
PR) get cached; transient failures (exit 2/4 = network/auth) skip
the cache and re-query. The asymmetric TTL bounds the staleness of
legitimate-empty results, not transient failures.
code-reviewer.md (new prompt sections):
- Shell Scripts and Comments (HIGH): comment-as-claim audit, empty-
input walk, substring-vs-structural matching, error-swallowing,
external-tool guards. Two BAD/GOOD examples pulled from the exact
bugs this commit fixes.
- Test Quality (MEDIUM): negative-only assertion pairing, brittle
regexes against rendered content, sequential numbering integrity,
tautology/skipped tests. BAD/GOOD example for doesNotMatch pairing.
doc-updater.md:
- Pseudocode bracket fix: ']' → '; fi' (line 133).
host/__tests__/sdd-workflow-upgrade.test.js:
- Replace brittle /file\.md.*350/ regex with decoupled name-and-budget
assertions that survive table reformatting.
- Pair both standalone doesNotMatch with positive companions: assert
the trigger language IS PR-boundary, assert the no-PR path actually
exits 0 (not just absence of forbidden phrases).
- Renumber section comments 8-14 → 7-13 to close missing-7 gap.
Adds preseed/agents/claude/rules/tdd-discipline.md as the third sibling
of the spec/docs/tests discipline triad (spec-discipline.md and
documentation-discipline.md being the others). Defines what counts as
a real test, using concrete antipattern examples drawn from an audit
of this codebase: text-matching theater, tautology, mock-only theater,
implementation-coupled call counts, missing assertions, unjustified
skips, trivial-on-trivial assertions.
The single gut-check rule: 'If I delete or break the implementation
this test is supposed to cover, will the test fail?' If no, the test
is theater and must be replaced.
Applied immediately:
- Replaces host/__tests__/sdd-workflow-upgrade.test.js (416 lines,
100 percent text-matching theater, zero behavior coverage) with
two real fixture-driven test files:
* host/__tests__/enforce-review-spawn.test.js spawns the Stop hook
against fixture transcripts + a fake gh binary, asserts on exit
code and stdout. Includes regression tests pinning the PUSH_TS
empty-string fail-open fix and the PUSH_LINE substring false-
positive fix shipped in b62e6db.
* host/__tests__/git-push-review-reminder.test.js spawns the
PostToolUse hook with stdin command JSON, asserts on
additionalContext directive shape and cache behavior.
- Extends code-reviewer prompt Test Quality section to flag text-
matching theater, tautology, mock-only, call-count-without-output
at HIGH severity. Defers the full rule body to tdd-discipline.md.
- Updates spec-discipline.md to reference both sibling files
(documentation-discipline + tdd-discipline) as the discipline triad.
- Adds rules/tdd-discipline.md to manifest with default+advanced modes
(universal — applies to vibe-coding mode as well, unlike
spec-discipline which is advanced-only).
Migration policy: existing antipattern tests get migrated as the
surrounding production code changes, not rewritten speculatively.
The 416-line text-matching file was the egregious anchor; the rest
of the suite gets cleaned up incrementally as touched.
…in /sdd help Per-test opt-outs are agent-writable bypasses — same failure class as sentinel files. An agent can write '// tdd-allow: existing pattern' in its own output and route around the rule. Removed from both tdd-discipline.md and code-reviewer.md. The only TDD lever is now project-level: enforce_tdd in sdd/config.yml (true by default). If a test can't fit the discipline, delete it. Also surfaces the three-sibling discipline triad in /sdd's help screen and Reference section so a user typing /sdd with no args sees that spec / docs / tests have parallel discipline rules with parallel enforcement (spec-reviewer / doc-updater / code-reviewer).
Tighten the no-args help screen so a user typing /sdd sees a real CLI-style description, not a long markdown document. Structure follows the conventions of git/gh/npm help output: - Header with one-line summary - USAGE block showing the call shape - SUBCOMMANDS table with one-line descriptions - AUTONOMY MODES, AUTO-RUN, CONFIG, FILES, DISCIPLINE TRIAD, EXAMPLES, LEARN MORE — each scannable, no walls of prose - Aligned columns throughout Same content, professional shape — about 80 lines, scannable in one screen, examples grouped at the bottom where users look for them in real CLI tools.
Adds a new 'Operational requirements for the Stop hook' subsection to
spec-discipline.md (advanced-only, loaded in pro mode) covering:
- Upstream tracking is needed for the cheap @{u} short-circuit and
for git push to record an 'update by push' reflog entry.
- A vanilla 'git clone https://github.com/owner/repo' sets this up;
cloning with -b <branch> + later switching branches breaks it.
- One-line repair: 'git branch --set-upstream-to=origin/<branch>'.
- Hook also needs gh on PATH and sdd/README.md present.
Adds a sibling pointer in the hook script's preamble so the on-call
reader landing in the script source finds the rule reference.
Surfaced after a v4 silent-failure observed in a session where the
clone was 'git clone -b workflow-upgrade --depth 50' followed by
'git checkout -B develop origin/develop' (no upstream tracking) —
the v4 reflog dependency mis-fired. v5 (live after next deploy) is
robust against this via gh pr view, but the operational footnote
explains why and how to repair the local state if needed.
Closes the substring false-positive bug class in the PostToolUse hook classifier. The cheap raw-input pre-filter stays loose (intentional — it short-circuits non-candidate commands), but the authoritative $COMMAND classifier now uses an anchored regex that requires 'git push' / 'gh pr create' to appear at the start of the command or after a shell separator (;&|). Failure mode this fixes: 'git commit -m "... git push ..."' would emit a spurious PR-SYNC directive because the commit message body contained the substring. Observed during this session every time a commit message referenced git push semantically. This is the same class as the awk PUSH_LINE bug fixed in b62e6db, ported to bash [[ =~ ]] for the case classifier. Adds three regression tests covering: - git commit with 'git push' in the message body - echo with 'git push' in the argument - 'git pushy' / 'git push-X' tokens
Addresses code-reviewer (3 HIGH, 4 MEDIUM), spec-reviewer (1 INFO), and doc-updater (2 MEDIUM, 2 LOW) findings on the PR #264 review. Plus a doc category-error fix flagged separately. Hooks (enforce-review-spawn.sh, git-push-review-reminder.sh): - H1: cheap @{u} pre-check now also requires HEAD == @{u} and an ack-file mtime within 5 minutes. Closes the force-push and git-reset-hard fail-open class where @{u} happens to match the acked SHA but local divergence or stale fetch hides a real un-acked PR HEAD upstream. - M1: cache file write in git-push-review-reminder is now atomic (mktemp + mv). Two concurrent hook invocations on a chained- pipeline turn no longer race to a partial 1-line cache file. - spec-reviewer F3: both hooks now carry 'Implements REQ-AGENT-007' and 'Implements REQ-AGENT-021' annotations so the source-vs-test coverage check has anchor points when enforce_tdd flips on. Tests (host/__tests__/): - H2: gh fixtures pinned to exact CLI shape with stderr+exit-99 on unexpected args. Future refactors that change the CLI shape surface loudly instead of silently passing. - H3: new 'cheap path' test uses a poison-gh that exits 99 if invoked, with @{u} pre-configured, asserting the gh round-trip is actually short-circuited (was previously path-ambiguous). - New 'force-push guard' test for the H1 fix: HEAD ahead of @{u} must fall through to gh, even when @{u} matches the ack. - M2: 3-strike circuit breaker + v4-to-v5 migration tests added. Discipline triad scope: - tdd-discipline.md is now advanced-only (matches spec-discipline and documentation-discipline). Default-mode users are vibe- coding; forcing rigorous TDD on them is friction. The terse Test Quality section in code-reviewer.md remains in default mode for the no-egregious-theater bar. - M3: documentation-discipline Pattern 15 (Big-O jargon) now flags inline backticks too — wrapping in backticks is not a loophole, the rule is supposed to make writers rewrite. - M4: spec-discipline Pattern 11 (run-on AC bullets) drops the '5+ ands' check (false-positive on enumerations like 'CSV, TSV, JSON, XML, YAML, and Parquet'). Detects via word count or 3+ semicolons-not-in-enumeration only. Documentation restructure: - Extracts Session Modes, Preseed System, Multi-Agent Preseed, Settings.json Merge, and Plugin Enablement from memory.md into a new documentation/preseed.md. Memory.md was the wrong home — those sections describe the agent-config pipeline, not the MCP memory server. - Memory.md slims from 248 to 136 lines, scope tightens to MCP memory + capture/compact + R2 sync of memory files. - documentation/README.md and documentation/container.md split their index/related-docs entries to reference both files. - doc-updater MEDIUM-1, MEDIUM-2, LOW-1, LOW-2 (stale rule counts, stale trigger model, manifest-total-entries, per- mode counts) all addressed in preseed.md with the corrected numbers; memory.md no longer carries those facts. Deferred (not in this PR): - code-reviewer L1: claim 'removed in 2026-05' was correct; reviewer misread the diff. The deletion lives in 6df52db. - code-reviewer L2: shared gh-pr-state helper. Tracked as follow-up; the two hooks have legitimately different cache semantics so unification might force-fit. - spec-reviewer F1+F2: pre-existing mechanism leakage in REQ-AGENT-005 — out of scope for this PR per migration policy. Tracked for /sdd clean.
…te helper Addresses every finding from the b8f682d follow-up review pass plus task #14 (extract shared gh-pr-state helper). code-reviewer findings (1 HIGH, 2 MEDIUM, 1 LOW): - HIGH: 239-word troubleshooting bullet in documentation/preseed.md exceeded the 40-word per-list-item budget that documentation- discipline.md defines. Extracted to a 'Resetting the review-spawn checkpoint' subsection. Same finding flagged by doc-updater (MEDIUM-1). - MEDIUM: 5-min ack-mtime branch of the H1 cheap-path fix was untested. Added a test that backdates the ack file 10 minutes via utimesSync and asserts the cheap path falls through to gh. - MEDIUM: spec-discipline.md operational-requirements section still claimed the v5 hook depends on 'update by push' reflog entries. Rewrote to describe the actual v5 truth signal (gh pr view) and reframe the @{u} requirement as a cheap-path optimization rather than a hard dependency. - LOW: documented the magic-phrase ordering constraint (only scans messages AFTER the push) in the bypass-2 comment block. doc-updater findings (3 MEDIUM, 1 LOW actionable): - MEDIUM-1: same as code-reviewer HIGH — addressed. - MEDIUM-2: documentation/memory.md title still said 'Memory & Preseed' after the slim-down. Now reads 'Memory'. - MEDIUM-3: documentation/preseed.md was missing the standard Audience tag. Added 'Audience: Developers'. - LOW-1: preseed.md line budget (314, soft cap 250) — recovered ~13 lines via the HIGH bullet extraction. Now 327 due to the expanded subsection but still in LOW tier (250-400). Defer further trimming to /sdd clean if it grows. spec-reviewer findings (4 HIGH count drift, 2 MEDIUM): - Spec REQs carried hardcoded counts (74 entries, 184 docs, 180 advanced files, 25 default files, per-agent doc table) that drift on every preseed change. Per spec-discipline.md these are mechanism leakage that belong in documentation/, not in REQ acceptance criteria. Replaced the counts with qualitative descriptions: * REQ-AGENT-005 content table: kept categorical rows, removed specific file counts and enumerations of names. * REQ-AGENT-005 AC1+AC2: 'seeds the rows above marked Yes' instead of magic numbers. * REQ-AGENT-006 AC6: 'output for all supported agents' instead of '184 documents'. * REQ-AGENT-007: dropped the per-agent count table, replaced with the strict-superset constraint. * REQ-AGENT-014 AC2: 'organizes by type' instead of 74-entry breakdown. Adding a new rule, hook, or skill no longer requires REQ edits — the spec is decoupled from the manifest's exact size. - MEDIUM-6: hook annotations were 'Implements REQ-AGENT-007' (multi-agent adaptation, doesn't fit — hooks are CC-only). Replaced with REQ-AGENT-004 (Pro mode opt-in) which is the correct intent gate. REQ-AGENT-021 annotation kept. Task #14 — shared gh-pr-state helper: - New preseed/agents/claude/plugins/codeflare-hooks/scripts/lib/ gh-pr-state.sh with a single gh_pr_state(branch) function. - Both hooks now source it. CLI shape is unified ('gh pr view <branch> --json state,headRefOid'); test fixtures pin the same exact-match args via fakeGh. - Manifest entry added; agent-seed regen wires it in (advanced- only, same modes as the other hook scripts). - Cache file content unchanged; cache semantics still per-hook. Documentation/preseed.md counts updated for the helper addition (76 → 77 manifest entries, 186 → 187 generated docs, 183 → 184 advanced-mode files). These counts are allowed in documentation/ (implementation specifics are the documentation/ lane) — the removal applies only to sdd/.
… test, remove residual count drift Addresses the two MEDIUM findings from the third code-reviewer pass. Test assertion strengthened (host/__tests__/enforce-review-spawn.test.js): - The 'stale ack file (>5 min old) → falls through to gh' test previously relied on 'assert.doesNotMatch(r.stderr, /FAKE_GH_UNEXPECTED_ARGS/)' which is also true when gh is never called at all (cheap path silent short-circuit). A future regression that re-enables the cheap path on stale ack would NOT have failed this test. - Inlined a custom fakeGh that writes a marker file when invoked. The test now asserts existsSync(markerFile) === true, which is unfakeable: the marker only exists if gh actually ran. Cheap-path silent short-circuit would leave the marker missing and the test would fail loudly. Residual count drift (3 files in sdd/): - sdd/agents.md:11 (Key Concepts table) — Session Mode entry no longer hardcodes '25 preseed files / 180 preseed files'. - sdd/memory.md:171 (REQ-MEM AC bullet) — replaced bare counts with a qualitative 'strict superset' description naming the Pro-only delta categorically. - sdd/storage.md:258 (REQ-STOR AC bullet) — same treatment. - documentation/preseed.md still carries the snapshot counts (77 entries, 187 docs, 184 advanced) — implementation specifics belong in documentation/ per documentation-discipline.md, so those are kept and updated as the manifest changes.
Closes 9 findings from the final semantic review: MEDIUM - Document DRAFT-PR semantic in git-push-review-reminder.sh and spec-discipline.md — drafts trigger review fully (gh pr view returns state=OPEN). Users wanting review-free WIP defer the PR open or use a per-push USER bypass. LOW (polish + symmetry) - Drop non-sequential 'Pattern 11/12/13/14/15' numbering from spec-discipline.md and documentation-discipline.md. Patterns now identified by name only — clearer and grep-stable. Update spec-reviewer.md and doc-updater.md to match. - Broaden documentation-discipline Pass 1 from 'per-cell only' to 'per-element' so it also enforces the list-item, code-snippet, heading-nesting and paragraph-length caps already listed in the budgets table (previously documented but unenforced). - Document known under-block conditions in enforce-review-spawn.sh header and spec-discipline.md operational requirements section: web-UI driven PR HEAD changes, spec-reviewer subagent failure, transcript rotation. All three are deliberate fail-safe trade-offs (under-block over lock-out). - Clarify '/sdd autonomous off' resets from auto OR unleashed in the /sdd help screen; add 'unleashed off' as an alias. - Add BYPASSING REVIEW section to /sdd help surfacing the three USER-only bypasses (sentinel, magic phrase, 3-strike) so users who hit a misfire don't have to grep rule files. Reinforces the hard rule that agents must NEVER use these — hook misfires get fixed in code, not bypassed inline. Regenerated src/lib/agent-seed.generated.ts after preseed edits.
Closes the single LOW finding from the doc-updater pass on bd38e42: preseed.md is 327 lines vs the 250-line soft budget for 'Other files'. The file is dense reference material (manifest structure, per-agent document counts, hook script roles, deployment paths, troubleshooting recipes) that benefits from living in one navigable file. The opt-out comment carries the rationale per documentation-discipline guidance.
Two cosmetic LOWs remained from the bd38e42 review: 1. spec-reviewer LOW: REQ-AGENT-005 length (36 lines) above the 25-line warn threshold. The 11-row Standard/Pro content matrix IS the contract; splitting would fragment a single decision. Added <!-- sdd-allow-large --> opt-out with rationale. 2. code-reviewer LOW: wording asymmetry between spec-discipline.md (separate Note paragraph for the enumeration disclaimer) and spec-reviewer.md item #13 (inline disclaimer). Canonicalized to use the same 'Note:' lead-in inline.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Develop → main release. Three themes plus operational follow-ups.
SDD framework (workflow-upgrade, #263)
documentation-discipline.mdnew always-loaded sibling rule (alongsidespec-discipline.md) enforced by doc-updater: forbidden content, per-file budgets (architecture 350 / api-reference 600 / configuration 200 / deployment 200), per-element caps for table cells / list items / code snippets / heading nesting / single paragraphs, lane separation, four enforcement passes. Plus named patterns: run-on AC bullets, mechanism leakage in ACs, dual-narrative ADRs, changelog drift, big-O jargon. Pattern numbering was dropped in the final pass — patterns are now identified by name (clearer, grep-stable).tdd-discipline.mdthird sibling rule (advanced-only) with the gut-check question "If I delete or break the implementation, will this test fail?" Defines 7 antipatterns drawn from a real audit of this codebase: text-matching theater, tautology, mock-only theater, implementation-coupled call counts, empty body, skipped without justification, trivial assertions on trivial values. No per-test opt-out (agent-writable bypasses defeat the rule); onlyenforce_tdd: true|falseinsdd/config.yml./sdd inittemplate polish: SKILL.md template-conventions section +<!-- doc-discipline: ... -->directives embedded in architecture/api-reference/configuration/deployment templates +<!-- doc-allow-large -->escape hatch..git/sdd-last-ack-pr-head(legacy v4 timestamp checkpoint auto-deleted on first run). Cheap-path optimization requires HEAD == @{u} AND ack mtime <5 min (closes force-push fail-open). PUSH_TS empty bails (closes awk fail-open). Anchored regex on the PUSH_LINE detector (closes substring false-positives in commit messages and echoed strings).lib/gh-pr-state.shhelper sourced by both hooks. Anchored regex on the PostToolUse classifier mirroring the awk fix in the Stop hook./sddhelp screen rewrite: professional CLI output — USAGE, SUBCOMMANDS, AUTONOMY MODES, AUTO-RUN, CONFIG, FILES, DISCIPLINE TRIAD, BYPASSING REVIEW, EXAMPLES, LEARN MORE.documentation/memory.mdinto a newdocumentation/preseed.md(right lane). Memory.md slimmed from 248→140 lines. Cross-references and deeplinks updated across documentation/.documentation/preseed.md, not in REQs.spec-discipline.md: upstream tracking required for cheap-path optimization, the three known under-block conditions (web-UI driven PR HEAD changes, spec-reviewer subagent failure, transcript rotation) — all fail-safe trade-offs.gh pr viewreturnsstate=OPENfor drafts, so review fires fully on every push. Users wanting review-free WIP defer the PR open or use a per-push USER bypass.code-reviewer.mddiff resolution usesgh pr view --json baseRefNameso feature branches PR'd into develop diff against develop, not main.git-workflow.mdinstructs agents to proactively surface GitHub branch protection during CI setup with a concretegh apicommand.documentation/:<!-- doc-allow-large -->opt-outs on the 3 genuinely-overweight files with rationale,token-scopes.mdindexed indocumentation/README.md.Dependency bumps (Dependabot, all minor/patch on safe versions)
3 Dependabot PRs intentionally held: wrangler 4.81 → 4.86 (#254, cohort-pinned), typescript 5.9.3 → 6.0.3 (#259, major bump previously caused tsc hang), @cloudflare/vitest-pool-workers 0.14 → 0.15 (#260, cohort-pinned + 0.x minor is breaking).
Operational follow-ups landed directly on develop
documentation-discipline.mdto theADVANCED_ONLY_CODEFLARE_RULESexemption list inagent-seed-ecc-rules.test.ts..trivyignorewith rationale (CVE-2026-4878 libcap2 TOCTOU, CVE-2026-33845 libgnutls30 DTLS DoS, CVE-2026-35386 openssh-client shell metachar injection).Verification
Test plan after merge to main
.git/sdd-last-ack-pushis auto-deleted on first v5 invocation across user containersCloses #251
Closes #252
Closes #253