gates / gates (push) Successful in 6m44s
Build skill (hub token, ISO publish), fb_probe (token from `sec run` env, tests red-proved), secrets.md (Resend: pipe inside sec run), bench README, read_credential docstring, 12-agent-tooling §5, workspace CLAUDE secrets line. Evidence: audits/cc-creds-build-2026-10-17/ (tests, red-proofs, 36-row child-session proof both launch modes, install, fresh-session proof, import names+lengths, history sweep names). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
27 lines
1.4 KiB
Python
27 lines
1.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Probe: log the SHAPE of tool_response (keys, types, string lengths — never values); if SCRUB=1, replace every
|
|
canary (files named in CANARIES, colon-separated) in every string, recursively, and return updatedToolOutput."""
|
|
import json, os, sys, time
|
|
ev = json.load(sys.stdin)
|
|
vals = [open(p).read().rstrip("\n") for p in os.environ.get("CANARIES", "").split(":") if p]
|
|
def shape(o):
|
|
if isinstance(o, dict): return {k: shape(v) for k, v in o.items()}
|
|
if isinstance(o, list): return [shape(v) for v in o[:3]] + (["...%d" % len(o)] if len(o) > 3 else [])
|
|
if isinstance(o, str): return "str(%d)%s" % (len(o), "+CANARY" if any(v in o for v in vals) else "")
|
|
return type(o).__name__
|
|
changed = [False]
|
|
def scrub(o):
|
|
if isinstance(o, dict): return {k: scrub(v) for k, v in o.items()}
|
|
if isinstance(o, list): return [scrub(v) for v in o]
|
|
if isinstance(o, str):
|
|
n = o
|
|
for v in vals: n = n.replace(v, "«CANARY»")
|
|
if n != o: changed[0] = True
|
|
return n
|
|
return o
|
|
new = scrub(ev["tool_response"])
|
|
with open(os.path.expanduser("~/cc-creds-build/ev/shape.log"), "a") as fh:
|
|
fh.write("%s %s scrub=%s changed=%s shape=%s\n" % (time.strftime("%H:%M:%S"), ev["tool_name"], os.environ.get("SCRUB"), changed[0], json.dumps(shape(ev["tool_response"]))))
|
|
if os.environ.get("SCRUB") == "1" and changed[0]:
|
|
print(json.dumps({"hookSpecificOutput": {"hookEventName": "PostToolUse", "updatedToolOutput": new}}))
|