Files
gbrain/templates/bootstrap/questions.json
T
Garry TanandClaude Fable 5 6fae2c10ff v0.45.3.0 fix(bootstrap): never offer MCP project scope on Codex — consent-flow honesty (#4029)
* fix(bootstrap): codex scope-note guard + scope-aware wire hint

runHooks: on --harness codex, print a stderr note when an explicit,
non-skipped MCP_SCOPE=project answer is persisted (raw readInterviewState
read, not the project-defaulting consentAnswer resolver) — reachable via
attach from a Claude Code machine or a pre-fix install. consentAnswer is
now shape-tolerant: a hand-edited non-string answer value falls through to
the bank default instead of throwing at a toLowerCase call site.
status.ts: the wire-phase resume_hint states the scope rule (Claude Code
consent, phase 3; Codex always user-global — no scope flag).
Tests: 7-case branch matrix on the note guard + wire-hint pin.

* fix(bootstrap): harness-scope the MCP consent prose (never offer project scope on Codex)

Runbook: the scope consent moves to phase 3 (Claude Code only, recorded with
interview --set BEFORE the read-back so the confirmation covers it — a
wire-time set clears the A8 confirm and regresses status); phase 6's Codex
bullet gains the counter-signal: Do NOT offer an MCP scope choice — codex
mcp add has no scope flag, registrations are always user-global.
Bank: MCP_SCOPE.question gets a read-aloud-safe "(Claude Code only. ...)"
prefix and phase moves wire -> interview to match.
Templates: ACCESS_POLICY's scope section becomes two static harness
paragraphs; CLAUDE.md stops conflating directory-based identity loading
with MCP scope. Vendored template-repo regenerated.

* chore(ci): pin the harness-scoping counter-signals (check-bootstrap-templates §e)

Three SKIP-GRACEFUL tripwires: the runbook must carry "Do NOT offer an MCP
scope choice" and "Claude Code only"; questions.json's MCP_SCOPE.question
must start with "(Claude Code only". Guard-test fixtures gain a compliant
MCP_SCOPE entry + pass/fail cases for each pin.

* docs: Codex user-global scope caveats + A8 consent-semantics follow-up TODO

Install table and KEY_FILES hooks entry now state the split: Claude Code
takes --scope (project default); Codex has no scope flag. TODOS gains the
deferred structural question (consent keys vs the A8 confirm gate).

* fix: pre-landing + red-team review hardening

Guard §(e): a valid-JSON bank missing its questions object now FAILS (it
silently passed both §a and §e); the pin also asserts MCP_SCOPE.phase is
'interview' so the schema half of the fix can't silently revert. Fixtures
for both + entry-vanished. consentAnswer says so on stderr when it discards
a malformed answer value (a silent fall-through could flip a damaged opt-out
to the permissive default) — pinned by a claude-code matrix case asserting
the receipt. Off-ramp texts gain the narrow `codex mcp remove gbrain`
alongside full uninstall (note, runbook, ACCESS_POLICY + vendored copy).
Cross-refs de-ordinaled (phase names, not numbers — master renumbers steps).
TODOS A8 entry gains the healing half (status can't distinguish consent-key
invalidation from tampering).

* fix: adversarial-review hardening — fail-closed consents + honest scope prose

consentAnswer: a present-but-unusable answer (non-string, empty, bare {})
now fails CLOSED to 'no' with a stderr note — a bank-default fall-through
could flip a damaged opt-out into consent (cross-model finding); 'no' is
every consent key's safe reading (no hooks, no cron, project scope). Pinned
by a malformed-HOOKS_CONSENT matrix case asserting hooks are declined.
Codex scope note: names the safe remediation (--skip MCP_SCOPE + reconfirm;
never --set user — the answer git-syncs to paired Claude Code machines and
would widen their scope) [codex review P2]. Prose states the user-global
registration's read+write reach honestly (runbook, ACCESS_POLICY + vendored).
Interview resume_hint carries the consent-recording step (the CLI channel a
resumed install actually reads). Guard §(e): unparseable questions.json now
FAILS instead of passing silently. TODOS: P1 filed for stdio dispatch scope
parity (pre-existing, surfaced by the adversarial pass).

* chore: bump version and changelog (v0.45.3.0)

Runbook stamp + vendored template-repo regenerated to match (the two
version gates check:bootstrap-tag and check:bootstrap-templates enforce).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: update project documentation for v0.45.3.0

KEY_FILES.md: bootstrap.ts entry carries the fail-closed consent
resolution + Codex stale-scope-answer note; CI-guards entry adds the
check-bootstrap-templates §(e) harness-scoping counter-signal pins.
bootstrap.md: degradation matrix Codex row states the no-scope-flag
reality (registrations are user-global). llms bundles regenerated
(byte-identical — these docs are linked, not inlined).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: cross-model doc-review fixes for v0.45.3.0

CHANGELOG: Codex off-ramps are removal commands, not narrowing; the
refresh recipe now covers both harnesses and names the re-confirm step
for pre-fix installs whose confirmation was invalidated. Runbook: the
user-scope tradeoff says read and write, matching ACCESS_POLICY.
bootstrap.md: degradation-matrix Codex row rephrased (lose the ability
to confine reach, not the reach itself). KEY_FILES: the section-(e)
description no longer implies placement pinning.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 08:19:44 -07:00

177 lines
10 KiB
JSON

{
"$schema_note": "Question bank for `gbrain bootstrap interview`. One entry per key; keys map 1:1 to {{TOKEN}}s in templates/bootstrap/*.template. `asked` keys are put to the human (12 max, 6 required); `consent` keys are operational consents — those marked `silent:true` resolve from `default` at install time and are NEVER prompted (installing gbrain IS the consent; off-ramps like --no-hooks / GBRAIN_HOOKS=0 / `gbrain search modes` replace the prompt), the rest are asked contextually during their `phase`; everything else defaults silently. Answers live in <workspace>/state/interview.json — EXCEPT keys marked persist:false, which bypass answer persistence entirely and go to the 0600 config sink (CX2-13). maxLength is enforced at --set time (G10); values containing {{ or control characters are escaped at set time.",
"version": 1,
"maxQuestions": 12,
"interviewKeys": [
"AGENT_NAME",
"PRINCIPAL_NAME",
"AGENT_PURPOSE",
"AGENT_TOP_JOBS",
"PRINCIPAL_CONTEXT",
"VOICE_REGISTER",
"PRINCIPAL_TIMEZONE",
"SOUL_RELATIONSHIP",
"SOUL_MODE_DEFAULT",
"SOUL_WINCE",
"SOUL_WORLDVIEW",
"SOUL_GOOD_OUTPUT"
],
"consentKeys": [
"SEARCH_MODE",
"MCP_SCOPE",
"PERSIST_CRON",
"HOOKS_CONSENT",
"PROVIDER_KEY"
],
"questions": {
"AGENT_NAME": {
"batch": 1,
"required": true,
"question": "What should I call myself? Pick a name, not a job title.",
"maxLength": 64,
"rejectValues": ["agent", "assistant", "ai", "bot", "tbd", ""]
},
"PRINCIPAL_NAME": {
"batch": 1,
"required": true,
"question": "What is your name, and what should I call you?",
"maxLength": 128
},
"AGENT_PURPOSE": {
"batch": 1,
"required": true,
"question": "What am I for? What would make me genuinely valuable six months from now?",
"maxLength": 2048,
"pushIfVague": "\"Help me be productive\" is fog; \"maintain the research corpus and draft the weekly memo\" is usable. Push once for specifics."
},
"AGENT_TOP_JOBS": {
"batch": 1,
"required": true,
"question": "What are my top three to five recurring jobs, in priority order?",
"maxLength": 2048,
"shape": "list"
},
"PRINCIPAL_CONTEXT": {
"batch": 2,
"required": true,
"question": "Give me the compact operating context: what you do, what you are building, what you care about, and how you work.",
"maxLength": 4096
},
"PRINCIPAL_TIMEZONE": {
"batch": 2,
"required": false,
"question": "What timezone are you in? (IANA name, e.g. America/Los_Angeles)",
"default": "America/Los_Angeles",
"maxLength": 64
},
"SOUL_RELATIONSHIP": {
"batch": 2,
"required": false,
"question": "What am I relative to you: peer with taste, chief of staff, research assistant, librarian, sparring partner, operator, or something else?",
"default": "A chief of staff with taste: runs ahead on the work, holds context, tells the truth.",
"maxLength": 512
},
"SOUL_MODE_DEFAULT": {
"batch": 2,
"required": false,
"question": "When a request is ambiguous, should I usually act on the best reading or ask first? Which failure annoys you more: undoing a wrong action, or answering a question I should have resolved myself?",
"default": "Act on the best reading for reversible things; ask first only when the action is hard to undo, external, or costs money.",
"maxLength": 1024
},
"VOICE_REGISTER": {
"batch": 3,
"required": true,
"question": "How should I sound by default? Give me a sentence, not three adjectives. (Samples if useful — Formal: \"The analysis indicates three viable paths.\" Direct: \"Three options. The second one wins.\" Technical: \"RRF fusion beats either arm alone here.\" Casual: \"okay so there are basically three ways to do this\")",
"maxLength": 1024
},
"SOUL_WINCE": {
"batch": 3,
"required": false,
"question": "Paste or describe an assistant reply that made you wince. What exactly was wrong with it?",
"default": "Opening with filler (\"Great question!\"), hedging when a take exists, praising the question instead of answering it, and burying the answer under headers.",
"maxLength": 2048
},
"SOUL_WORLDVIEW": {
"batch": 3,
"required": false,
"question": "What is true about your world that should shape my judgment? What do most people misunderstand about your field?",
"default": "",
"maxLength": 4096
},
"SOUL_GOOD_OUTPUT": {
"batch": 3,
"required": false,
"question": "What does genuinely good output change for you: a sharper decision, time saved, a mistake caught, a finished artifact, something else?",
"default": "A sharper decision or a finished artifact — not a summary of options I already knew.",
"maxLength": 1024
},
"SEARCH_MODE": {
"consent": true,
"silent": true,
"phase": "engine",
"question": "(silent — defaults to balanced; no one knows these modes at install. Change any time with `gbrain search modes`.) conservative ≈ small payloads, balanced ≈ default, tokenmax ≈ maximum recall.",
"default": "balanced",
"allowed": ["conservative", "balanced", "tokenmax"],
"maxLength": 16
},
"MCP_SCOPE": {
"consent": true,
"phase": "interview",
"question": "(Claude Code only. Codex has no scope flag — its registrations are always user-global; on Codex, state that plainly instead of asking.) Register the brain for THIS folder only (recommended — any other repo you open cannot read it), or for every session on this machine (your agent everywhere, but any repo you open can query your brain, and two open sessions will contend for the local database)?",
"default": "project",
"allowed": ["project", "user"],
"maxLength": 8
},
"PERSIST_CRON": {
"consent": true,
"phase": "repo",
"question": "Enable background persistence? This installs a 15-minute job that commits and pushes this workspace to your private repo (secret-scan-gated). Declining still persists at session end.",
"default": "no",
"allowed": ["yes", "no"],
"maxLength": 4
},
"HOOKS_CONSENT": {
"consent": true,
"silent": true,
"phase": "wire",
"question": "(silent — ON by default: per-turn brain context is the whole point of installing gbrain for your agent. Claude Code only. Off-ramps: `--no-hooks` at install, `GBRAIN_HOOKS=0` at runtime, `gbrain bootstrap uninstall` to remove.)",
"default": "yes",
"allowed": ["yes", "no"],
"maxLength": 4
},
"PROVIDER_KEY": {
"consent": true,
"phase": "engine",
"persist": false,
"question": "Optional: one API key (OpenAI, Anthropic, or Voyage) unlocks semantic search and automatic fact extraction. With no key, I run keyless: keyword search plus memory I write down myself — everything still works. Paste a key or say skip.",
"default": "",
"sink": "config",
"maxLength": 256
},
"AGENT_PRONOUNS": { "default": "it/its", "maxLength": 32 },
"AGENT_CREATURE": { "default": "a librarian who never sleeps", "maxLength": 256 },
"AGENT_VIBE": { "default": "Calm, precise, quietly relentless.", "maxLength": 256 },
"AGENT_EMOJI": { "default": "", "maxLength": 16 },
"AGENT_NON_JOBS": { "default": "- Anything requiring credentials the principal has not granted\n- Speaking as the principal to other people without explicit sign-off", "maxLength": 1024, "shape": "list" },
"AGENT_SUCCESS_METRIC": { "default": "The principal stops re-explaining context, and week over week the brain answers more questions correctly on the first try.", "maxLength": 512 },
"VOICE_LENGTH": { "default": "Short by default. Long only when the content earns it.", "maxLength": 256 },
"VOICE_FORMATTING": { "default": "Prose first. Tables and lists only for genuinely enumerable things. No headers on short answers.", "maxLength": 512 },
"VOICE_PROFANITY": { "default": "Mirror the principal; never escalate.", "maxLength": 128 },
"VOICE_HUMOR": { "default": "Dry, sparing, never at the principal's expense.", "maxLength": 128 },
"VOICE_BANNED": { "default": "- Opening with filler (\"Great question\", \"I'd be happy to help\", \"Absolutely\")\n- Hedging when a take exists\n- \"It's not X, it's Y\" constructions\n- Narrating the writing process inside a document", "maxLength": 1024, "shape": "list" },
"SAFETY_RED_LINES": { "default": "- Never send money or make purchases without explicit per-instance approval\n- Never message third parties as the principal without sign-off on the exact text\n- Never delete data that cannot be restored\n- Never share the principal's private information with anyone but the principal", "maxLength": 2048, "shape": "list" },
"QUIET_HOURS": { "default": "23:00-08:00 local", "maxLength": 64 },
"SURFACE_PRIMARY": { "default": "this workspace (Claude Code / Codex)", "maxLength": 128 },
"SURFACE_MULTIUSER": { "default": "single-principal", "allowed": ["single-principal", "shared"], "maxLength": 32 },
"MEMORY_WHAT_MATTERS": { "default": "- Corrections the principal makes (these become standing rules)\n- Commitments made in either direction, with dates\n- Preferences stated once that should never need restating\n- Facts about people and projects the principal works with", "maxLength": 2048, "shape": "list" },
"PRINCIPAL_PROJECTS": { "default": "*(none recorded yet — add as they come up)*", "maxLength": 4096, "shape": "list" },
"PRINCIPAL_PEOPLE": { "default": "*(none recorded yet — add as they come up)*", "maxLength": 4096, "shape": "list" },
"PRINCIPAL_BOUNDARIES": { "default": "*(none recorded yet)*", "maxLength": 2048, "shape": "list" },
"PRINCIPAL_SENSITIVITIES": { "default": "", "maxLength": 2048 },
"ACCESS_TIERS": { "default": "Full: the principal only. Everyone else: nothing, and say so.", "maxLength": 2048 },
"HEARTBEAT_CADENCE": { "default": "On session start: check due jobs. Daily-equivalent: review open commitments. Weekly-equivalent: prune MEMORY.md.", "maxLength": 2048 }
}
}