feat(memory-ingest): honor the per-remote deny/read-only trust policy (#2392)

Transcript ingest now respects the same trust store as code import — the gate
existed only in gstack-gbrain-sync's runCodeImport, so memory-ingest happily
ingested transcripts from deny-listed repos. preparePages filters prepared
transcript pages through ONE batch policy lookup (new 'get --batch' verb on
bin/gstack-gbrain-repo-policy — the script owns URL normalization; the client
adds repoPolicyTierBatch, one spawn for all distinct remotes, so large corpora
never pay a 10s-timeout subprocess per remote).

Outcomes match code-import semantics: read-only → clean skip
(skipped_policy_readonly), deny → counted refusal (skipped_policy_deny),
corrupted/unreadable store → HARD ERROR before any write (state, staging,
egress receipt, and import all untouched) with the recovery command named —
policy corruption must never read as successful ingestion. Artifacts are
never policy-filtered (their git_remote is a project slug, not a remote).

Fixes #2392.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-08-17 10:39:24 -07:00
co-authored by Claude Fable 5
parent 40e4a53f74
commit 2494276742
6 changed files with 632 additions and 2 deletions
+19
View File
@@ -35,6 +35,25 @@ happens after you say yes.
- **Repos under a `deny` trust policy** (set in `/setup-gbrain` Step 6)
are skipped — neither code nor transcripts from those repos ingest.
## Per-remote trust policy (deny / read-only)
Transcript ingest respects the same per-remote trust store as code import
(`~/.gstack/gbrain-repo-policy.json`, managed by
`gstack-gbrain-repo-policy`). Each transcript's git remote is checked
against the store before anything is written:
- **deny** — the transcript is skipped (reported as `skipped (policy deny)`).
- **read-only** — skipped too: read-only means "search allowed, page
writes never", and transcript ingest writes pages (reported as
`skipped (policy read-only)`).
- **read-write, or no entry** — ingests normally.
- **Corrupted or unreadable store** — ingestion aborts before any writes
rather than bypassing a set policy. Inspect the store with
`gstack-gbrain-repo-policy list`; re-run `/setup-gbrain` if it's corrupt.
Artifacts (learnings, plans, retros, etc.) are never policy-filtered — the
policy is keyed by git remote, which artifacts don't have.
## What gets scanned for secrets
The cross-machine secret boundary is `gstack-brain-sync` (the git push