feat(self-knowledge): session boot self-knowledge — vault secret names + operational facts injected at session start#811
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
42fb7eb to
5bbf3fa
Compare
5bbf3fa to
f4bb3d2
Compare
JKHeadley
added a commit
that referenced
this pull request
Jun 5, 2026
…rvive compaction (+ structural parity test) (#848) New standard, earned from PR #811's design review: the boot self-knowledge block survived three convergence rounds boot-only until the operator asked "sessions last days; won't this be forgotten after compaction?" — the whole session-context injector class (org-intent, preferences) carried the same silent gap. Rule: whatever a session must know at message one, it must still know after compaction — every session-start injector ships its compaction-recovery twin. Enforcement: tests/unit/session-context-compaction-parity.test.ts asserts every */session-context fetch in the session-start hook appears in the compaction-recovery hook, with a shrink-only allowlist for the two legacy violators (tracked: framework-issue session-context-injectors-lack-compaction-parity). Ratification: proposed to Justin (topic 19437, 2026-06-05) — his suggestion. Co-authored-by: Instar Agent (echo) <echo@instar.local> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…s + operational facts injected at session start
Closes the secret re-ask loop and the unknown-channel loop (topic 19437): an
agent session now boots KNOWING what its own infrastructure holds.
- src/core/BootSelfKnowledge.ts: bounded <session-self-knowledge> block —
vault secret NAMES (never values; shared secretKeyPaths derivation, depth-2
collapse, sanitized/clamped/alphabetical/capped, actionable truncation
marker) + self-asserted operational facts (stamped {fact,updatedAt,machine}).
Decrypt-failure honesty: exists-check, one retry, hands-off warning — never
an empty-vault lie. Module names-cache keyed on vault path + (mtimeMs,size).
- Routes: GET /self-knowledge/session-context (?full=1) behind the
developmentAgent gate (enabled ?? !!developmentAgent — dark fleet / live
dev-agent; live flip tracked as CMT-1053); POST/DELETE
/self-knowledge/facts (validated, dup/cap/ambiguity 409s, expect-guarded
delete) via the new writeConfigAtomic() temp+rename helper. Decrypt failure
is a 200 with the warning block, never a 500 (curl -sf swallows 5xx).
- Session-start hook: one fail-open fetch block (curl -sf --max-time 4
--connect-timeout 1, header-only Bearer), placed after org-intent +
preferences; always-overwrite delivery via migrateHooks.
- secret-get.mjs: hardened vault retrieval (value→stdout pipe-only,
names→stderr, value-silent on every error path) — the read path the block's
guidance names; shipped via migrateScripts + init.
- MasterKeyManager: VITEST constructor guard forces the file key — no test
can ever read or overwrite the machine-global keychain master key again
(closes the 2026-06-05 bifurcated-master-key incident class).
- Config surface (selfKnowledge.*) + ConfigDefaults + migrateConfig backfill;
CLAUDE.md template section + migrateClaudeMd parity.
- 36 tests across 4 files (unit/integration/e2e/migration), all green; spec
converged (3 iterations, codex-cli:gpt-5.5 cross-model every round).
Spec: docs/specs/session-boot-self-knowledge.md
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
f4bb3d2 to
4be71de
Compare
…ery registry + framework-shadow markers CI's feature-delivery-completeness guard caught the new section untracked: now registered in featureSections AND mirrored to the shadow-capability markers so Codex/Gemini agents learn the capability too (an unshadowed capability gets improvised around — the Secret Drop lesson). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
JKHeadley
pushed a commit
that referenced
this pull request
Jun 6, 2026
… start (Know Your Principal #898, increment 2c) Adds the READ side of the operator binding: the session-start hook now fetches /topic-operator/session-context?topicId=$INSTAR_TELEGRAM_TOPIC (the route shipped in #906) and injects the <topic-operator> block when the topic has a verified operator — so the agent reasons with its authenticated principal from message one and never seats a content name in the operator's chair (the "Caroline" fix). - PostUpdateMigrator.getHookContent('session-start'): one additive fetch-block, modeled byte-for-byte on the ORG-INTENT and AUTO-LEARNED-PREFERENCES blocks. - Compaction Parity (PR #811 standard): the SAME fetch is wired into getCompactionRecovery() so the verified operator is re-injected after a context reset — thematically load-bearing here, since losing operator awareness post-compaction is exactly the identity gap this feature closes. - Fail-open, three guards: runs only when $INSTAR_TELEGRAM_TOPIC + $PORT + $TOKEN are set; unbound topic / store-503 / unreachable injects nothing. - Cannot seat anyone — only surfaces the operator the store already verified. Migration parity: the instar/ session-start + compaction-recovery hooks are both rewritten on every update, so existing agents get the blocks automatically. Tests: 3 Tier-3 E2E lifecycle tests + the session-context-compaction-parity unit test (now green — the new injector has its compaction twin, not an allowlist entry). Analog hook suites stay green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
JKHeadley
added a commit
that referenced
this pull request
Jun 6, 2026
… start (Know Your Principal #898, increment 2c) (#908) Adds the READ side of the operator binding: the session-start hook now fetches /topic-operator/session-context?topicId=$INSTAR_TELEGRAM_TOPIC (the route shipped in #906) and injects the <topic-operator> block when the topic has a verified operator — so the agent reasons with its authenticated principal from message one and never seats a content name in the operator's chair (the "Caroline" fix). - PostUpdateMigrator.getHookContent('session-start'): one additive fetch-block, modeled byte-for-byte on the ORG-INTENT and AUTO-LEARNED-PREFERENCES blocks. - Compaction Parity (PR #811 standard): the SAME fetch is wired into getCompactionRecovery() so the verified operator is re-injected after a context reset — thematically load-bearing here, since losing operator awareness post-compaction is exactly the identity gap this feature closes. - Fail-open, three guards: runs only when $INSTAR_TELEGRAM_TOPIC + $PORT + $TOKEN are set; unbound topic / store-503 / unreachable injects nothing. - Cannot seat anyone — only surfaces the operator the store already verified. Migration parity: the instar/ session-start + compaction-recovery hooks are both rewritten on every update, so existing agents get the blocks automatically. Tests: 3 Tier-3 E2E lifecycle tests + the session-context-compaction-parity unit test (now green — the new injector has its compaction twin, not an allowlist entry). Analog hook suites stay green. Co-authored-by: Instar Agent (echo) <echo@instar.local> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ELI16
Your agent keeps asking you to re-send credentials it already has, and keeps not knowing about tools it has used dozens of times. The data was never lost — the encrypted vault and the logged-in browser seat are right there on disk. What's missing is awareness: every new session wakes up like a person with a safe in their basement and no memory of owning a safe.
This PR adds a small "what I already have" note to the context every session receives at startup: the names (never the values) of the secrets in the agent's vault, plus any operational facts the agent has recorded about its machine (like "your logged-in Telegram test seat is the default playwright profile at this path"). One rule rides along: a secret named here is in the vault — fetch it with the new hardened
secret-get.mjsscript (value pipes straight into the consuming command, never echoed) instead of asking the user to re-send it, unless it's actually invalid.Safety, in plain terms: no secret value ever appears anywhere; names and facts are sanitized so a malicious entry can't smuggle instructions into the boot context; a vault that won't unlock says "don't touch it, tell the operator" instead of pretending to be empty; tests can no longer touch the real macOS keychain (the structural guard closes the incident class from 2026-06-05); and the feature ships dark on the fleet, live on Echo — the live-fleet flip is a tracked one-line follow-up (CMT-1053) that rides #800's merge or your explicit "approve, live".
What's in the box
src/core/BootSelfKnowledge.ts— block builder: sharedsecretKeyPaths()derivation, depth-2 collapse, sanitize/clamp/alphabetize/cap, byte-bounded with actionable truncation markers, decrypt-failure honesty (exists-check → one retry → hands-off warning, never an empty-vault lie), module-level names cache keyed on vault path + (mtimeMs, size).GET /self-knowledge/session-context(?full=1) behind thedevelopmentAgentgate; decrypt failure is a 200 with the warning block (the hook'scurl -sfwould swallow a 5xx and hide it).POST/DELETE /self-knowledge/facts— agent-driven facts writer (auto-stamped{fact, updatedAt, machine}, dup/cap/ambiguity 409s, expect-guarded delete) through a new atomic temp+rename config write.curl -sf --max-time 4 --connect-timeout 1, header-only Bearer), after org-intent + preferences; always-overwrite delivery.secret-get.mjs— hardened vault retrieval (stdout pipe-only, stderr diagnostics, value-silent error paths); shipped viamigrateScripts+ init.MasterKeyManagerVITEST constructor guard — keychain structurally unreachable from tests.migrateConfigdefaults, CLAUDE.md template +migrateClaudeMd, hook always-overwrite. Agent Awareness section included.Verification
docs/specs/session-boot-self-knowledge.md, report indocs/specs/reports/).secret-get.mjswithout re-asking. Will run after deploy and report in topic 19437.Collateral findings filed to the framework-issues ledger:
sync-status-decrypt-fail-reads-empty,session-start-hook-uncapped-curls.🤖 Generated with Claude Code