Skip to content

fix: guard deterministic repair scope - #46

Open
miyaontherelay wants to merge 5 commits into
mainfrom
fix/repair-scope-guard-0825
Open

fix: guard deterministic repair scope#46
miyaontherelay wants to merge 5 commits into
mainfrom
fix/repair-scope-guard-0825

Conversation

@miyaontherelay

Copy link
Copy Markdown
Contributor

Summary

  • Add deterministic-step repairProtection.protectedPaths, resolved from the effective gate cwd.
  • Always protect the loaded workflow YAML and directly invoked local gate/custom-verification scripts.
  • Snapshot canonicalized protected paths before each repair, including node type, bytes, mode, and SHA-256; verify in one finally path and restore violations before failing the run.
  • Skip repair with loud evidence when local gate code is indirect or unresolved and no explicit protection is configured.

Execution paths covered

  • Injected executor: mutable-state repair is allowed; protected modification terminates the run.
  • API executor: protected deletion is detected and restored.
  • CLI executor: protected creation is detected and removed.
  • Canonical symlink resolution: a protected symlink swap is detected and restored.
  • Repair timeout/error: the common finally check still detects and restores mutations.
  • Environmental gate timeout/failure: the identical guard runs and a violation prevents any further repair or gate retry.
  • Automatic scope: loaded workflow YAML, direct local gate scripts, and direct custom-verification scripts are protected.
  • Unresolvable indirect gate code: repair is skipped loudly and only the gate is rerun.
  • Verified terminalSuccessExitCodes: existing terminal-success coverage confirms the completed-early result does not spawn repair.

A green suite proves the paths that have tests, and nothing else.

Verification

  • npm run typecheck
  • vitest run --no-file-parallelism --maxWorkers=1 --minWorkers=1 --retry=1 (66 files, 1,060 tests)

Session-Id: 01a03a38-b143-7000-84b5-2fc9c9c26f69
@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f6b2e970-d662-4648-ab14-c6b6ddc3ff5c


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.

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 11 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/core/src/repair-protection.ts Outdated
Comment thread packages/core/src/repair-protection.ts
Comment thread packages/core/src/runner.ts
Comment thread packages/core/src/custom-steps.ts
…s in the repair guard

Four review findings on the repair-scope guard, each with a regression test:
- a planted symlink cycle (ELOOP) now records a violation and restores instead
  of throwing past the restore path
- restoration rebuilds a real parent chain so a parent directory swapped for a
  symlink cannot redirect the restore to an external target
- interpreter eval modes resolve their nested command (bash -c scripts become
  protected paths) and fail closed when inline code references a local script
- custom-step resolution preserves the invoking step's cwd/workdir so
  repairProtection paths resolve against the gate's actual directory

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 5 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/core/src/repair-protection.ts
Comment thread packages/core/src/runner.ts Outdated
Comment thread packages/core/src/runner.ts
Comment thread packages/core/src/runner.ts Outdated
Comment thread packages/core/src/custom-steps.ts
- an absent protected path masked by a parent directory replaced with a file
  is now a violation: snapshots track parent-chain traversability and restore
  rebuilds the real chain
- nested shell parsing models cd (directory state), source/. (protects the
  sourced script), exec (recurses), and eval (fail closed)
- inline eval payloads probe extension-less import/require specifiers against
  local module layouts (x.py, pkg/__init__.py, pkg/__main__.py, x.js, index.js)
- python -m probes pkg/__main__.py as well as pkg.py
- custom-step validation no longer warns that supported cwd/workdir fields
  will be ignored

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 5 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread packages/core/src/repair-protection.ts Outdated
Comment thread packages/core/src/runner.ts Outdated
Comment thread packages/core/src/runner.ts
Comment thread packages/core/src/runner.ts
Comment thread packages/core/src/runner.ts Outdated
Comment thread packages/core/src/runner.ts Outdated
Comment thread packages/core/src/__tests__/repair-scope-guard.test.ts
- parent-chain check resolves symlink ancestors: a dangling link or cycle
  planted over a parent now reads as blocked, not as genuine absence
- the shell tokenizer carries separators; cd only threads the effective
  directory across proven-sequential positions (start, ;, &&, newline) and
  fails closed behind ||, |, or &
- builtins match on the raw token, so a script literally named ./source is
  protected as a script
- sourced files are protected AND inspected recursively (depth-capped,
  cycle-safe); a cd inside a sourced file marks later resolution unresolved
- quoted side-effect imports are scanned; bare-identifier import matching is
  python-only so JS import bindings stop false-positiving; relative-path
  specifiers are probed without dotted-module mangling

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai 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.

2 issues found across 3 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/core/src/runner.ts">

<violation number="1" location="packages/core/src/runner.ts:5242">
P1: When a failing command precedes `cd` with `&&`, the scanner changes `effectiveCwd` even though the shell skips that `cd`, so a later gate can run from the original directory without protection. Treat `&&` as non-sequential for `cd` resolution, or fail closed for the affected command chain.</violation>

<violation number="2" location="packages/core/src/runner.ts:5259">
P1: With four nested sourced scripts, the depth limit records the last script but silently skips inspecting it and its local dependencies. Remove the arbitrary cutoff, relying on `visited` for cycle termination, or mark the plan unresolved when the inspection limit is reached.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread packages/core/src/runner.ts Outdated
Comment thread packages/core/src/runner.ts Outdated
…ully

- cd now threads the effective directory only from provably-executed
  positions (start, ;, newline); behind &&, ||, |, or & it fails closed
- sourced-script inspection relies on the visited set alone, so arbitrarily
  deep source chains are inspected instead of silently cut off at depth 3

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants