Team Context
Context Sources and Update Targets for governed coding-agent workflows.
Team Context is the product surface for Context Sources and Update Targets.
Context Sources are existing knowledge systems agents may read:
- Git docs and runbooks;
CLAUDE.md/AGENTS.md/ repo guidance;- team memory documents;
- Notion and Confluence later, once live adapters are proven.
Update Targets are places agents may propose changes:
- Git docs PRs;
- repo instruction files;
- Notion or Confluence pages, once customer-edge writeback is wired up locally. The adapters exist; live writeback against a hosted Viewport tenant is not yet proven.
Viewport should not be treated as the default plaintext source of truth for company knowledge. The default enterprise posture is customer-managed context: Viewport stores refs, policy, citations, digests, approvals, receipts, and audit; retrieval and writeback can happen at the customer edge.
A Viewport-hosted encrypted vault can remain as an advanced source type. Git-backed docs are the first-class path today.
Context is not a floating object to share from person to person. It belongs to the active team or to organization policy. Team membership, workflow policy, and runner capability decide which node can read or update which source.
For Viewport-hosted encrypted vault entries, the platform stores ciphertext and decryption happens on trusted edges that have received a key grant. For Git-backed context, Git remains the plaintext system of record. For customer-managed Notion/Confluence in the target posture, local workers use customer credentials and report metadata receipts back to Viewport.
The cryptographic model lives in Security · Team Context; this page is the product model.
The product shape
A Viewport-hosted vault is not just a bag of notes. It has a server-visible descriptor and an encrypted body log:
| Layer | What it contains | Who can read it |
|---|---|---|
| Descriptor | Vault name, description, stable id, "use this when" guidance, and "propose an update when" guidance | The platform and authorized workspace users |
| Approved index | Small routing fields such as entry ids, source, tags, timestamps, and digests | The trusted edge; only explicitly non-sensitive fields should be server-visible |
| Entry body | The actual runbook, incident note, convention, or decision | Decrypt-ready trusted edges only |
| Candidate review | Proposed changes waiting for review | Metadata in the platform; candidate body on trusted edges |
The descriptor is intentionally plaintext metadata. It tells agents when the vault is relevant without forcing them to decrypt or paste a whole vault into every run. Do not put secrets in the descriptor fields.
GitHub-backed context uses the same descriptor idea, but the body log lives in GitHub instead of Viewport. Viewport stores the repo pointer, branch, and markdown path patterns. GitHub controls repo access and plaintext storage. The trusted edge clones or pulls the repo with your local Git credentials, searches the configured markdown files, and proposes updates by pushing a branch and opening a PR when the GitHub CLI is available.
External memory providers also use a Viewport descriptor. Viewport stores the provider name, endpoint, collection, namespace, and declared capabilities. The provider remains the plaintext system of record, and the trusted edge is responsible for credentials and provider-specific read/write behavior.
How an agent uses a vault
- Your repo's
.viewport/config.yamlreferences providers undercontext.providers[]. - At session start, the daemon refreshes each saved provider:
viewport-vault: pull encrypted events, process pending grants, and process pending revokes.github-repo: clone or pull the configured GitHub repo into the daemon's local cache.external-memory: connect from the trusted edge to the configured memory service and query the configured collection.
- The daemon gives the agent the descriptor guidance first: what the vault is for, when to use it, and when to propose updates.
- For encrypted Viewport vaults, the trusted edge checks whether this device has a usable key grant.
- For external providers, the external provider's credentials and ACLs decide whether the local edge can read/write the collection.
- If the provider is readable, the daemon searches locally and gives the agent a bounded result set.
- If it is not readable, the session sees only descriptor metadata and an error that the provider could not refresh.
The daemon should not paste a whole vault into every run. It asks for a bounded result set scoped to the repo, profile, query, and item limit. Treat a big vault like a searchable library, not a giant prompt prefix.
If the agent learns something durable while using a provider, it may propose a context candidate. Candidates are still untrusted until the configured review path approves them.
The same refresh happens when the repo provider is used directly through vpd context search, vpd context get, or a trusted-edge web preview command. Raw local commands such as vpd context resolve --context ... are intentionally local-only; they are useful for debugging exactly what is already cached on that trusted edge.
If the network is down or the API rejects a refresh, the daemon falls back to the local cache. It does not block the agent just because a refresh failed.
Candidate review: the trust gate
Agents can propose new entries based on what they observed during a session. Proposals are untrusted until a human reviewer approves them through the inbox. On approve:
- The platform records the decision with an HMAC signature so the trusted edge can verify the decision came from the control plane.
- The decision does not carry the body. Only a digest and routing metadata.
- The daemon receives the decision, re-decrypts the candidate it cached locally, signs a real encrypted event, and pushes it to the platform.
For Viewport-hosted encrypted vaults, the body bytes never visit the platform in plaintext form, even during candidate approval.
For GitHub-backed providers, proposed updates become Git branches and pull requests. The platform can link to the PR, but GitHub remains the plaintext system of record. That is useful when you want team memory to behave like docs-as-code: reviewable, diffable, and governed by the same repo permissions as the rest of your team knowledge.
CLI surface
The vpd context family manages vaults, encrypted sync, and trusted-edge enrollment:
vpd context init # initialize a per-repo context store
vpd context status # show grants, devices, latest epoch
vpd context add # add an entry locally
vpd context propose # submit a candidate
vpd context use-github # attach a GitHub markdown repo as a context provider
vpd context resolve # approve / reject a candidate locally
vpd context sync-push # push signed encrypted events to the platform
vpd context sync-pull # pull signed encrypted events from the platform
vpd context sync-all # pull, materialize grants, process revokes, and push
vpd context epoch-publish # publish this trusted edge's public user/team epoch
vpd context epoch-rotate # rotate a user/team epoch with signed continuity
vpd context rotations-process
vpd context device-enroll-request
vpd context device-enroll-approve
vpd context device-enroll-accept
vpd context device-enrollments
vpd context team-grant-create
vpd context team-grants-acceptWhen you create or attach a platform vault, use guidance fields so agents know when to call it:
vpd context create qa_guardrails \
--name "QA guardrails" \
--use-when "The task changes release, test, or deployment behavior." \
--update-when "A reviewer accepts a durable QA lesson that should apply to future work." \
--use
vpd context use qa_guardrails \
--use-when "The task changes release, test, or deployment behavior." \
--update-when "A reviewer accepts a durable QA lesson that should apply to future work."To use a GitHub repo as team context, first create or choose a repo such as acme/team-memory. Then attach it from each product repo that should use it:
vpd context use-github \
--repo acme/team-memory \
--provider team_memory \
--paths "context/**/*.md,docs/**/*.md" \
--use-when "The task needs durable team decisions or incident lessons." \
--update-when "A new durable lesson should be reviewed as a PR."If the context repo does not exist yet and your local GitHub CLI is authenticated, create it from the trusted edge:
gh repo create acme/team-memory --private --clonePropose an update as a PR:
vpd context propose \
--provider team_memory \
--title "Document retry policy" \
--body "Retry queue workers at most three times before alerting."See CLI reference for the full flag set.
Local-edge storage
The daemon's local store is SQLite via better-sqlite3. At-rest encryption uses the OS key store (macOS Keychain on Darwin) or a passphrase-derived key. Default is --key-store file; pass --key-store macos-keychain for OS-backed.
Remote daemons and VPS use
A daemon on a VPS is still a trusted edge, but your browser cannot call that daemon through 127.0.0.1. The supported shape is outbound relay:
- The VPS daemon keeps an outbound relay connection open.
- The web app asks the server API for a short-lived command capability scoped to one action, such as context candidate preview.
- The browser and daemon exchange encrypted command frames through the relay.
- The daemon decrypts locally and returns the preview over that encrypted command channel.
The relay routes frames and sees envelope metadata. It should not see vault plaintext or raw context keys.
For a VPS or second laptop to decrypt, pairing is not enough. Pairing lets the daemon connect. Device enrollment grants decrypt material to that daemon:
- On the new device, run
vpd context device-enroll-request --device <id> --label "<name>". - On an already enrolled trusted edge, run
vpd context device-enroll-approve --enrollment <id>. - Back on the new device, run
vpd context device-enroll-accept --enrollment <id>.
The request is signed by the new device, approval wraps the user epoch material to that device, and accept publishes a signed materialization receipt after the device decrypts the grant.
What the docs do not promise
- Field-level encryption inside a vault entry. Entries are encrypted as wholes.
- Hard revocation for content already pulled or decrypted. Revocation blocks future access, but a device that already had plaintext cannot be forced to forget it.
- A hosted browser outside the trust boundary. If hosted web renders plaintext, that browser session can see plaintext.
Related
- Security · Team Context encryption for the HPKE suite, event log shape, and server-safe ingestion rules.
- Security · Context quality and review for how candidate updates avoid polluting team memory.
- CLI setup reference for how to attach a vault from a repo config.
- Inbox for where context candidates surface.
- Workflow YAML reference for the
viewport-config-v1field that attaches a vault. - Self-host for running the relay on your own infra.