fix: pre-landing review fixes (datamark, DRY, compact, coverage)

Addresses the pre-landing review findings (all INFORMATIONAL, no criticals):
- security: datamark resurfaced decision text at the render boundary
  (lib/gstack-decision.ts datamark() — neutralizes code fences, --- banners,
  <|role|>/</system> markers, control chars, newlines). Applied in
  gstack-decision-search human output so stored text can't masquerade as
  instructions in Context Recovery (codex hardening #3 / AC #7). --json stays raw.
- DRY: extract resolveSlug/gitBranch/flagValue to lib/bin-context.ts; both
  decision bins use it instead of duplicating the helpers.
- compact(): batch the archive append (one write, not N) and shrink the
  mid-compact crash window; simplify the opaque branch/issue ternary.
- coverage: learnings-log injection rejection (D2A wiring), search --recent/
  --scope + NaN-safe --recent, datamark-applied, unparseable lock body,
  compact-empty, corrupt-snapshot degrade.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-06-07 19:17:44 -07:00
parent 02eba57f3a
commit 55e7ed9fec
8 changed files with 164 additions and 47 deletions
+10
View File
@@ -77,6 +77,16 @@ describe("detectAutopilot", () => {
expect(r.active).toBe(true);
expect(r.signal).toBe("process:gbrain autopilot");
});
test("a lock with no parseable pid stays conservative (active, no pid in signal)", () => {
const tmp = fs.mkdtempSync(join(os.tmpdir(), "ap-"));
const lock = join(tmp, "autopilot.lock");
fs.writeFileSync(lock, "corrupted-no-pid-here");
const r = detectAutopilot(process.env, { lockPaths: [lock], processRunning: () => false });
expect(r.active).toBe(true); // can't introspect → don't ignore the lock
expect(r.signal).toContain("lock:");
expect(r.signal).not.toContain("pid");
});
});
// ── #1734 remove safety (E7: fail closed on user-managed without keep-storage) ─