Codex adversarial review found a HIGH the Claude pass missed plus 3 mediums:
- C1 (HIGH): gstack-decision-search --all returned every decide and IGNORED redact
events, so a redacted secret still resurfaced via --all until compact ran. --all
now excludes redacted (redact = expunge from every read path), still showing
superseded history.
- C-med: semantic (external gbrain) slug/snippet were printed raw — datamark them too
so a gbrain hit can't spoof role markers / fences into agent context.
- C4: semanticRecall fell back to an UNSCOPED gbrain search when no curated-memory
source resolved, pulling code/doc corpora mislabeled as 'related decisions'. Now
returns null (degrade) when there's no worktree-backed memory source.
- C5: validateDecide scanned only decision/rationale/alternatives; branch and issue
are stored + surfaced (raw via --json), so include them in the injection+secret scan.
C2 (snapshot staleness) / C3 (compact TOCTOU residual): accepted for a single-user
store — atomic appends never lose the event, rebuilds self-heal, and the compact
size-recheck leaves only a sub-ms window; full append-locking would break the
lock-free append design.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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>
Adds gstack-decision-search --semantic (with --query): appends a 'Related from
memory' block from gbrain semantic search, scoped to the curated-memory source.
Pure enhancement, reliability-first: a new lib/gstack-decision-semantic.ts is the
ONLY decision module that touches gbrain and is imported lazily only on --semantic,
so the reliable file path never loads gbrain code. Every path degrades to the
reliable file results when gbrain is off, unconfigured, empty, or errors (never
throws, 10s timeout).
Built against the verified gbrain 0.42.x surface (text output [score] slug --
snippet, NOT JSON; curated-memory source resolved by worktree path, not a
gstack-brain-<user> id). Deterministic-contract tests only: parser units,
degrade-to-null when gbrain absent, and a fake-gbrain shim proving scope+search
end-to-end. find-contradictions deferred (no verifiable CLI surface yet + curated
memory not indexed).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two bins mirroring gstack-learnings-* (D3A). log writes decide/--supersede/--redact/
--compact events + refreshes the bounded snapshot + enqueues for cross-machine sync;
search reads the O(active) snapshot, scope-filtered to current branch, newest-first,
--all to include superseded, --json for machines. Empty store returns silently
(no snapshot write on an empty read).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>