Skip to content

fix(provenance): stop requiring a projection of roots no model sees - #6981

Merged
icecrasher321 merged 2 commits into
stagingfrom
provenance/dont-require-projecting-bundle-roots
Aug 22, 2026
Merged

fix(provenance): stop requiring a projection of roots no model sees#6981
icecrasher321 merged 2 commits into
stagingfrom
provenance/dont-require-projecting-bundle-roots

Conversation

@icecrasher321

Copy link
Copy Markdown
Collaborator

Summary

  • A secretProvenance selection is the opposite mechanism to a projected model input: the value reaches an internal API unchanged, with its provenance alongside it in the private bundle, precisely so nothing has to be substituted. selectBlockBoundaryPaths marked those roots required-to-project anyway.
  • That made a projection failure fatal for tools with no way to project. createStructuredModelProjection rescues only a mode: 'project' tool with an applyProjected, so for the ~21 secretProvenance-only tools (memory, file, knowledge, all the table tools) it returns undefined on its first check. table_insert_row declares no modelInput at all — nothing on that path reaches a model.
  • In prod this fired as: the Table block's params threw on its projected data, the whole run's registry latched, and every later boundary in that run lost provenance — including the table write that prompted it, whose rows were then stored unknown and re-reported on every subsequent read.
  • Those paths are still tracked for provenance export; none of them is required to project. A root is required to project when a model will see it, which is what modelInput declares.
  • Separately: a crossing that carried no provenance is now distinguished from one that was rejected, so a run that failed before producing any stops reporting a by-design state as an originating fault at error level.
  • And the first guard's location is carried into the diagnostics a refusal reports, so a downstream reporter names where rather than only what — the ModelInputProvenance line had no tool field at all.

Type of Change

  • Bug fix

Testing

Tested manually. bun run lint, all 24 CI audits, and type-check pass. 4,459 tests pass across the executor, provenance, table, and secret-provenance suites, including a regression test that a bundle-only tool keeps vouching when its block params throws on projected inputs — verified to fail against the previous behaviour.

Note for review: the reproduction test makes params throw on any projected input rather than replicating the exact JSON shape that breaks in prod. prepareResolvedSecretProjectedInputs preserves JSON grammar and substitutes inside it, so the common case parses fine; which shape breaks isn't known and doesn't change the invariant under test — a bundle-only tool must not latch the registry when it cannot project.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

A secretProvenance selection is the opposite mechanism to a projected
model input: the value reaches an internal API unchanged, with its
provenance alongside it in the private bundle, precisely so nothing has
to be substituted. selectBlockBoundaryPaths marked those roots required
to project anyway.

That made a projection failure fatal for tools with no way to project.
createStructuredModelProjection rescues only a mode: 'project' tool with
an applyProjected, so for the twenty-odd secretProvenance-only tools it
returns undefined on its first check. table_insert_row declares no
modelInput at all and posts row data to the table API; when the Table
block's params threw on its projected data the whole run's registry
latched, costing provenance for every later boundary — including the
table write that prompted it, whose rows were then stored unknown and
re-reported on every later read.

Track those paths, require none of them. A root is required to project
when a model will see it, which is what modelInput declares.

Also separate a crossing that carried no provenance from one that was
rejected, so a run that failed before producing any stops reporting a
by-design state as an originating fault; and carry the first guard's
location into the diagnostics a refusal reports, so a downstream
reporter names where rather than only what.
@vercel

vercel Bot commented Aug 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Aug 22, 2026 7:26pm

Request Review

@cursor

cursor Bot commented Aug 22, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches secret-provenance completeness and logging, which can change whether a run keeps vouching for secrets. The change is a targeted relaxation plus diagnostics, not a new egress path.

Overview
Stops treating secretProvenance input roots as required-to-project. Those values go to internal APIs with provenance in the private bundle, not to a model, so a failed placeholder projection must not latch the run.

That latch was fatal for bundle-only tools such as table_insert_row: params threw on projected JSON, the registry went incomplete, and later boundaries (including the table write) lost provenance.

Also distinguishes a crossing with no provenance (value-provenance-absent, warn) from a rejected bundle (value-provenance-untrusted, error), and carries the first guard’s detail (block, tool, path) through diagnostics into refusal logs without overwriting the refusal’s own inputPath.

Reviewed by Cursor Bugbot for commit 40f8761. Configure here.

@greptile-apps

greptile-apps Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR separates private provenance selections from model-input projection requirements and improves provenance diagnostics.

  • Keeps bundle-only tools from latching the registry when projected block parameters cannot be constructed.
  • Distinguishes absent crossing provenance from rejected provenance.
  • Carries originating guard detail into projection-refusal records.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
apps/sim/executor/handlers/generic/generic-handler.ts Limits required projection roots to declared model inputs while continuing to track private provenance paths.
apps/sim/executor/utils/resolved-secret-projection-refusal.ts Adds nested originating-guard detail to projection-refusal diagnostics.
apps/sim/executor/utils/resolved-secret-trace-registry.ts Adds absent-crossing classification and propagates incompleteness detail through registry diagnostics.

Reviews (2): Last reviewed commit: "fix(provenance): report where the guard ..." | Re-trigger Greptile

Comment thread apps/sim/executor/utils/resolved-secret-trace-registry.ts
The registry retained the first guard's location, but the refusal
reporter copies named fields out of the diagnostics and never picked it
up — so the line an operator actually reads when a projection is refused
still named only the reason.

Nested rather than spread flat: the guard's `inputPath` names where it
tripped and the refusal's names where the refusal happened, which differ
whenever a latch travels, so flattening would overwrite one with the
other.
@icecrasher321

Copy link
Copy Markdown
Collaborator Author

@greptile

@icecrasher321

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor 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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 40f8761. Configure here.

@icecrasher321
icecrasher321 merged commit a721a76 into staging Aug 22, 2026
30 checks passed
@icecrasher321
icecrasher321 deleted the provenance/dont-require-projecting-bundle-roots branch August 22, 2026 19:32
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