Skip to content

improvement(provenance): name the block behind an unprojected input root - #6890

Merged
icecrasher321 merged 2 commits into
stagingfrom
provenance/name-the-unprojected-block
Aug 20, 2026
Merged

improvement(provenance): name the block behind an unprojected input root#6890
icecrasher321 merged 2 commits into
stagingfrom
provenance/name-the-unprojected-block

Conversation

@icecrasher321

Copy link
Copy Markdown
Collaborator

Summary

  • structural-input-root-unprojected fires when a block's tools.config.params throws on the projected inputs — the copy where a secret has been replaced by its placeholder — and no structured projection recovers it. It was reported with the reason and nothing else, and the caught error was dropped by a bare catch, so the line said this had happened somewhere without naming the block. In prod it has been firing at a baseline of ~1–16/day for over a week with no way to act on it.
  • markIncomplete now takes a structural detail, and this guard passes the block type, tool id, input path, and failure class. Its sibling guard (structural-input-projection-incomplete) gets the same treatment.
  • Names and types only, never the thrown message: a coercion that rejects a value tends to quote it, and an input reaching this guard may still hold a resolved secret. Detail keys are spread first so they cannot shadow the canonical fields these lines are queried by.
  • Fixes a related leak found in the same function. The json/array parse warning logged toError(error).message, and V8 quotes the text it rejected back into that message — Unexpected token 's', "sk-live-EX"... is not valid JSON. That value is a resolved input, so the prefix could be a secret. It now logs the failure class; the field name and its declared type were already in the message, and SyntaxError is the only class JSON.parse throws.

Type of Change

  • Bug fix

Testing

Tested manually. bun run lint, all 24 CI audits, and check-block-registry pass; type-check clean. 2,387 tests pass across the executor and provenance suites, including two new cases pinning that a supplied detail reaches the line and that it cannot shadow the canonical fields.

Note for review: the json-parse leak fix is not covered by a test. The handler builds its logger at import time and the shared @sim/logger mock returns a fresh instance per call, so the instance the module holds is unreachable from an assertion without either changing the shared mock for every test in the repo or using the resetModules + dynamic-import pattern the testing rules prohibit. The change itself is one field.

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)

structural-input-root-unprojected fires when a block's config.params
throws on the projected inputs — the copy where a secret has been
replaced by its placeholder — and no structured projection recovers it.
It was reported with the reason and nothing else, so a line told you
this had happened somewhere without naming the block, and the caught
error was discarded by a bare catch. markIncomplete now takes a
structural detail, and this guard passes the block type, tool, input
path, and failure class.

Names and types only. A coercion that rejects a value tends to quote it,
and an input reaching this guard may still hold a resolved secret.

Which is also why the json-parse warning a few lines above no longer
logs the thrown message: V8 quotes the text it rejected back into it —
Unexpected token 's', "sk-live-EX"... is not valid JSON — and that
prefix is enough to leak. The field name and its declared type are
already in the message, and SyntaxError is the only class JSON.parse
throws.
@vercel

vercel Bot commented Aug 20, 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 20, 2026 5:35pm

Request Review

@cursor

cursor Bot commented Aug 20, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches secret-trace incompleteness logging and a path that can still hold resolved secrets. The change is diagnostic-only and deliberately avoids logging thrown messages, but a mistake here could leak secret prefixes or break alerting on reason.

Overview
Makes structural-input-root-unprojected (and its sibling structural-input-projection-incomplete) actionable by attaching where the guard tripped: block type, tool id, input path, and error class. Production was seeing these daily with only a reason, so they could be counted but not investigated.

markIncomplete now accepts a closed detail object. Detail is spread first and reason is written last so callers cannot shadow the fields these lines are queried and alerted on. Tests pin both the extra fields and the anti-shadowing guarantee.

Also stops a related leak in the same handler: JSON/array parse warnings now log error.name instead of error.message, because V8 quotes the rejected text (which may be a resolved secret) into that message.

Reviewed by Cursor Bugbot for commit 672d441. Configure here.

@greptile-apps

greptile-apps Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR makes provenance incompleteness diagnostics actionable while avoiding resolved-secret disclosure.

  • Adds block, tool, input-path, and failure-class context to structural projection failures.
  • Prevents caller detail from overriding canonical diagnostic fields.
  • Replaces JSON parse error messages with error-class names.
  • Adds coverage for detail propagation and canonical-field precedence.

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 Adds secret-safe failure attribution to structural projection guards and removes parsed input text from warnings.
apps/sim/executor/utils/resolved-secret-trace-registry.ts Introduces a closed structural-detail payload and preserves canonical incompleteness fields when logging.
apps/sim/executor/utils/resolved-secret-trace-registry.test.ts Verifies detail propagation and protection of canonical diagnostic fields.

Reviews (2): Last reviewed commit: "fix(provenance): keep a detail from disp..." | Re-trigger Greptile

Comment thread apps/sim/executor/utils/resolved-secret-trace-registry.ts
The detail merged into the incompleteness payload could shadow `reason`.
Spreading it first at the call site protected only the fields added
there; `reason` is added a level up in reportIncompleteness, which
built `{ reason, ...details }`, so a detail carrying that key replaced
the guard literal on the line while the level was still selected from
the real one. `origin` was reachable the same way whenever no importer
origin was set.

Write `reason` last, which protects every caller of that reporter
rather than the one that prompted this, and close the detail to named
fields so neither key is expressible without a cast.
@icecrasher321

Copy link
Copy Markdown
Collaborator Author

@greptile

@icecrasher321

Copy link
Copy Markdown
Collaborator Author

@cursor review

@icecrasher321 icecrasher321 changed the title fix(provenance): name the block behind an unprojected input root improvement(provenance): name the block behind an unprojected input root Aug 20, 2026

@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 672d441. Configure here.

@icecrasher321
icecrasher321 merged commit 785c619 into staging Aug 20, 2026
31 checks passed
@icecrasher321
icecrasher321 deleted the provenance/name-the-unprojected-block branch August 20, 2026 17:41
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