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>
writeSnapshot/readSnapshot/rebuildSnapshot give an O(active) bounded read for the
session-start hot path (D1A). compact() rewrites the log to active, archives
superseded decisions for history, and EXPUNGES redacted ones (dropped, never
archived) so an accidentally-captured secret leaves the store for good.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
decide/supersede/redact events on lib/jsonl-store; active set is computed (no
mutable status), dangling refs tolerated. Free-text is injection-checked and
redact-scanned on write (HIGH secret -> reject). Scope filter (repo/branch/issue)
for relevant resurfacing. File-only + reliable; gbrain not required.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>