FE-1241: Add isolated brownfield comparison cases#362
Conversation
|
Semgrep found 2 RegExp() called with a View Dataflow Graphflowchart LR
classDef invis fill:white, stroke: none
classDef default fill:#e7f5ff, color:#1c7fd6, stroke: none
subgraph File0["<b>src/dev/execution-comparison/__tests__/historical-replay-target.test.ts</b>"]
direction LR
%% Source
subgraph Source
direction LR
v0["<a href=https://github.com/hashintel/brunch/blob/5e1ed22b8c9bf153d017514aaf987584350e0892/src/dev/execution-comparison/__tests__/historical-replay-target.test.ts#L734 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 734] overrides</a>"]
end
%% Intermediate
subgraph Traces0[Traces]
direction TB
v2["<a href=https://github.com/hashintel/brunch/blob/5e1ed22b8c9bf153d017514aaf987584350e0892/src/dev/execution-comparison/__tests__/historical-replay-target.test.ts#L734 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 734] overrides</a>"]
v3["<a href=https://github.com/hashintel/brunch/blob/5e1ed22b8c9bf153d017514aaf987584350e0892/src/dev/execution-comparison/__tests__/historical-replay-target.test.ts#L234 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 234] portableDependencies</a>"]
v4["<a href=https://github.com/hashintel/brunch/blob/5e1ed22b8c9bf153d017514aaf987584350e0892/src/dev/execution-comparison/__tests__/historical-replay-target.test.ts#L225 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 225] await</a>"]
v5["<a href=https://github.com/hashintel/brunch/blob/5e1ed22b8c9bf153d017514aaf987584350e0892/src/dev/execution-comparison/__tests__/historical-replay-target.test.ts#L225 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 225] ready</a>"]
v6["<a href=https://github.com/hashintel/brunch/blob/5e1ed22b8c9bf153d017514aaf987584350e0892/src/dev/execution-comparison/__tests__/historical-replay-target.test.ts#L275 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 275] `</a>"]
end
v2 --> v3
v3 --> v4
v4 --> v5
v5 --> v6
%% Sink
subgraph Sink
direction LR
v1["<a href=https://github.com/hashintel/brunch/blob/5e1ed22b8c9bf153d017514aaf987584350e0892/src/dev/execution-comparison/__tests__/historical-replay-target.test.ts#L275 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 275] new RegExp(`^${ready.baseSha}\\.\\.[a-f0-9]{40}$`, 'u')</a>"]
end
end
%% Class Assignment
Source:::invis
Sink:::invis
Traces0:::invis
File0:::invis
%% Connections
Source --> Traces0
Traces0 --> Sink
|
This stack of pull requests is managed by Graphite. Learn more about stacking. |
Add history-free Brunch and Petrinaut profiles with controller-owned oracles so real repositories can enter the crossed comparison without exposing historical solutions. Co-authored-by: Cursor <cursoragent@cursor.com>
Make strict two-commit admission the sole lane-ready preparation path and harden its dependency and network contracts. Co-authored-by: Cursor <cursoragent@cursor.com>
Exercise the branded sandbox contract with a portable test runner so Linux CI does not invoke the macOS-only production verifier. Co-authored-by: Cursor <cursoragent@cursor.com>
Align the frozen mission with merged reference behavior while preserving greenfield access, isolated runtime bounds, and portable CI verification. Co-authored-by: Cursor <cursoragent@cursor.com>
Preserve the landed FE-1250 and FE-1251 frontier state alongside the latest brownfield comparison status. Co-authored-by: Cursor <cursoragent@cursor.com>
24abfa8 to
3327b6a
Compare
Run the expect-backed PTY integration suite on Ubuntu with the zsh executable its fixtures invoke. Co-authored-by: Cursor <cursoragent@cursor.com>
Accept both first-run mode selection and an already-settled controller session before driving the public landing command. Co-authored-by: Cursor <cursoragent@cursor.com>
Canonicalize bounded reads across filesystem aliases and replace runtime regex construction with fixed-text option matching while retaining redaction coverage. Co-authored-by: Cursor <cursoragent@cursor.com>
Deny lexical escapes uniformly while permitting canonical in-root aliases and retaining symlink containment checks. Co-authored-by: Cursor <cursoragent@cursor.com>
Validate the nearest existing ancestor so absent in-root paths reach the underlying tool without weakening alias or symlink boundaries. Co-authored-by: Cursor <cursoragent@cursor.com>
Retire consumed scope cards and preserve the real-reference preflight as an explicit future gate rather than completed evidence. Co-authored-by: Cursor <cursoragent@cursor.com>
Move the waived provider evidence to an explicit Later gate and keep only current D136-D138 topology in live canonical memory. Co-authored-by: Cursor <cursoragent@cursor.com>
PR SummaryMedium Risk Overview Controller and operator plumbing gains D137-L historical replay ( Lane isolation tightens comparison runs: Brunch comparison TUI disables web tools and Specify subagents, bounds foreground read/grep/find/ls to the target (symlink-aware), and limits execution subagents to planner/worker; Claude brownfield launches use strict MCP, disabled web fetch/search, sandbox denied reads for controller roots, and parallel subagent path bounding. Docs and process update Reviewed by Cursor Bugbot for commit bc323a3. Bugbot is set up for automated code reviews on this repo. Configure here. |
Bind retained evidence to every runtime oracle input and make Petrinaut interactions fail closed on declared addresses. Co-authored-by: Cursor <cursoragent@cursor.com>
Encode tool policy lists unambiguously and provision ripgrep so the Linux full gate can exercise bounded grep reads. Co-authored-by: Cursor <cursoragent@cursor.com>
| assertContainedPath(root, target); | ||
| const [realRoot, realTarget] = await Promise.all([realpath(root), realpath(target)]); | ||
| assertContainedPath(realRoot, realTarget); | ||
| } |
There was a problem hiding this comment.
Subagent path bound rejects aliases
Medium Severity
assertBoundedExistingPath rejects lexically mismatched paths before comparing canonical roots, so macOS /var vs /private/var aliases fail even when both resolve inside the worktree. Foreground assertBoundedReadPath in this same change already allows that alias case, and planner/worker reads now go through the stricter helper unconditionally.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit ec0d321. Configure here.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
There are 3 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit bc323a3. Configure here.
| await assertBoundedExistingAncestor(cwd, target); | ||
| await mkdir(dirname(target), { recursive: true }); | ||
| await assertBoundedExistingPath(cwd, dirname(target)); | ||
| await assertBoundedExistingTargetIfPresent(cwd, target); |
There was a problem hiding this comment.
Dangling symlink write escape
High Severity
The new worktree write bounds treat a missing final path as safe, then call writeFile. A dangling symlink that is lexically inside the worktree still resolves to ENOENT on realpath, so containment passes and writeFile follows the link and can create or overwrite a file outside the target root. That undermines the comparison isolation this change is adding.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit bc323a3. Configure here.
| caseValue['surface'] !== 'backend' || | ||
| repository['substrate'] !== 'pinned_git' || | ||
| !gitObjectId(repository['parentCommit']) || | ||
| !gitObjectId(repository['parentTree']) || |
There was a problem hiding this comment.
Brunch source identity unfrozen
Medium Severity
The Brunch brownfield parsers only require parentCommit and parentTree to look like Git object ids. Petrinaut pins the exact frozen hashes in the same allowlist path, so Brunch source identity can drift to any other commit/tree without failing contract validation.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit bc323a3. Configure here.



Why
The greenfield Petri case does not prove that exact handoff, repository preparation, and solution isolation hold inside real brownfield repositories. This adds representative backend and frontend replays without exposing historical solutions to either execution lane.
What
Add two frozen comparison profiles:
/brunch:landjourney with black-box TUI evidence plus an independent full-range Git model./optimization, using focused package preparation, a same-origin deterministic optimizer, declared mechanical addresses, and contrastive browser rivals.Both profiles use the same admitted historical-replay pipeline:
The admission boundary verifies the exact two-commit prefix, clean tracked source, closed dependency recipes, bounded filesystem access, disabled web/MCP surfaces, and denied historical-source network probes. Oracle reports are retained write-once beside a hash covering controller manifests, implementation modules, and runtime calibration inputs.
How to run a comparison
Run comparisons from a trusted top-level project Pi session in the Brunch repository. To list the available cases:
The eligible case ids are:
minimal-petri-net-editor— greenfield; no source checkout required.brunch-host-landing— brownfield; requires a Brunch checkout containing parentf5a423b19f76cf345d88053456870a126e451618.petrinaut-optimization— brownfield; requires a HASH checkout containing parent5c7a2d9db5caa851c38938f4b1bac19005b0e978.For a greenfield run, use the guided workflow directly:
For a brownfield run, inspect the frozen public packet and prepare each executor in a fresh absolute target directory:
Review the returned launch descriptor and run it unchanged. Keep exactly one executor lane live at a time, stop Brunch at
promotion_prepared, and retain the target after process cleanup. Once the lane has terminated, run the compiled controller oracle with an absolute evidence path:Repeat with a fresh target for the other executor. Preserve failed and invalid attempts; compare validity and requirement evidence before outcomes, and do not infer a general winner from one run. The full operator/evidence rules are in
docs/praxis/comparison-runs.md.Before the first Petrinaut provider attempt, run the required merged-reference preflight:
A passing receipt is required under D138-L. The implementation-PR waiver is not reusable as campaign evidence.
Scope and evidence
How to test
npm run verify:fullnpm run checknpx changeset status --since=origin/nextgit diff --check origin/next...HEAD