feat(box): passkey fetch, agent key-approval flow, unified lookups, tmux agent UX

- box passkey [show|fetch] (+ muse passkey): documents VM-only passkey
  (/srv/box/passkey.txt, fallback /etc/netvm/passkey.txt on 34.139.37.135),
  probes VM over SSH with graceful fallback; --json supported. No secrets on bl.
- approvals: request_key_approval / check_node_key_request; KEY_APPROVAL status
  surfaced in `box approvals check`; allow/deny resolve + audit to box-ctl.jsonl;
  never auto-approved. New `box approvals request-key <node> --reason`.
- box lookup (summary|fleet|threads|unread|approvals|key|docs) and docs-lookup
  engine with lookup_internal/ database (docs_internal symlink).
- muse-tmux: non-TTY attach falls back to scrollback capture; prune NameError fix.
- box/muse passthrough for tmux/muse/docs; thread list/view alias + prefix resolve.
- Docs: AGENTS.md, AGENT-TOOLING.md, BOX-WEB-SURFACE-GUIDE.md, README.
- Tests: key-approval + passkey tests; sync stale sidechat UUIDs and manifest name.
- .gitignore runtime trackers (subagent-sessions, conversation-nudge-tracker).
This commit is contained in:
operator
2026-10-05 20:18:47 +00:00
parent 59c9965791
commit adfcd2e602
38 changed files with 5948 additions and 168 deletions
+11 -4
View File
@@ -280,10 +280,17 @@ def make_digest_id(agent):
# recursive box->agent->box discipline: post the RESULT back in this thread
# (box records it and dispatches the next chained step); never DM the next
# agent directly. ~166 chars, within the 600-char digest budget.
CONTRACT_FOOTER = ("Reply: [ACK id] seen | [CLAIM id] mine | "
"[RESULT id] done | [DECLINE id] | [NO-ACTION id]. "
"Report back here. Box dispatches the next step; "
"do not DM the next agent directly.")
try:
import lookup_engine
HAS_LOOKUP_ENGINE = True
except ImportError:
HAS_LOOKUP_ENGINE = False
_DEFAULT_CONTRACT_FOOTER = ("Reply: [ACK id] seen | [CLAIM id] mine | "
"[RESULT id] done | [DECLINE id] | [NO-ACTION id]. "
"Report back here. Box dispatches the next step; "
"do not DM the next agent directly.")
CONTRACT_FOOTER = lookup_engine.get_contract_footer() if HAS_LOOKUP_ENGINE else _DEFAULT_CONTRACT_FOOTER
def send_prompt(sender, agent, sidechat, digest):