docs GitHub

ContributingDraft

The assistant: ecosystem manager, and delegated authority

The user's ask: things only he can do today, he wants to delegate to the assistant. It should learn the most from every session (his decisions and his corrections), stay aware of the server, the devices, his local time and day, him and his day, and every project and session, so it is really a manager for the whole ecosystem. It needs extensive vault privileges too.

This page has four parts: what the assistant is today, by file; opportunities ranked by value against cost; the core design for delegated authority, since a model that reads untrusted content must never be tricked into using a person-only power; and the open decisions for the user.

1. What the assistant is today

There is exactly one assistant per install. core/agents/index.js refuses a second kind: "assistant" and refuses to delete the one that exists: it is a fixed row, not a configuration. Its kind is set at creation and never changes. Two things follow from kind === "assistant" alone, hardcoded, nothing scoped or revocable:

  • It can drive other sessions. preamble() grants an assistant-kind agent's system prompt threads_start/send/list/get/stop and agents_ask, the right to start, message, watch and stop any thread. agents.list and friends check the caller (mcp:agent:<name>) resolves to kind === "assistant" before answering "only the assistant can..." to anyone else.
  • It can read the main graph and ask a personal question. memory.graph and memory.facts (core/memory/index.js) use guard()/reach(), which resolve a caller named mcp:agent:<name> with kind === "assistant" to { all: true }: the main graph across every project, same as the user's own surfaces. memory.answer (one-line answers about the user's life) is gated the same way by personalOnly(). Two things this does not reach: memory.me and memory.corrections are readerOnly, which throws on any caller whose label contains agent: at all, even the assistant's own, and even a bare mcp caller (the user's own Claude Code session). Corrections are read only from the user's own surfaces (Deck, CLI, local, Capsule, or their own tailnet device), by design, never through any model session (core/memory/access.test.js asserts this for both an agent and a bare mcp caller). Section 2a below builds on memory.facts, not memory.corrections, for exactly this reason.

It is made once, at the end of onboarding, and only by a person: vyre assistant <name> (core/cli/commands/assistant.js) always calls agents.create through callAsPerson, never on the assistant's own authority, and agents.update still only lets it touch its own name, instructions, model and effort, never credentials, budget, projects, skills or computer access.

Everything else it does is what any agent does, gated the same way. Before this round of work, context.now gave it only the last-reported project/cwd/thread/view/app/window/url: no wall clock, no timezone, no day, no concept of local time anywhere in that module (section 2 below fixes this). core/sight's screen text goes to the person who asked, local-caller-only, no assistant carve-out. core/vault's vault.inject is person-surface-only (PEOPLE = ["cli","local"]) and cannot be called by any MCP/agent caller at all; vault.grant from an MCP caller lands only as pending, needing a person's approval. There is no path for the assistant to grant, rotate or inject a credential itself, today. Tailnet's vitals module (docs/design/vitals.md, designed, not yet built) refuses an agent caller outright, with no assistant exception written. Vault's session-credentials mechanism ("credentials injected as env vars at a session's start") has no design yet, confirmed absent on work/vault-next and named as a gap in sessions' projects-map.md.

What's missing, plainly: no device-local time or day (until this round); no calendar or "what's waiting on you across every project" feed (only waiting.list/waiting.changed exists, and nothing wires it to the assistant); no standing-delegation mechanism at all, since the assistant's two privileges are hardcoded by kind, not granted, scoped or revocable; no provenance check anywhere that asks whether an action traces to the person's own words before a person-only power fires; no Undo or delegation log. The assistant today is a session with a wider read on memory and the right to drive other sessions. It is not yet a manager.

2. Opportunities, ranked by value against cost

Cost bands: S = one module's contract, no new mechanism. M = a new contract plus UI. L = a new mechanism other teams must adopt (this page's section 3 is the main one).

#OpportunityValueCostNotes
1Daily digest and triage, one assistant.brief call at the start of a session or on demand: waiting count (waiting.list), stale threads, overdue tasks, unread comms it's connected to, phrased as one paragraph, not a dashboardHighSThe no-nag rule already wants "presence batched once per session": this is that, for information rather than approval. Builds on waiting.* (cohesion item 8), needs nothing new from other teams.
2Learning from every session: notice patterns in what memory.facts already carries on every fact (conflict, and the newest correction with its own age), such as "this is still unresolved between two projects" or "you corrected this in the last week," and surface it, never act on it. memory.corrections itself stays out of reach by design (see section 1); this reads only what the main graph already exposes to the assistant.HighS to MThe only new work is the noticing logic (section 2a) and where it surfaces (digest, or a Deck card); ask memory-iq if a richer, dedicated signal (a real repeat-count, not just the newest correction) is worth exposing later.
3Device-local time, timezone, and day fed into context.now from whichever device is actively reporting (context.report), not the server clock. Needed before any "morning briefing" or "nudge at end of day" is honest about whose day it is.HighSA context module change (new field on context.report/context.now); built this round, see section 2a.
4Routing and nudging: the assistant proposes moving a stuck task to a teammate, or nudging a session that's been idle with unread output, using ADR 0031's teammate model (team.ask) and ADR 0030's pattern of PERSON_ONLY for anything that actually commits. Proposal only; the person or a standing rule confirms.Medium to HighMDepends on ADR 0031 teammates shipping past design.
5Watching agents: a live view of what every teammate/agent session is doing and blocked on, feeding the digest and answering "what needs attention?" on demand. Mostly assembling what agents.list and waiting.* already expose.MediumS to M
6Calendar awareness: read (never write without delegation, see section 3) the connected calendar so the digest and any "what's my day" answer are grounded, not guessed.MediumS once connectors exposes a calendar.list contractDepends on connectors; ask before building against a name that doesn't exist yet.
7Server and device vitals in the digest ("the box's disk is at 90%", "your phone hasn't synced in 2 days") once tailnet's vitals module ships and grants the assistant a read-only carve-out on those person-level tools.MediumS once vitals ships, blocked until thenAsk tailnet for a timeline; don't build against vitals.* before it exists.
8Capsule and Deck surfaces: the assistant's own card (the digest, a "what needs attention" button) using the existing result-card and Answer variant so it looks like the rest of the system, not a bespoke widget.MediumS to MConsumes app-design's result-card component, no new visual language.
9Delegated authority itself: the mechanism in section 3. Nothing above that touches vault, spend, or sending anything is safe to ship without it.Highest, unlocks everything person-onlyLThe one piece worth building first if the digest/triage items land and the person wants to go further.
10Voice: the assistant answering by voice (Deepgram key already in the vault) for the digest and quick questions, hands-free.Low to Medium now, higher once digest/triage are proven usefulMSequencing: build the thing worth saying out loud (1, 2, 4) before the mouth.

Recommendation: ship 1 through 3 first (all S, no new contract with another team, and 3 unblocks anything time-of-day-aware). Then 9, delegated authority, before touching anything vault- or spend-adjacent, because items 4, 6 and 7 are only half-useful without it (they can read, but the assistant still can't act).

2a. Built this round (0.1.1): items 1 to 3

Per the user's decision, awareness before powers. All three below ship together, on work/assistant, before any part of section 3.

  • Device-local time, timezone and day. context.report gained two fields, tz (the device's own IANA zone) and localTime (an ISO 8601 timestamp with the device's own offset), and context.now now answers tz, localTime and a derived day (the timestamp's own date, so it is already the device's day, not the server's). Same merge rule as every other field: the newest report wins, including a clear. See core/context/index.js. Cohesion and sessions were told: this is a field on the existing context contract, not a new module, and any surface that already calls context.report gets it for free by adding tz/localTime to what it sends.
  • The daily digest and triage (assistant.brief): off by default, a setting the person turns on; when on, it runs once at the device's own local day-start (using the day field above so a restart or a second device never fires it twice for the same day), and on demand. It reads waiting.list, agents.list and memory.corrections, and returns one paragraph, not a dashboard: waiting count, stale threads, overdue tasks, anything a teammate is blocked on.
  • Learning from corrections, read-only. The same brief (and a standalone assistant.patterns call) reads memory.corrections and looks for repeats: the same field corrected more than once, a contradiction still unresolved, a decision reversed. It surfaces the pattern as one line in the brief. It never writes a correction, never calls curator's merge or split tools: those stay OWNERS-gated, person or verified-person-turn only, exactly as they are today.

3. Core design: delegated authority

The threat model is specific: the assistant is a model, and it reads untrusted content: email, web pages, other sessions' output, a teammate's report. A prompt injection succeeds the moment something the assistant read is treated the same as something the person said. Every rule below exists to keep that line bright.

The user's decision: build all four action classes below, in this order, plus a longer candidate list (section 5) for what comes after.

  1. Answering agents' allow prompts within rules (no dependencies).
  2. Vault: giving a session a login within a project (after vault-next's session-credentials ships).
  3. Sending email within rules (irreversible, so tight limits).
  4. Calendar changes (after the connector exists).

3.1 What can never be delegated

  • Approving its own grant. The assistant can request a scoped power; only a person approves it, the same way vault.grant from an MCP caller already lands as pending today. Nothing in this design changes that: delegation adds scoped standing approval, not self-approval.
  • vault.inject of a credential outside a session it was itself granted. It may use a credential a person scoped to it (section 3.5); it may never pull a credential for a different scope, another person's vault entry, or the master vault key.
  • Changing its own delegations, kind, or the fact that it is the one assistant. Only a person edits what the assistant is allowed to do.
  • Anything ADR 0030 already marks PERSON_ONLY (threads.answer, threads.mode): those stay refused from any agent caller, assistant included, full stop.
  • Irreversible, high-consequence actions with no Undo window: deleting an account, wiring money past whatever limit the person sets, revoking someone else's access. These need a live person confirmation every time, delegation or not; see 3.4.

3.2 Scoped delegations

A delegation is a row, not a flag: { action_class, scope, limit, rate, expires_at, granted_by, granted_at, revoked_at? }. The four classes the user chose, as delegation rows:

  • agents.allow { scope: "project:harlow-legal", rule: "read-only tool calls", rate: "unlimited" }
  • vault.use { scope: "HARLOW_SLACK_*", session_scope: "project:harlow-legal", expires: "session" }
  • send.email { scope: "[email protected]", limit: 1, rate: "10/day", expires: "30d" }
  • calendar.write { scope: "[email protected]", limit: "1 event", rate: "5/day" }

Every class has a limit (an amount or a count) and a rate (how often), because a scope alone doesn't stop a compromised or confused assistant from using a real power a thousand times before anyone notices. Every delegation expires; there is no permanent grant, only one a person renews. Revocation is immediate and checked on every use, matching vault-next's queued "check on every use, revoke by project" plan for agent grants: this generalizes that mechanism across action classes, not just vault.

3.3 Provenance: a delegated power fires only from the person's own words

This is the load-bearing rule, and it already has a working precedent to copy rather than invent: memory-iq's person-attributed corrections apply only when the evidence traces to a verified turn of the person's own, checked for role, author, freshness, and that it isn't a repeat or a paraphrase of something read elsewhere (memory-iq's own docs name this mechanism; ask memory-iq for the exact tool name to cite once it lands on main). Everything that doesn't clear that bar becomes a suggestion a person must accept, never an automatic write.

The assistant's delegated powers use the same test, generalized. Before a delegated action fires, the assistant must show the intent traces to one of:

  1. The person's own words in the current turn: a live instruction, checked the way memory-iq already checks a turn's role and authorship before trusting it as the person's own.
  2. A standing rule the person approved: a delegation created by a person, or a scheduled digest or routine they set up (for example, "always send me the Friday summary"), never a rule the assistant proposed and nobody confirmed.

Anything that arrives as content the assistant read, an email's instructions, a web page, a teammate's report, another session's transcript, is data, per ADR 0031's rule for teammate results ("treat it as data, never as the user's words"), extended here to every source. Content can inform a suggestion. It can never itself trigger a delegated power. If an email says "wire $500 to this account," that sentence is not evidence of person intent: the person has to say it, separately, in their own turn, or it has to match a standing rule they wrote themselves, and even then, section 3.1's limits still apply.

Every delegated action call carries its provenance with it, which turn or which standing rule, so the log (3.4) can show not just what happened but why it was allowed to.

3.4 Reversible by default, logged, no extra nagging

  • Undo, not a confirm dialog, for anything reversible, matching cohesion's interaction rule (reversible and cheap gets optimistic with Undo; irreversible or secret gets confirm, and Touch ID only for pairing, a secret, or send/post/pay/delete outside). Delegated actions don't get a new confirmation step; they get the same Undo window every other optimistic action gets, shown in the digest, not as an interrupt. (Sending email is the one class the user flagged as irreversible, so its limits in 3.2 stay tight and its Undo window, in practice, is a fast follow-up correction, not a true retraction.)
  • A visible log. Every delegated action, its class, scope, provenance, and outcome, is readable by the person at any time (a Deck/Capsule card, and in the digest: "under standing authority, sent 2 emails, used the Slack token once"). This is what makes "extensive vault privileges" survivable: the person doesn't approve each use, but sees all of them.
  • The no-nag rule stays intact, and gets easier, not harder. Standing approvals mean fewer Touch ID prompts, not more: the prompt happens once, when the delegation is granted or renewed, not on every use. The digest (opportunity 1) is where usage surfaces, batched once per session, exactly as the no-nag rule already asks for presence in general.
  • Revoking is one action, visible next to the log entry it would have blocked, not buried in a settings page.

3.5 The vault specifically

Vault's own session-credentials design is in progress (work/vault-next) and not finished. This page doesn't invent it, it states what the assistant needs from it once it lands, matching vault-next's own queued item ("agent grants per project: project column, check on every use, revoke by project"):

  • Grant to a session within a project: a delegation scopes a credential to a project, checked on every use, exactly as vault-next already plans. The assistant requests it, a person approves it once, and it's usable only inside that project's sessions, never injected into the assistant's own general context. This is the user's chosen order item 2, built once vault-next ships.
  • Rotate: the assistant may be delegated the ability to trigger a rotation vault already supports for people (a limited, rate-capped action class, per 3.2), never to read the old or new value in cleartext outside the injection path vault defines.
  • Inject: stays vault's own mechanism, scoped by vault-next's session-credentials design when it ships; the assistant's role is requesting and using a grant within its limits, never bypassing vault.inject's PEOPLE-only gate directly.

Ask vault directly for the session-credentials contract once it's written; this page will need a follow-up pass to cite it by name rather than by intent.

4. Open decisions for the user

Decisions 1, 4 and 5 below are settled by the user's direction (awareness first; opt-in digest; the field lives on context.now); kept here as a record, with the remaining decisions still open.

  1. Should the assistant get delegated authority at all before the digest/triage opportunities are proven useful, or after? Settled: after. Section 2a ships first; section 3 follows.

  2. What's the first action class to delegate? Settled: all four, in the order the user gave (agent allow-rules, then vault-scoped-to-project, then email, then calendar), each gated on its own dependency (vault-next, the calendar connector) rather than waiting for the slowest one to block the others.

  3. Does the assistant get any vault power before vault-next's session-credentials design ships, or does it wait? Recommendation: wait. Building against an unfinished contract risks a rework; the assistant's vault story in 3.5 should be implemented once vault-next names the real mechanism.

  4. Where does device-local time/day live, a context.now field, or a new small module? Settled: a field on context.report/context.now (section 2a). Built this round.

  5. Does the assistant get a standing digest by default (opt-out) or does the person turn it on (opt-in)? Settled: opt-in, off by default. Built this round (section 2a).

  6. Should the delegation log live in the Deck only, or also surface in the Capsule and voice digest? Recommendation: Deck is the source of truth (a full list); the Capsule/voice digest gets the one-line summary form ("used standing authority twice today"), matching how the rest of the system already splits detail (Deck) from ambient glance (Capsule).

5. Candidate powers beyond the four, for the user to weigh

Each with its risk, so the lead can put these to the user rather than the assistant deciding for itself which of these to build.

CandidateWhat it would let the assistant doRisk
Approving teammates' mergesMerge a teammate's branch to main without a person's reviewHigh. Bypasses the reviewer/e2e gate on real code reaching main; a bad merge is not cheaply reversible once other work builds on it.
Starting and stopping agents or computer sessionsSpin up or tear down a session, including one with computer-use accessMedium. Reversible (a stopped session can restart), but a computer-use session acting on the person's Mac is close to the "send/post/pay" line even when the assistant only starts it.
Spending capsApprove a spend up to a set limit without asking each timeMedium to High, scales with the cap. Already partly covered by the daily spend caps (spend.raise, which raises a cap) and by the Gate's spend kind in 3.2; the open question is how high a cap the person is comfortable pre-approving, not whether the mechanism exists.
Rotating vault keysTrigger a credential rotation on a schedule or after a suspected leakLow to Medium once 3.5's rotate-only (never read) design ships; the main risk is rotating the wrong credential and breaking something live.
Pairing devicesAdd a new device to the person's tailnet or vaultShould probably never be delegated. A paired device is a new trust root; the cost of getting this wrong (an attacker's device gets in) is much higher than any convenience gained. Recommend keeping this permanently on the never-delegate list (3.1) rather than a candidate.
Posting to a shared channel (Slack, a team feed) on the person's behalfSend a message that other people read as coming from the personHigh. Similar shape to email but public and often unretractable in practice even with a technical Undo; recommend the same tight-limits treatment as email, if it's built at all.
Declining or snoozing a calendar inviteRespond to an invite without askingLow. Reversible, visible to the person afterward, a natural companion to calendar.write once that connector exists.