You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
gstack-learnings-search cross-project trust gate fails open for rows missing the trusted field #1745
bin/gstack-learnings-search --cross-project is meant to be an allowlist: per the inline comment, cross-project learnings are "only loaded if trusted (user-stated)" to prevent prompt injection from one project's AI-generated learnings silently influencing reviews in another project.
The gate is implemented as a denylist instead:
if(isCrossProject&&e.trusted===false)continue;
Any cross-project row where trusted is missing/undefined (not literally false) is admitted, because undefined === false is false. So legacy rows written before the trusted field existed, hand-edited rows, and rows produced by other tools all bypass the gate.
The trusted field was added in the security wave 3 (#988, 2026-04-13), while gstack-learnings-search shipped earlier (#622, 2026-03-29). Any learnings.jsonl written in that window — or by anything that does not set the field — has rows with no trusted key. Those rows leak across projects today.
A foreign project row with no trusted field and source: observed is loaded and shown as [cross-project]:
$ # foreign learnings.jsonl row, no trusted field:
$ # {"ts":"2026-05-09T00:00:00Z","type":"pattern","key":"foreign-legacy","insight":"INJECTED legacy guidance with no trusted field","source":"observed"}
$ gstack-learnings-search --cross-project --query INJECTED
LEARNINGS: 1 loaded (1 pattern)
## Patterns
- [foreign-legacy] (confidence: 5/10, observed, 2026-05-09) [cross-project]
INJECTED legacy guidance with no trusted field
Expected behavior
The gate should fail closed: a cross-project row is admitted only when trusted === true. Rows missing the field are treated as untrusted. Current-format rows are unaffected (user-stated rows carry trusted: true and still load; everything else carries trusted: false and is still excluded).
Change the cross-project trust check from a denylist (e.trusted === false) to an allowlist (e.trusted !== true), and add a regression test for a foreign row with no trusted field.
Fixed in #1911 (v1.57.6.0). The cross-project trust gate is now a true allowlist (trusted !== true), so rows missing the field are excluded. A follow-up commit also removed backticks from the surrounding comment (they were command-substituted inside the bun -e block). Thanks @jbetala7. Auto-closes on merge.
Activity
garrytan commentedon Jun 8, 2026
Fixed in #1911 (v1.57.6.0). The cross-project trust gate is now a true allowlist (
trusted !== true), so rows missing the field are excluded. A follow-up commit also removed backticks from the surrounding comment (they were command-substituted inside thebun -eblock). Thanks @jbetala7. Auto-closes on merge.v1.57.6.0 fix wave: 8 community bugs (4 security guards failing open) (…
fix(learn): normalize legacy category/summary/detail learnings rows i…