mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-12 16:08:59 +02:00
fix(code-intelligence): consent that means what it says — polarity, receipts, read-only veto
Four review findings on the wave's own Phase 1 port, all red-first: 'consent <repo> no' recorded consent GRANTED (the CLI ignored the argument and always wrote true) — yes|no is now required and garbage records nothing; Sourcebot egress receipts claimed consented=true on paths that never checked consent — the actual consent state is threaded into every receipt, search is fail-closed on non-loopback, and the liveness probe's receipt says truthfully that it sends no repo content; repoPolicyVeto only honored the deny tier while gbrain refresh writes pages — write-class ops now veto on read-only too, matching the sync chokepoint, via one shared lib/gbrain-repo-policy-client.ts (win32 bash invocation, spawn-vs-unreadable error distinction) used by both call sites. Also: source ids get a host+path hash (same-name repos no longer collide), refresh timeout raised to 120s, availability probes run concurrently at 3s, graphify status stops JSON.parsing 100MB graphs for a count, and every ported file carries the fork MIT notice. +15 tests across the two suites.
This commit is contained in:
+16
-13
@@ -42,6 +42,7 @@ import { detectAutopilot, decideSourceRemove, decideCodeSync } from "../lib/gbra
|
||||
import { writeReceipt } from "../lib/egress-receipt";
|
||||
import { localEngineStatus, type LocalEngineStatus } from "../lib/gbrain-local-status";
|
||||
import { buildGbrainEnv, spawnGbrain, execGbrainJson, NEEDS_SHELL_ON_WINDOWS } from "../lib/gbrain-exec";
|
||||
import { repoPolicyTier as sharedRepoPolicyTier } from "../lib/gbrain-repo-policy-client";
|
||||
import { checkOwnedStagingDir } from "../lib/staging-guard";
|
||||
|
||||
// ── Types ──────────────────────────────────────────────────────────────────
|
||||
@@ -793,21 +794,23 @@ function warnProbeTimeout(stage: "code" | "memory" | "dream"): void {
|
||||
* behavior as before for every non-policy user, and skips the subprocess).
|
||||
* Fail-closed ("error") when a store exists but can't be read: a policy the
|
||||
* user set must not be silently bypassed by a broken store or missing jq.
|
||||
*
|
||||
* Reads through the shared lib/gbrain-repo-policy-client.ts (same client as
|
||||
* the code-intelligence consent veto — the two gates can never drift, and
|
||||
* win32 gets the invoke-via-bash path). A spawn failure is still fail-closed
|
||||
* but says so, instead of the misleading "store could not be read".
|
||||
*/
|
||||
export function repoPolicyTier(url: string | null): "read-write" | "read-only" | "deny" | "unset" | "error" {
|
||||
const policyFile = join(process.env.GSTACK_HOME || join(homedir(), ".gstack"), "gbrain-repo-policy.json");
|
||||
if (!existsSync(policyFile)) return "unset";
|
||||
if (!url) return "unset"; // policy is keyed by origin remote; no remote → nothing set for this repo
|
||||
const res = spawnSync(join(import.meta.dir, "gstack-gbrain-repo-policy"), ["get", url], {
|
||||
encoding: "utf-8",
|
||||
timeout: 10_000,
|
||||
// Explicit env: Bun's spawnSync default env snapshot misses runtime
|
||||
// process.env mutations (e.g. tests redirecting GSTACK_HOME).
|
||||
env: { ...process.env },
|
||||
});
|
||||
if (res.error || res.status !== 0) return "error";
|
||||
const tier = (res.stdout || "").trim();
|
||||
return tier === "deny" || tier === "read-only" || tier === "read-write" || tier === "unset" ? tier : "error";
|
||||
const res = sharedRepoPolicyTier(url, process.env);
|
||||
if (res.error === "spawn-failed") {
|
||||
process.stderr.write(
|
||||
"[gstack-gbrain-sync] the repo-policy helper could not be spawned (bash missing from PATH?) — " +
|
||||
"refusing ingest rather than bypassing a possibly-set policy\n",
|
||||
);
|
||||
return "error";
|
||||
}
|
||||
if (res.error) return "error";
|
||||
return res.tier === "none" ? "unset" : res.tier;
|
||||
}
|
||||
|
||||
async function runCodeImport(args: CliArgs): Promise<StageResult> {
|
||||
|
||||
Reference in New Issue
Block a user