While on, the admin's updates are routed as the target user's (allow-list,
chat, workspace, session, settings, jobs) and the target chat's output goes
to the admin's chat. The target's own updates are dropped with a notice that
an admin is working with their account. In memory; /impersonate 0 stops.
token.json is sealed with AES-256-GCM (key derived from the OAuth client secret,
bound to the chat), so the agent's processes can read the file but not the
refresh token. Plain files, including VolcanicSecretary's refresh_token format,
are rewritten sealed on first read.
The scheduler gains IScriptEnvironment: extra per-run variables set after the
process environment filter and redacted from the run's output. The Telegram
host uses it to pass GOOGLE_ACCESS_TOKEN, refreshed to cover the job's timeout;
the refresh token and client secret never reach the script.
Each chat's jobs live in <workspace>/.volcanic/scheduler/jobs.json. On start the
scheduler loads every chat's file, moves the retired shared
<agentDir>/scheduler/jobs.json into them and renames it .migrated-<ts>.
A VolcanicSecretary jobs.json (bare array) in a chat's folder is converted
in place for that chat; the original is kept as .secretary-<ts>.
Also adds the VolcanicSecretary data migration plan.
Jobs are prompts or watchers. A reminder is a prompt the agent passes on, so
it lands in the transcript. Stored reminder jobs load as prompts
("Remind me: <text>"). Also records the Coolify deploy target in CLAUDE.md.
Tokens now live in <cwd>/.volcanic/google-calendar/token.json, as in the
VolcanicSecretary reference, instead of <agentDir>/google-calendar/<chat
key>/. GoogleCalendarOptions.TokenDirectory, when set, keeps the old
per-chat layout under that root. Spec, docs and CLAUDE.md updated.
telegram-bot.md: what you can send, files from the agent, speech settings, security notes. ui-integration.md: document/voice input rows and a new section 5 on IChatChannel. architecture, extensions and CLAUDE.md list IChatChannel. Drop the interim paragraph from the message-context spec; mark the attachments spec implemented with resolved questions.
InputDebounce config row, the Using it section (replies, quotes, forwards, local-time header, grouping window, eyes reaction, online message, forwards never count as the login code), the Inbound paragraph in CLAUDE.md, and spec status set to implemented.
extensions.md: api.Processes and api.Redactor, ExecAsync on the policy,
ProcessSpawnEvent, ctx.TimeZone and PrepareProcessAsync, and a Spawning
processes section. architecture.md: Processes slice, the Abstractions
contract, a Processes and secrets section, and where the loop redacts.
CLAUDE.md: Processes slice and bullet.
Spec: status implemented (scheduler and MCP spawners come with their specs);
a hook returning null fails the spawn; test projects consume the one-shot
hardening from a module initializer; the Hardener seam; 'allow: none' in the
Telegram log line.