| name | box-companion |
| description | Generate a paired companion markdown file for a binary in the local Box Drive workspace. Describes the file contents, key facts, hash-anchored to the current SHA256 of the binary. No chunking, no embedding - the binary stays whole, the companion describes it. FS-only, no Box API. Use when the user references a binary file (PDF, CAD, image, Office doc) and asks to describe, remember, or review it. |
| argument-hint | <file-relative-path> [--team=<team>] [--tags=<a,b,c>] [--force] [--check] |
/box-companion
If you see unfamiliar placeholders or need to check which tools are connected, see CONNECTORS.md.
Produce a markdown companion describing a binary in the local Box Drive workspace. The binary stays whole — never chunked, never embedded. Hash anchoring detects when companions go stale because the underlying binary changed.
Usage
/box-companion <relative-path> [--team=<team>] [--tags=<a,b,c>] [--force] [--check]
Examples:
/box-companion files/contract.pdf — companion by path relative to workspace root
/box-companion files/drawing-A-127.dwg --tags=cad,turbine --team=engineering
/box-companion files/contract.pdf --check — is the existing companion still current?
What to do
- Verify workspace + backend. Read
_box-memory.json; confirm backend: local; confirm box-drive-detect shows mount writable.
- Resolve the binary. Construct absolute path:
<workspace_root>/<relative_path>. If file doesn't exist, surface clearly.
- Read file metadata via local FS.
stat() for size and mtime. Mime type guessed from extension.
- Check for existing companion. Look at the relevant
_index.json for by_companion_for[<file_relative_path>]. If present:
- Compute current SHA256 of the binary (stream-hash the local file)
- Compare to companion's stored hash
- Match → companion is current. Show its content. Stop unless
--force.
- Differ → companion is stale. Continue to regenerate.
- Review the file via best-available local read:
- PDF/DOCX/XLSX → fetch text representation if a local tool exists (no Box API); if not, describe by filename + size and note the gap
- CAD/proprietary formats → describe by filename + extension; honest about what you couldn't parse
- Code/markdown → read raw content
- Images → describe based on filename + size; multimodal inspection if the agent supports it
- Generate companion IDs. ULID prefixed
mem_. Slug from binary filename.
- Build frontmatter:
---
id: mem_<ULID>
slug: <slug>
title: Companion - <original-filename>
kind: companion
status: active
team: <from arg or default>
agent: box-memory-onprem
created_at: <ISO now>
updated_at: <ISO now>
companion_for:
local_path: <relative path from workspace root>
filename: <original filename>
sha256: <hash from step 4>
hash_algo: sha256
size_bytes: <from stat>
mime_type: <guessed>
reviewed_at: <ISO now>
reviewed_by: box-memory-onprem
tags: [companion, <file-type>, <user tags>]
related:
- "[[Other memories or companions]]"
supersedes: [<old companion ID>]
---
Note: in the on-prem variant, the canonical pointer is local_path, not file_id (Box assigns IDs only after sync). If Box file ID later becomes known via cloud-variant inspection, it can be added under companion_for.file_id non-destructively.
- Compose body. Sections: "What's in this file" (plain-English), "Key facts" (bulleted), "Structure" (page count / sheets / layers if relevant), "Classification / handling notes", "Related" (wikilinks), "Hash chain" (current sha256 + reviewed_at), "What the agent did NOT verify" (honest list of gaps).
- Acquire workspace lock (see lockfile protocol in
box-init).
- Write the companion file.
- Sibling layout (default):
<binary-dir>/<binary-filename>.md (e.g., files/contract.pdf → files/contract.pdf.md)
- Folder layout:
<workspace>/companions/<binary-filename>.md (or under teams//companions/)
Atomic write: .tmp + fsync + rename.
- Update folder's
_index.json. Entry with companion_for: <relative_path>, sha256: <hash>. Update by_id, by_slug, by_companion_for[<relative_path>].
- Release lock.
- Report. Companion path, hash, first ~500 chars of body, supersession info if applicable.
Hash mismatch handling
If step 4 detected a hash mismatch:
- Mention explicitly: "The existing companion was reviewed at sha256: on . The binary's current hash is sha256:. The companion is stale; regenerating."
- Show what the old companion said (one-line summary).
- Generate the fresh companion.
- Mark old companion as
superseded and link via superseded_by.
If the user asked --check, just report the result of the check — don't regenerate.
Be honest about what you couldn't read
A small honest companion ("this is a 50 MB CAD file; I cannot extract layer info locally") beats a fabricated one. Always include the "What the agent did NOT verify" section.
Differences from cloud variant
local_path instead of file_id as the binary's canonical pointer
- No metadata template instance application — that's a Box API operation
- No Box-side preview API — text extraction depends on what local tools the agent has access to (e.g.,
pdftotext if installed); be explicit when extraction wasn't possible
Errors
- File not found at relative path → "No file at
<workspace>/<path>. Check the path or run /box-status to see what's in the workspace."
- Hash computation failed → file too large to stream / I/O error; surface and stop
- Lock cannot be acquired → another writer is active; retry or investigate
- Preview extraction not possible → continue with a sparse companion documenting the gap
Don't
- Don't chunk or embed the file. The whole point is to NOT do that.
- Don't hallucinate contents you couldn't read.
- Don't skip the hash. Hash anchoring is what makes the companion auditable.
- Don't call any Box API. Don't read any URL.