Skip to content

fix(core): treat cloned repo targets as source-aware whitebox scans - #885

Open
timhaines wants to merge 2 commits into
usestrix:mainfrom
timhaines:fix/whitebox-repo-targets
Open

fix(core): treat cloned repo targets as source-aware whitebox scans#885
timhaines wants to merge 2 commits into
usestrix:mainfrom
timhaines:fix/whitebox-repo-targets

Conversation

@timhaines

@timhaines timhaines commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Fixes #884.

A repository target is cloned into /workspace/<subdir> and returned by collect_local_sources, exactly like a local_code target — but both whitebox checks tested only type == "local_code". So strix -t https://github.com/org/repo -t https://your-app.com, the invocation docs/quickstart.mdx:63 documents as "white-box testing", ran with is_whitebox=False: source-aware skills not preloaded, telemetry recording blackbox.

Before / after

targets = [{"type": "repository", "details": {"cloned_repo_path": "/clone", "workspace_subdir": "repo"}}]

bool(collect_local_sources(targets))  # True — source is in the workspace
is_whitebox_scan(targets)             # before: False    after: True

Change

The predicate was duplicated — interface/utils.py:1247 feeds telemetry, an inlined copy at core/runner.py:211 gates skills — so the two could drift. Both now share one helper, aligned with collect_local_sources for the target shapes the CLI produces:

def is_whitebox_scan(targets_info: list[dict[str, Any]]) -> bool:
    return any(
        t.get("type") == "local_code" or (t.get("details") or {}).get("cloned_repo_path")
        for t in targets_info or []
    )

It lives in strix/core/inputs.py, which already owns target-dict interpretation (build_root_task, build_scope_context) and sits on the right side of the interface → core import direction, so runner.py can reach it. If you'd rather keep it in interface/utils.py, I'm happy to drop the move and patch both sites in place.

Tests

7 new, across test_inputs.py, test_runner_root_prompt.py, and a new test_prompt_skills.py:

  • a cloned-repo target is whitebox; a URL-only scan is not
  • the predicate agrees with bool(collect_local_sources(...)) on representative target-type combinations, including repo+domain and an uncloned repo — this covers the seam that was missing, so narrowing either function in isolation should now trip a test
  • the runner's flag reaches build_strix_agent
  • _resolve_skills(is_whitebox=True) pulls in coordination/source_aware_whitebox and custom/source_aware_sast

Verified by reverting the predicate in place: exactly the three behavior tests fail (421 passed), and pass again on restore.

Checks

424 passed. ruff, mypy, pyright and bandit all at parity with main — pyright total is unchanged at 981 (inputs.py 40→42, runner.py 15→13; the two dict.get() errors moved with the code). No docs change needed: docs/quickstart.mdx:63 and docs/usage/cli.mdx:105 already document the fixed behavior.

🤖 Generated with Claude Code

A `repository` target is cloned into `/workspace/<subdir>` and returned by
`collect_local_sources`, exactly like a `local_code` target, but both whitebox
checks tested only `type == "local_code"`. Scanning a GitHub repo — alone or
alongside a domain — therefore ran with `is_whitebox=False`, so the source-aware
skills were not preloaded (`agents/prompt.py:47-49`) and telemetry recorded the
scan as blackbox, while the agent had full source in the workspace and
diff-scoping was already driving off that same `local_sources` list.

Bisects to 1e641e5, which replaced `bool(args.local_sources)` with a type check
covering only the first branch of `collect_local_sources`, not the
`repository`/`cloned_repo_path` one.

The predicate was also duplicated — `interface/utils.py:1247` feeds telemetry,
an inlined copy at `core/runner.py:211` gates skills — so the two could drift.
Both now share one helper in `strix/core/inputs.py`, which already owns
target-dict interpretation and sits on the right side of the interface -> core
import direction.

Tests: cloned-repo target is whitebox; the predicate agrees with
`collect_local_sources` across target-type combinations; the runner's flag
reaches `build_strix_agent`; `_resolve_skills(is_whitebox=True)` pulls in the
source-aware skills. The first three fail against the old predicate.

Fixes usestrix#884

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR centralizes white-box scan classification and recognizes successfully cloned repository targets as source-aware.

  • Adds is_whitebox_scan to the core input helpers.
  • Uses the shared predicate for runner skill selection and interface telemetry.
  • Adds coverage for cloned repositories, URL-only scans, and source-aware skill resolution.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
strix/core/inputs.py Adds the shared white-box predicate covering local-code and cloned-repository targets.
strix/core/runner.py Replaces the local-code-only check with the shared predicate when constructing root and child agents.
strix/interface/main.py Imports the shared core predicate so telemetry uses the same classification as the runner.
strix/interface/utils.py Removes the narrower duplicate white-box predicate while retaining local-source collection.
tests/test_inputs.py Covers cloned-repository classification and alignment with source collection across supported target combinations.
tests/test_prompt_skills.py Verifies white-box skill inclusion, black-box exclusion, ordering, and deduplication.
tests/test_runner_root_prompt.py Verifies cloned repositories reach the root agent as white-box targets while URL-only scans remain black-box.

Reviews (2): Last reviewed commit: "docs(core): scope the whitebox predicate..." | Re-trigger Greptile

…sert

The helper does not exactly mirror ``collect_local_sources`` — it accepts
``local_code`` without ``target_path``, and treats ``cloned_repo_path`` by
truthiness rather than key presence. Those shapes are unreachable through the
CLI, so the predicate is unchanged; only the claim is narrowed. Same for the
test, which checks enumerated representative cases rather than a universal
invariant.

Also records why classification is target-derived: ``_load_resume_state``
restores ``local_sources`` conditionally while requiring ``targets_info``, so
an older resumed run can describe a cloned repo with no ``local_sources``, and
deriving from the latter would disable source-aware behavior in a sandbox that
still has the source.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@timhaines

Copy link
Copy Markdown
Contributor Author

@greptile

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.

[BUG] GitHub repo targets scan as blackbox — source-aware skills not preloaded

1 participant