Skip to content

fix(learnings): fail closed when cross-project learning lacks trusted field#1746

Closed
jbetala7 wants to merge 2 commits into
garrytan:mainfrom
jbetala7:oss/fix-learnings-trust-gate-fail-open
Closed

fix(learnings): fail closed when cross-project learning lacks trusted field#1746
jbetala7 wants to merge 2 commits into
garrytan:mainfrom
jbetala7:oss/fix-learnings-trust-gate-fail-open

Conversation

@jbetala7

Copy link
Copy Markdown
Contributor

Fixes #1745

Summary

  • treat a cross-project learnings row as untrusted unless trusted === true
  • add a regression test for a foreign row written with no trusted field

Root cause

gstack-learnings-search --cross-project documents an allowlist ("cross-project learnings only loaded if trusted (user-stated)") to keep one project's AI-generated learnings from influencing reviews in another. The gate was a denylist:

if (isCrossProject && e.trusted === false) continue;

undefined === false is false, so any cross-project row missing the trusted field was admitted. The field was introduced in security wave 3 (#988, 2026-04-13); gstack-learnings-search shipped earlier (#622). Rows written before the field existed — plus hand-edited rows and rows from other tools — have no trusted key and leak across projects today.

Fix

Switch the gate to an allowlist (e.trusted !== true). Current-format rows are unaffected: user-stated rows carry trusted: true and still load; everything else carries trusted: false and is still excluded. Only rows missing the field change behavior, and they now fail closed.

Testing

  • bun test test/gstack-learnings-search.test.ts (6 pass; the new test fails on the pre-fix binary, confirming it guards the regression)
  • bun test test/learnings.test.ts test/learnings-injection.test.ts (30 pass)
  • direct repro on a clean GSTACK_HOME: a foreign observed row with no trusted field is no longer admitted; a foreign user-stated/trusted: true row still is
  • git diff --check clean; git merge-tree clean against origin/main

jbetala7 added 2 commits May 27, 2026 13:25
The --cross-project trust gate used a denylist (e.trusted === false), so
rows with no trusted field (legacy rows written before the field existed
in garrytan#988, hand-edited rows, or rows from other tools) were admitted because
undefined === false is false. Switch to an allowlist (e.trusted !== true)
to match the documented intent: cross-project learnings load only when
explicitly trusted. Current-format rows are unaffected.
@jbetala7

Copy link
Copy Markdown
Contributor Author

Closing as superseded: the fix for #1745 landed on main via the v1.57.6.0 fix wave (#1911), which lists fixes #1745 with attribution and includes an equivalent regression test. Verified the current main already contains this exact behavior, so this PR is redundant. Thanks for consolidating it into the wave.

@jbetala7 jbetala7 closed this Jun 11, 2026
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.

gstack-learnings-search cross-project trust gate fails open for rows missing the trusted field

1 participant