docs(memorable): vendor environment allowlist and stderr policy; two follow-ups

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-09-09 03:19:04 +00:00
co-authored by Claude Fable 5.1
parent 17bb209457
commit 4a808f0c58
2 changed files with 45 additions and 0 deletions
+35
View File
@@ -626,6 +626,41 @@ identity-based answer.
**Effort:** S. **Priority:** P3. **Depends on:** none.
### P3: one state-root rule for the bridge's four stores
**What:** The hook, `bin/gstack-config` and `bin/gstack-memorable` resolve
their root as `GSTACK_STATE_ROOT` > `GSTACK_HOME` > `GSTACK_STATE_DIR`; the
egress ledger (`lib/egress-receipt.ts`) honors `GSTACK_HOME` >
`GSTACK_STATE_DIR`; the trust-policy store (`lib/gbrain-repo-policy-client.ts`)
only `GSTACK_HOME`; `bin/gstack-uninstall` deletes only
`${GSTACK_STATE_DIR:-$HOME/.gstack}`. Extract one shared rule (a
`lib/state-root.ts` plus its bash twin) and use it everywhere.
**Why:** With `GSTACK_STATE_ROOT` set, the gate lives under one directory and
the receipts under another; the tests pin all three variables to one temp dir,
so the drift is invisible to them. Found by the /ship red team.
**Context:** Uninstall already flips `memorable_recall` off unconditionally
(through gstack-config's own resolution) so no config can say `on` after the
hook is gone; the remaining drift is observability, not consent.
**Effort:** S (human ~3 h / CC+gstack ~20 min). **Priority:** P3.
**Depends on:** none.
### P3: shared hook logging helper
**What:** `stateRoot()` and the `hook-errors.log` appender now exist in five
hooks (`question-log`, `question-preference`, `auq-error-fallback`,
`timeline-stop`, `memorable-user-prompt`), with drifting env-var precedence.
Extract `hosts/claude/hooks/hook-log.ts` (root resolution, 0600 append, the
rate limiter the memorable hook added) and migrate the five.
**Why:** One place to fix precedence and file modes; the memorable hook's
rate limiter belongs to every hook that can fail on every prompt.
**Effort:** S (human ~2 h / CC+gstack ~15 min). **Priority:** P3.
**Depends on:** the state-root rule above.
## Aside integration follow-ups (filed via /plan-ceo-review + /plan-eng-review on the third-party-actions Aside plan)
### QA logged-in-evidence path via Aside (Phase 2)
+10
View File
@@ -68,6 +68,16 @@ allowlisted argument fields and a 200-character task line. Those are the
vendor's claims. The bridge is tested against memorable-cli 0.5.18's hook
contract; other versions are the vendor's compatibility claim.
The binary's environment is an allowlist, not your session's: `PATH`, `HOME`,
user and shell names, locale (`LANG`, `LC_*`), temp directories, the standard
proxy and TLS variables (`HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY`,
`SSL_CERT_FILE`, `SSL_CERT_DIR`, `NODE_EXTRA_CA_CERTS`), the `XDG_*`
directories, and every `MEMORABLE*` variable. No `ANTHROPIC_API_KEY`, no
`GSTACK_*`, no `CLAUDE_*` reaches it. Its stderr is kept out of
`hook-errors.log` whenever the redaction engine finds a credential or PII
shape in it, so a vendor that echoes its input on an error cannot copy your
prompt into a log.
The hook skips the hand-off entirely, with one rate-limited line in
`~/.gstack/hook-errors.log`, when: