Skip to content

fix(orchestrator): parent-must-be-on-main guard in state check + loop tick (AISDLC-358)#528

Merged
deefactorial merged 7 commits into
mainfrom
ai-sdlc/aisdlc-358-fix-orchestrator-state-parent-must-be-on-main-guard
May 18, 2026
Merged

fix(orchestrator): parent-must-be-on-main guard in state check + loop tick (AISDLC-358)#528
deefactorial merged 7 commits into
mainfrom
ai-sdlc/aisdlc-358-fix-orchestrator-state-parent-must-be-on-main-guard

Conversation

@deefactorial
Copy link
Copy Markdown
Contributor

Summary

Pattern-C contract enforcement: parent worktree MUST be on main. Detects parent on stale feature branch and either auto-recovers (clean tree) or refuses (dirty tree). Prevents the silent-stale-main class of incident encountered today.

Changes

  • scripts/check-orchestrator-state.sh: pre-flight branch check via git symbolic-ref --short HEAD. Clean non-main → git checkout main && git reset --hard origin/main. Dirty non-main → refuse with explicit error naming branch + dirty paths + recovery command. Explicit error handling on checkout/reset failure (no silent 2>/dev/null swallowing).
  • pipeline-cli/src/orchestrator/loop.ts: runParentBranchGuard() + ParentNotOnMainError called at top of every runOrchestratorTick(), before frontier scan. Exit-code check on git checkout main prevents false "auto-recovered" success log when checkout fails.
  • Tests: 4 hermetic shell tests covering all 4 AC scenarios + 22 TS unit tests in loop.branch-guard.test.ts covering all 5 runParentBranchGuard branches + ParentNotOnMainError constructor truncation. parentBranchGuard: async () => {} no-op stub injected into all loop test adapters (removes accidental /tmp not a git repo dependency).
  • CLAUDE.md: Pattern C "Hard guards" subsection documenting the enforcement.

Reviewer findings addressed

3 code/test reviewer subagents flagged 5 majors total; all addressed in commits 7d96da0 + 9f3fd04:

  • Code Major 1 — silent shell checkout/reset failures with suppressed stderr → explicit error handling
  • Code Major 2 — TS auto-recovery silent success log on checkout failure → exit-code check + throw
  • Test Major 1 — runParentBranchGuard had zero TS unit tests → 22 new tests
  • Test Major 2 — ParentNotOnMainError untested → constructor tests including truncation path
  • Test Major 3 — existing loop tests didn't inject parentBranchGuard adapter → stubbed across 12 loop test files

Security reviewer: APPROVED clean (no exploitable surface; branch-name injection prevented by git's check-ref-format + execFile array-arg).

Test plan

  • Pre-tick guard fires on cli-orchestrator tick when parent is on stale feature branch (clean → auto-recover)
  • Guard refuses with clear error when parent is on stale branch + dirty tree
  • No regression on parent-on-main happy path
  • All 22 new unit tests + 4 new shell tests pass

🤖 Generated with Claude Code

@deefactorial deefactorial enabled auto-merge May 18, 2026 06:28
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 18, 2026

AI-SDLC: Reviewer Agents Skipped (Local Attestation Valid)

A valid DSSE attestation envelope was found at
.ai-sdlc/attestations/<HEAD-sha>.dsse.json for this commit. The 3 review
agents were already run locally via /ai-sdlc execute and the verdict was
cryptographically signed against:

  • Per-file content hash (contentHashV3)
  • Review policy hash
  • Reviewer agent file hashes
  • Plugin version

CI re-running the same 3 agents would produce the same verdict at the cost
of ~3 Anthropic API invocations. Per AISDLC-147 patch 1, we trust the local
attestation as a SOFT signal and skip the duplicate review.

Note: Attestation remains AUDIT-ONLY as a merge gate (per AISDLC-140 sub-4).
The re-actors/alls-green aggregator (ai-sdlc/pr-ready) is the single merge gate.

Posted by AI-SDLC Review Agents — AISDLC-147 attestation cost-saver

github-actions[bot]
github-actions Bot previously approved these changes May 18, 2026
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Auto-approved by valid local DSSE attestation (AISDLC-147 patch 1).

@deefactorial deefactorial added this pull request to the merge queue May 18, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 18, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 18, 2026
@deefactorial deefactorial force-pushed the ai-sdlc/aisdlc-358-fix-orchestrator-state-parent-must-be-on-main-guard branch from 7e9e30c to c865234 Compare May 18, 2026 07:03
@deefactorial deefactorial enabled auto-merge May 18, 2026 07:03
@deefactorial deefactorial disabled auto-merge May 18, 2026 07:03
@deefactorial deefactorial enabled auto-merge May 18, 2026 07:03
github-actions[bot]
github-actions Bot previously approved these changes May 18, 2026
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Auto-approved by valid local DSSE attestation (AISDLC-147 patch 1).

@deefactorial deefactorial added this pull request to the merge queue May 18, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 18, 2026
@deefactorial deefactorial force-pushed the ai-sdlc/aisdlc-358-fix-orchestrator-state-parent-must-be-on-main-guard branch from c865234 to 84acc7d Compare May 18, 2026 07:18
@deefactorial deefactorial enabled auto-merge May 18, 2026 07:19
@deefactorial deefactorial force-pushed the ai-sdlc/aisdlc-358-fix-orchestrator-state-parent-must-be-on-main-guard branch from 84acc7d to 8676a92 Compare May 18, 2026 07:22
@deefactorial deefactorial disabled auto-merge May 18, 2026 07:23
@deefactorial deefactorial enabled auto-merge May 18, 2026 07:23
github-actions[bot]
github-actions Bot previously approved these changes May 18, 2026
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Auto-approved by valid local DSSE attestation (AISDLC-147 patch 1).

@deefactorial deefactorial added this pull request to the merge queue May 18, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 18, 2026
@deefactorial deefactorial added this pull request to the merge queue May 18, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 18, 2026
@deefactorial deefactorial force-pushed the ai-sdlc/aisdlc-358-fix-orchestrator-state-parent-must-be-on-main-guard branch from 8676a92 to 04a7a71 Compare May 18, 2026 16:08
@deefactorial deefactorial enabled auto-merge May 18, 2026 16:08
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 18, 2026

AI-SDLC: Reviewer Agents Skipped (Anthropic Budget Exhausted)

3/3 review agents failed with HTTP 400 invalid_request_error
("credit balance is too low"). The remaining agent(s) either succeeded or were
skipped by the AISDLC-141 conditional classifier. Since every reviewer that
DIDN'T succeed only failed due to budget, the noisy CHANGES_REQUESTED has been
suppressed.

What this means:

  • This PR has been only partially reviewed by the automated agents.
  • Branch protection still requires ai-sdlc/pr-ready (the rollup gate),
    but the Post Review Results status was posted as success so the gate
    does not deadlock.
  • A human reviewer should manually validate this PR before merging,
    or top up the Anthropic API credit balance and push again to re-trigger.

Posted by AI-SDLC Review Agents — AISDLC-147 budget circuit breaker (AISDLC-157 broadened gate)

@deefactorial deefactorial force-pushed the ai-sdlc/aisdlc-358-fix-orchestrator-state-parent-must-be-on-main-guard branch from 04a7a71 to 1c429c1 Compare May 18, 2026 16:13
@deefactorial deefactorial force-pushed the ai-sdlc/aisdlc-358-fix-orchestrator-state-parent-must-be-on-main-guard branch from 1e1367f to b22f5d6 Compare May 18, 2026 17:39
@deefactorial deefactorial disabled auto-merge May 18, 2026 17:40
@deefactorial deefactorial enabled auto-merge May 18, 2026 17:40
github-actions[bot]
github-actions Bot previously approved these changes May 18, 2026
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Auto-approved by valid local DSSE attestation (AISDLC-147 patch 1).

@deefactorial deefactorial added this pull request to the merge queue May 18, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 18, 2026
@deefactorial deefactorial force-pushed the ai-sdlc/aisdlc-358-fix-orchestrator-state-parent-must-be-on-main-guard branch from b22f5d6 to 7e8d783 Compare May 18, 2026 17:59
@deefactorial deefactorial enabled auto-merge May 18, 2026 18:00
@deefactorial deefactorial disabled auto-merge May 18, 2026 18:06
@deefactorial deefactorial enabled auto-merge May 18, 2026 18:06
@deefactorial deefactorial force-pushed the ai-sdlc/aisdlc-358-fix-orchestrator-state-parent-must-be-on-main-guard branch from 7e8d783 to 391c4b1 Compare May 18, 2026 18:13
@deefactorial deefactorial disabled auto-merge May 18, 2026 18:14
@deefactorial deefactorial enabled auto-merge May 18, 2026 18:14
github-actions[bot]
github-actions Bot previously approved these changes May 18, 2026
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Auto-approved by valid local DSSE attestation (AISDLC-147 patch 1).

@deefactorial deefactorial added this pull request to the merge queue May 18, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 18, 2026
@deefactorial deefactorial added this pull request to the merge queue May 18, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 18, 2026
github-actions[bot]
github-actions Bot previously approved these changes May 18, 2026
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Auto-approved by valid local DSSE attestation (AISDLC-147 patch 1).

deefactorial and others added 5 commits May 18, 2026 12:58
… tick (AISDLC-358)

Augments check-orchestrator-state.sh with a pre-flight branch check (section 1a,
AISDLC-358): if the parent working tree is NOT on main, auto-recover when the
tree is clean (git checkout main + git reset --hard origin/main, log the
recovered branch), or REFUSE with exit 1 and a clear error (branch name + dirty
paths + recovery command) when the tree is dirty.

Wires the same logic into pipeline-cli/src/orchestrator/loop.ts as
runParentBranchGuard() + ParentNotOnMainError, called at the top of every
runOrchestratorTick() before the sweep or frontier scan. The implementation
resolves the parent root via git rev-parse --git-common-dir so it correctly
handles invocations from inside linked worktrees (returns early when not in a
git repo, making hermetic test setups safe without needing to inject a no-op
parentBranchGuard adapter).

Test coverage: extended check-orchestrator-state.test.mjs with 4 new hermetic
cases covering all four AC-specified scenarios (main+clean, main+dirty,
feature-branch+clean auto-recover, feature-branch+dirty refuse).

CLAUDE.md: added "Pattern C hard guards (AISDLC-358)" subsection documenting
the enforcement behavior and recovery steps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…dapters (AISDLC-358)

Add error handling for git checkout/reset failures in runParentBranchGuard()
and check-orchestrator-state.sh: propagate failures as ParentNotOnMainError
instead of silently continuing. Also add parentBranchGuard: async () => {} to
hermeticFilterAdapters() in loop.test.ts and loop.umbrella.test.ts so tests
are hermetic regardless of the git working tree context during coverage runs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…d (AISDLC-358)

- Tests: add loop.branch-guard.test.ts covering 5 runParentBranchGuard
  branches + checkout/reset failure cases + ParentNotOnMainError truncation
- Tests: inject parentBranchGuard no-op stub into all remaining loop test
  adapters (events, filters, rollback, resume, sweep, in-flight, blast-radius,
  dispatchability, chaos, playbook) to remove dependency on '/tmp not being
  a git repo'

Note: Code Major 1 (shell silent failure), Code Minor 1 (reset silent failure),
and Code Major 2 (TS false-success log) were addressed in the preceding commit
7d96da0 on this branch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rebase post-363 left dup parentBranchGuard keys in 3 test files
(both 358's fix-up and 363's fix-up added them to the same adapter
literals). Dedup keeps the 363 (newer) stub.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
github-actions[bot]
github-actions Bot previously approved these changes May 18, 2026
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Auto-approved by valid local DSSE attestation (AISDLC-147 patch 1).

deefactorial and others added 2 commits May 18, 2026 13:08
…LC-358)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Auto-approved by valid local DSSE attestation (AISDLC-147 patch 1).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant