Skip to content

feat: implement issue #1144 — [Phase 1] Spec-drift detector script + pure-classifier unit tests - #1224

Merged
don-petry merged 3 commits into
mainfrom
dev-lead/issue-1144-20260714-0430
Jul 14, 2026
Merged

feat: implement issue #1144 — [Phase 1] Spec-drift detector script + pure-classifier unit tests#1224
don-petry merged 3 commits into
mainfrom
dev-lead/issue-1144-20260714-0430

Conversation

@don-petry

Copy link
Copy Markdown
Collaborator

Closes #1144

Implemented by dev-lead agent. Please review.

Copilot AI review requested due to automatic review settings July 14, 2026 04:44
@don-petry
don-petry requested a review from a team as a code owner July 14, 2026 04:44
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@don-petry, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 57 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

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.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 23ea8623-be1e-4b43-b198-0d9ddb620b1b

📥 Commits

Reviewing files that changed from the base of the PR and between 1d262d1 and 103eb0b.

📒 Files selected for processing (3)
  • .github/workflows/lint.yml
  • scripts/spec-drift.sh
  • tests/test_spec_drift.bats
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev-lead/issue-1144-20260714-0430

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.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces scripts/spec-drift.sh, a deterministic spec-drift detector that compares merged PR diffs against a story's acceptance criteria to output a structured verdict (DRIFT, ALIGNED, or INDETERMINATE), along with a comprehensive BATS test suite in tests/test_spec_drift.bats. The review feedback recommends separating the local declaration from the command substitution for the now variable in spec-drift.sh to prevent masking exit codes (SC2155). Additionally, it is advised to create temporary directories within $BATS_TEST_TMPDIR with proper error handling in the test suite to ensure automatic cleanup and robust error recovery.

Comment thread scripts/spec-drift.sh Outdated
Comment thread tests/test_spec_drift.bats Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds the first-phase “spec drift” detector to the org CI tooling: a deterministic scripts/spec-drift.sh that compares a merged initiative PR diff against the source story’s acceptance criteria, emits a JSON verdict envelope, and includes bats coverage for the pure classifier path.

Changes:

  • Introduces scripts/spec-drift.sh with pure helpers (classifier + AC parsing + envelope) and an I/O main() that fetches story/PR data and calls run_triage from scripts/engine.sh.
  • Adds tests/test_spec_drift.bats to unit-test the pure helpers and exercise main() with mocked gh / run_triage.
  • Registers the new bats test in .github/workflows/lint.yml.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
scripts/spec-drift.sh New spec-drift detector script with pure classifier + I/O main() that fetches story ACs and PR diff and emits a JSON verdict.
tests/test_spec_drift.bats New bats tests covering the pure helpers and mocked-IO main() behavior (including inert no-ACs path).
.github/workflows/lint.yml Adds the new bats file to the lint workflow’s test list.

Comment thread scripts/spec-drift.sh
Comment thread scripts/spec-drift.sh
Comment thread scripts/spec-drift.sh
@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — review-changes (applied)

Changes committed and pushed.

@don-petry
don-petry enabled auto-merge (squash) July 14, 2026 04:53
@don-petry
don-petry disabled auto-merge July 14, 2026 04:57
@don-petry
don-petry enabled auto-merge (squash) July 14, 2026 05:01
@don-petry
don-petry disabled auto-merge July 14, 2026 05:02
@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — waiting on PR blockers (intent: fix-reviews)

PR: #1224
No changes were committed, but the PR still has blocking checks or reviews (failing or cancelled checks, or changes-requested reviews). The retry cron will re-attempt automatically. Next attempt after: 2026-07-14T05:36:51Z

@don-petry
don-petry enabled auto-merge (squash) July 14, 2026 05:06

@donpetry-bot donpetry-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Automated review — APPROVED ✓

Risk: MEDIUM
Reviewed commit: 103eb0bc2054b54cb7077004cab03e176560aae8
Review mode: triage-approved (single reviewer)

Summary

Adds scripts/spec-drift.sh (a spec-drift detector with a pure, unit-testable classifier and an I/O-only main()), 22 bats tests in tests/test_spec_drift.bats, and registers the test file in the lint.yml bats list. Implementation cleanly follows the pure-helper + main() split modeled on scripts/mcp_connectivity_check.sh. All 6 acceptance criteria of issue #1144 are satisfied. All 5 prior bot-review threads (2 gemini, 3 copilot) were addressed by follow-up commits and are resolved. CodeRabbit approved the head commit.

Linked issue analysis

Issue #1144 lists 6 ACs — all substantively addressed:

  1. Pure classifier (classify_drift) maps analysis to DRIFT / ALIGNED / INDETERMINATE with no network/LLM in the pure path ✓
  2. main() gathers the PR diff + story ACs and invokes the cheap tier via run_triage from scripts/engine.sh (lazy-sourced so pure helpers never load the engine) ✓
  3. Inert paths (no story, fetch failure, non-initiative story, no ACs, no PR, empty diff) all emit INDETERMINATE and exit 0 — never fabricates a verdict ✓
  4. Structured JSON verdict envelope via jq, with non-numeric pr/story safely rendered as null (try tonumber catch null) ✓
  5. bats tests cover DRIFT / ALIGNED / INDETERMINATE including the inert no-ACs path and main() with mocked gh + run_triage; test file registered in the lint.yml bats list per AGENTS.md ✓
  6. shellcheck passes (ShellCheck CI check green) ✓

Findings

No blocking findings.

  • Secret scan: run_secret_scanning MCP tool unavailable in this run; the gitleaks CI check passed (SUCCESS).
  • lint.yml change is a single-line bats-list registration — exactly the AGENTS.md-sanctioned edit; lint.yml is not one of the protected thin-caller stubs.
  • Non-blocking observation: classify_drift greps for the verdict token anywhere in the analysis (case-insensitive), and the PR diff is embedded in the LLM prompt, so a crafted diff could in principle steer the model toward ALIGNED. Impact is bounded: this is a post-merge detector, DRIFT wins when both tokens appear, absent/garbled output is INDETERMINATE, and per the story the detector is validated against a frozen eval before any workflow wiring. Worth revisiting in the Phase-2 eval story.
  • Prior review threads (local-declare masking, BATS_TEST_TMPDIR usage, tonumber hardening, run_triage stderr passthrough, empty-body fetch-failure messaging) are all fixed in the current head and resolved.

CI status

All checks green on head 103eb0b: ShellCheck, shellcheck, bats, unit-tests, Lint, CodeQL (actions + python), Secret scan (gitleaks), SonarCloud quality gate, agent-shield, Agent Security Scan, holdout-guard, template-drift, guard, validate-agent-profiles, validate-personas, gh-aw-compile — SUCCESS. Cancelled/skipped entries are dev-lead dispatch/ci-relay and conditional audit jobs from earlier pushes, not failures. Branch is BEHIND main but MERGEABLE.


Reviewed automatically by the PR-review agent (single-reviewer mode: fable 5). Reply if you need a human review.

@sonarqubecloud

Copy link
Copy Markdown

@don-petry
don-petry merged commit 994b130 into main Jul 14, 2026
30 checks passed
@don-petry
don-petry deleted the dev-lead/issue-1144-20260714-0430 branch July 14, 2026 06:03

@donpetry-bot donpetry-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Automated review — APPROVED ✓

Risk: MEDIUM
Reviewed commit: 505a7422b5a39deafa824d4f6632c651ad58b83a
Review mode: triage-approved (single reviewer)

Summary

Adds scripts/spec-drift.sh, a deterministic spec-drift detector for the initiative pipeline (issue #1144, epic #1142), with a clean pure-classifier/main() I/O split mirroring scripts/mcp_connectivity_check.sh, plus 18 bats tests registered in lint.yml. The pure helpers (classify_drift, parse_acceptance_criteria, story_is_initiative, drift_verdict_envelope) have no network/LLM dependency; main() resolves the story ACs and PR diff via gh, invokes the cheap triage tier through engine.sh, and emits a JSON verdict envelope. Fail-loud design: all unresolvable paths emit inert INDETERMINATE with exit 0 and distinct reasons, and DRIFT wins over ALIGNED when both tokens appear.

Linked issue analysis

Linked issue #1144 (closed) is substantively addressed on all 6 acceptance criteria: (1) pure unit-testable classifier with no network/LLM in the pure path; (2) main() gathers PR diff + story ACs and calls run_triage from engine.sh; (3) inert INDETERMINATE with exit 0 when ACs cannot be resolved, including a distinct reason for fetch failures vs non-initiative stories; (4) compact JSON verdict envelope via jq; (5) bats tests cover DRIFT/ALIGNED/INDETERMINATE plus the inert paths and are registered in the lint.yml bats list per AGENTS.md; (6) shellcheck passes in CI.

Findings

No blocking findings. Security: no secrets or credentials introduced (gitleaks CI green; run_secret_scanning MCP tool unavailable in this run — noted, not blocking); expansions are quoted, set -euo pipefail, mktemp used correctly, no eval/dynamic execution; the lint.yml change is a one-line additive test registration with no security-relevant workflow changes. Correctness: classify_drift fails toward DRIFT on ambiguous dual tokens; drift_verdict_envelope degrades non-numeric pr/story to JSON null (try tonumber catch null) preserving the inert contract; run_triage stderr is preserved to the script's own stderr. All 5 prior bot review threads (gemini SC2155 + BATS_TEST_TMPDIR, Copilot tonumber crash + stderr discard + misleading empty-body reason) were fixed, verified in follow-up replies, and are resolved. Risk is MEDIUM rather than triage's low call due to non-trivial new script logic, but this does not change the outcome.

CI status

All 30 checks green: shellcheck, bats (unit-tests), Lint, CodeQL (actions + python), SonarCloud, gitleaks secret scan, AgentShield, agent-profile/persona validation, template-drift, holdout-guard all SUCCESS; dependency-audit per-ecosystem jobs SKIPPED (no matching ecosystems).


Reviewed automatically by the PR-review agent (single-reviewer mode: fable 5). Reply if you need a human review.

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.

[Phase 1] Spec-drift detector script + pure-classifier unit tests

3 participants