Repository navigation
feat(agents): guiding default agents - AgenticOS, Architect, next steps, profile - #2324
Conversation
A single-tenant Azure Bot reached over the Bot Connector's HTTP protocol. Every activity is believed only after its JWT checks out: signature against the issuer's published keys, the Bot Framework or the bot's own tenant as issuer, the bot's app id as audience, an unexpired token and the service the activity names. Activities from another tenant are refused, and the bot's token goes only to a Connector host. The bot answers in personal chats, group chats and channel threads; approvals and questions are Adaptive Cards decided by whoever pressed them; files reach a personal chat through the consent card. Each conversation is recorded so a reply after a restart, and a trigger's post into a team channel or group chat, know where to go. Where the deployment signs in with Entra in the same tenant, a Teams account is linked to its member through the roster's address. The console takes the app and tenant ids and builds the Teams app package. Closes #1985
The three agents a new deployment meets first answered like a reference manual (#2301). The starter "Claude Code like" is now AgenticOS, wears the product logo, and its instructions lead people one step at a time: the answer first, one question with proposed answers when a request is ambiguous, capabilities used without being asked, and one fitting next step after a task - a routine, an app, a connection - not repeated once declined. The Architect walks a person from "what should it do" to a tested, published agent, proposing defaults and explaining each choice. - A new agent with no instructions starts as AgenticOS: its prompt, opening with {{agent_name}}, plus the capabilities, skills, platform binding, starters and budget the creator left empty. default_instructions.py is gone; the template is the one source. - Every text run carries a "Your setup" section built from the spec: what the agent has, and what it has not, so "what can you do?" and "I cannot do that here" follow the switches, not a stale prompt. - Platform MCP: update/test/publish an agent draft, list models, routines (list, create, update, run now, delete), MCP server search, the caller's connections, and set_my_language - the one write no binding holds for approval. - users.locale (0159_user_locale) and PUT /users/me/locale; trigger, model-profile and own-connection routes are public API; run takes "draft": true for a test run of the draft. - AgentSpec.starters (up to four, blanks dropped), exposed on the listing from the published version; spec version unchanged. Refs #2301
- The console follows user.locale on every device; the language menu keeps the choice on the account, and an agent's set_my_language result switches the open page without a reload. - First messages: a Builder card under the instructions edits spec.starters, and an empty chat offers them; an agent with none gets the chat's own openers, now "What can you do?" and "Set up a routine". - The walkthrough has a stop for the new card. - The platform server card marks set_my_language as never asking. - The seeded starter agent is found as @AgenticOs. Refs #2301
Rename Claude Code like to AgenticOS across install, deploy, first agent and capabilities; describe the Architect building and publishing agents, the platform MCP tools for drafts, routines and the console language, draft runs and the newly public routes in the API page, the language kept on the account and first messages in the console page. Translated into pl, de and es; the Architect's guide copies regenerated with the backend commit. Refs #2301
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
Security findingsAdvisory findings (6)
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
…agents # Conflicts: # CHANGELOG.md
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Here are some automated security review suggestions for this pull request.
Reviewed commit: 16a01708c9
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 16a01708c9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- list_models called /model-profiles; the route is under /providers. A test now checks every platform tool's call against the public routes the app mounts, so a wrong path or a private route fails. - A key reaches /me/mcp-connections and /users/me/locale only when it was issued for agents:run, as the credential a run is minted holds; a session still reaches both with no organization active. - Bootstrap counts the starter's former @claude-code-like handle as the starter, so a rerun on an older organization installs no second one; the walkthrough finds it under either handle. - The console adopts a locale only from the platform's own agenticos_set_my_language, not from another server's tool of that name, and keeps the query string when it switches. - E2E fixtures name the seed AgenticOS; the Architect's description no longer contains the word, so the two agents are told apart. - The setup briefing's joined strings are explicit. Refs #2301
…tarter An organization that already has @claude-code-like gets @AgenticOs too when bootstrap is rerun, so the former-handle check and the walkthrough's fallback go. Refs #2301
- Platform MCP tool tests use fixed ids: the route check parametrises on paths, and uuid4() made each xdist worker collect different tests. - The locale BFF route mounts every verb like the others and is in the proxy-route test, so the frontend gate counts it. - E2E: the seeded agent's description and instructions are AgenticOS's, and a delegate's token count may be grouped (1,335). Refs #2301
… you The second round of #2301, everything decided in its Q&A. - Follow-ups: a `follow_ups` capability whose `suggest_next_steps` puts up to three next steps as buttons under the latest answer. On in AgenticOS and the Architect, left out of voice calls. - A capability an agent lacks gets a card in the chat: an editor switches it on (published at once only when the draft held nothing else), anyone else asks the owner, who is notified. New console-only routes under /agents/{id}/capabilities/{capability_id}. - Under a person's own message: make it a weekly routine, or ask the Architect to build an agent of it. Under an answer: what the agent remembered or forgot, with a link to manage it; asked to forget, the agent deletes the note. - What agents know about the person: role on the walkthrough's first card, role, work and time zone in Settings -> Profile, the time zone taken from the browser until chosen. Every run is told them after its instructions, and a schedule reads times in the account's zone. - A routine's finish notifies its creator with the start of its answer instead of the generic run-completed one; a weekly_tips template. - Your first steps: a card on the person's own dashboard. - POST /agents fills the whole starter only with from_starter, as New agent sends; /users/me/locale and /me/mcp-connections need a key issued for agents:run. Migrations: 0159_user_locale becomes 0159_user_profile (adds time_zone, job_title and about beside locale); 0160_capability_requested adds the notification event. Both renumber on the next merge with main, which now holds its own 0159. Docs in en, pl, de and es; the Architect's guide regenerated. Refs #2301
…agents Main took 0159 for the default organization (#2187), so this branch's migrations follow it: 0160_user_profile and 0161_capability_requested. The CHANGELOG keeps #2301's entries and the default organization under [Unreleased], and the benchmark under the 1.10.2 cut; the api.md translations hold both sides and are stamped again.
CI on f86a8ae found three things: - A delegate was told "the person you are talking to" too, because it reuses the run's variable renderer. A delegate answers the agent that called it, so the runner now keeps the two apart: `_RunRendering` carries the variables every agent reads and the person only the run's own agent is told about. - The data-protection report has to classify every capability; the follow-ups capability sends nothing out of the process. - The getting-started card navigated with the locale router, which the dashboard's integration test cannot construct. It links with `next/link` like every other card, and a done step is plain text. Refs #2301
…agents Brings in the 1.11.0 cut and #2328. The empty chat offers an agent's own first messages first, then #2328's visual openers for an agent that draws, then the chat's own four. The CHANGELOG keeps both PRs' entries under [Unreleased]; the capabilities translations hold both sides and are stamped again.
Microsoft Teams (#2188) ships with #2301 in one release, as decided. Its migration follows this branch's: 0135_teams_channel is now 0162_teams_channel on top of 0161_capability_requested; the exposure CHECK it rewrites has not changed since the baseline. Brought up to date with what main gained since 18 October: no `from __future__ import annotations`, the A2A surface beside Teams in the routers, enums, filters and copy, the project and remote-agent routes, the brand-icon generator's full-colour sets with `simple8` kept only for the Teams mark, the speech-to-text fields in the add-bot dialog, and the docs tables in all four languages (the `@`-mentions row gains a Teams column). Translations stamped again. Refs #1985, #2301
Round 3 of #2301, its backend. Everything proactive runs in the worker; a request only ever queues a job. - A nightly look at each person's week (THINK_FOR_PERSON, queued by an hourly PROACTIVE_SWEEP early in their own morning): one structured call on the starter agent's model that notices requests repeated three times, proposes a profile update from what the agent noted, writes the empty chat's first messages for them and picks a role pack. Skipped at no cost when nothing is new. - Every such call is a run row (surface `proactive`) under the starter agent, so its cost is in run history and the monthly total, and it is refused past the organization's cap or its new per-person proactivity limit (`organizations.proactive_limit_usd`, $1 by default, zero is off, `budgets:manage` to change). - Proposals wait as suggestions, deduplicated per person so a dismissed one is never made again, announced by one `suggestion` notification a day. `/me/suggestions` lists them; accepting a profile update writes it, a role pack is queued (INSTALL_ROLE_PACK makes its routines once each), anything else is the console's to carry out. - A new member is greeted in Slack, Mattermost and Teams (WELCOME_MEMBER, queued where an invitation, the default organization or directory sync adds them), found by address; Slack's manifest gains `users:read.email`. One attempt, a failing platform does not stop the next. - Working hours on the profile, told to every agent; knowledge only. Migration 0163_proactivity: `suggestions`, `users.working_hours`, `users.personal_starters(_at)`, `organizations.proactive_limit_usd`, and the `suggestion` event in both CHECKs. Also the surface-parity and security-marker checks the Teams merge left red. Refs #2301
The console half of the background initiative in #2301. - The starter agent's empty chat carries what the night proposed, as cards: a routine opens the routine dialog filled in, an agent asks the Architect, a profile update and a role pack are saved by the server, and "Not now" declines for good. Its first messages are the ones written for the person, after the agent's own. - `?agent=` (a handle or an id) selects that agent in the chat, which is where the suggestion notification lands. - Settings -> Profile gains working hours: day toggles named by the browser in the console's language, and start and end times. - The members page gains the per-person proactivity limit beside the organization's own, gated on `budgets:manage`. - The bell and Settings -> Notifications know `suggestion` and `capability_requested`, which round 2 left out. Refs #2301
More of round 3 in #2301: - `propose_setup` in the follow-ups capability: up to three proposals - an agent, a routine, a connection - drawn as cards under the answer, each acted on in one click (the routine dialog filled in, a question to the Architect, the MCP servers page at its add button). What the welcome interview ends with. - `set_my_profile` on the platform's MCP server, through the new public `PATCH /users/me/agent-context` (role and work only, a key issued for `agents:run`); ungated like `set_my_language`, and the open console adopts what it saved. - `create_skill` on the platform's MCP server, held for approval like every other write, for "make a skill of this". - A console link an agent writes in the chat opens that page and points at the control its `?highlight=` names, as the Architect's do. Still to come in this round: the prompts that use these, tests for the setup cards and the profile adoption, follow-ups in the chat apps, the docs and the changelog. Refs #2301
More of round 3 in #2301: - AgenticOS gets to know somebody the account knows nothing about: three questions, one per turn, then `set_my_profile` and up to three `propose_setup` cards drawn from the answers. A person who skips it, or starts with real work, gets the work. - A table of console links with `?highlight=` anchors, for the places a member looks for, and the Morning briefing offered once, beside the Weekly tips. - "Make a skill of this": AgenticOS writes one with `create_skill` when asked, and a button under an answer hands the Architect the request and the answer (cut at 2000 characters) to write it from. Shown to somebody who may write skills while the Architect is there. - A test that every `?highlight=` a shipped template writes names an anchor the console renders. - Tests for the setup cards, `setupProposalsOf` and adopting a saved profile. Refs #2301
…and Teams An answer that ended with `suggest_next_steps` lost its steps in a chat: the tool tells the model not to list them, and nothing drew them. Now they are posted under the answer as a message with a button per step, kept as a `channel_prompts` row of the new kind `follow_up`. A press is the presser saying that step: the worker replays it through the router as their next message in the chat it was offered in, so the link, the bot's access policy and the rate limit apply as they do to typing. The button names a row and an index (`aosnx:`, within Telegram's 64 bytes), the row is the bot's own and is taken once, and the pressed message then reads the step instead of its buttons. A follow-up row named through an approval's value answers nothing. `0164_channel_next_steps` adds `chat_type`, which the replayed message needs and a press does not carry, and widens the kind check. Verified up, down and up again, and `alembic check`, on a pgvector database. Refs #2301
What round 3 of #2301 changed, where a reader looks for it: - Capabilities: `propose_setup`, and next steps reaching the chat apps. - MCP and API: `set_my_profile` (never held for approval), `create_skill`, and `PATCH /users/me/agent-context`. - Console: the welcome interview, what the nightly look proposes, the "make a skill of this" button, links that point, working hours. - Governance: proactive work, its per-person monthly limit and the `suggestion` event. - Channels: next steps as buttons, the welcome DM and the Slack `users:read.email` scope an existing app needs a reinstall for. - Data protection: the profile fields, `suggestions`, and what the nightly look and the welcome send out. Translated into Polish, German and Spanish and stamped; the Architect's guide copies of mcp.md and api.md regenerated; CHANGELOG entries under [Unreleased]. Refs #2301
A look through a connection whose sign-in lapsed reads nothing, and the watch still showed as working. Its row now says to sign in again, and the Proactivity card's model hint names the watches it also runs. Refs #2301
A watch's update was dumped by hand, which the update-schema guard refuses, and WatchUpdate named no row it writes. The personal-data route test built an export without the new watches collection. Refs #2301
opentelemetry-api 1.44.0 carries GHSA-xcq7-p3pf-p88h and failed make audit on every branch. The OpenTelemetry packages Logfire brings in move together: 1.45.1, and 0.66b1 for the instrumentations. Lockfile and third-party notices only; make audit is clean. Refs #2301
Findings from a watch that are not urgent no longer wait silently for the person to open a chat. Once a day, at the organization's proactive hour, the sweep queues one briefing per person: a notification and a direct message from each Slack, Teams and Mattermost bot that knows them, listing what is new. suggestions.briefed_at keeps each finding in a single briefing. The console gets an Inbox page under Chat, with a count in the sidebar, filters by source and a Done view that brings a declined item back. The dashboard's suggestions card becomes Briefing, urgent first, at the top of the personal view. Migration 0168_finding_briefed. Refs #2301
…a list After a look at stage 2 on a live stack: - Watches move to Routines: a Watches card says, per watch, which account it reads, how often and when it last looked, and how many of its findings wait in the inbox; New watch sits in the header. A watch started from an account's menu says where it now lives. Settings > Assistant only points there. GET /me/watches carries `waiting`. - The organization's list of servers that may be watched is gone: any server a person connected may be watched. 0167_watches is edited in place rather than followed by a drop, as it has not left this branch. - Inbox and the dashboard's Briefing are one mail-like list: a row each, the source's mark, its source and time, the answers in the row, the filters in the card's header; ?filter=watches opens it narrowed. The empty chat keeps its cards; both share one set of actions. - Get started and Your first steps were the same card twice: one Get started now, the person's own steps first and the organization's after them for builders, the next one saying what it is for. - Account and provider selects show each one's mark and its catalog name (the watch dialog, the organization's speech-to-text provider). Refs #2301
The inbox filters carry an icon each; ChoiceGroup takes an optional icon per choice for it. The empty chat offers only the first suggestion, what cannot wait first, with a link to the rest in the inbox: four cards above the starters buried them. Refs #2301
…riefing Get started and the Briefing now share the first row of the personal dashboard, half each. Once the checklist is done or closed the Briefing takes the whole row. The Briefing leaves the personal view's default grid, where it would otherwise show twice; it stays in the catalog. Refs #2301
Half a row wide, the card's line of ticked labels left most of it empty. It is a checklist now: the person's steps and, for a builder, the organization's under their own headings; a done step is one quiet line, a step left keeps its mark and what it is for, and the next one is raised and labelled. The Briefing beside it now stretches to the same height. Refs #2301
A ring with how far along, the next step raised in a panel of its own with what it is for and a Start button, the other open steps as rows under it, and what is already done as a line of chips at the foot. Refs #2301
- A server's accounts are opened by key, kept in the URL as ?server=, and read from the live connection lists: a disconnect shows at once, where the dialog held the row it opened with until it was reopened. - A consent started on the servers page comes back to that server's accounts rather than to the top of the list. - In the Builder, a consent run in another tab lands that tab on the server's accounts, and this tab refetches its connections on return; with focus refetch off, "it appears here once authorised" was untrue until a reload. - Watch sits beside Tools on a connected personal account instead of in its menu. Refs #2301
…agents # Conflicts: # CHANGELOG.md
A worker killed mid-call left no run, so the per-person limit and the due check never saw the call. A run that fails after the provider answered (output validation out of retries) booked zero tokens; the usage is now accumulated across the run and priced on failure too.
What it saves is appended to every agent the person runs, in every organization, so a page an agent read could prompt-inject a profile that persists. Only set_my_language stays ungated.
The card chose enable or ask from the scoped agents:edit permission, which a Member holds for their own agents only, and which an explicit edit grant reaches without. It now always tries enable and asks the owner on a 403.
A nightly look still queued at the next sweep was queued again and both copies passed the same spend check; two acceptances of a role pack - a double click - each installed its routines. Each job now carries a dedupe key with active-job deduplication.
Opening the dialog accepted the suggestion, so cancelling it or a refused create removed the card with no routine made.
…nization The nightly look writes them from one organization's conversations, memories and routines, and they were kept on the account: a person in two organizations was offered one's requests in the other's chat, and each night overwrote the other's. They move to the membership (0169_starters_per_membership), are read from GET /me/suggestions/starters for the active organization, and are exported with the membership.
… markup A shared file's address and an accepted file's upload address are the Teams client's to write, and the bot fetched and PUT to any HTTPS address they named. Both now go through PinnedAsyncClient, SSRF-checked and pinned on every hop, and a refused upload ends quietly. The markup regexes ran quadratic on a message of unclosed tags; each scan now stops at the next "<".
…agents # Conflicts: # CHANGELOG.md # docs/configuration.de.md # docs/configuration.es.md # docs/configuration.pl.md # docs/mcp.de.md # docs/mcp.es.md # docs/mcp.pl.md
…nization The unreleased #2301 entries still said set_my_profile is never held and that the first messages are kept on the account; both changed in the Codex round. Also marks the new approval test as a security refusal.
…chat Every empty chat mounted the query, so a surface without a query client - the Builder's test chat in its tests - failed to render. The starters are read by a welcome rendered for the starter agent alone.
The Builder's connect entry invalidates the connection list since 221d5ab, so its page tests need a QueryClientProvider as the app has. The notifications page names the finding switch "Findings from your watches" since the watches stage; the test still said "Urgent findings".
Promotes `[Unreleased]` to `[1.15.0] - 2026-10-23` and bumps `backend/pyproject.toml`, `backend/uv.lock` and `frontend/package.json`. Ships #2324: the guiding default agents, proactivity, watches and the Microsoft Teams channel. New things a member and an operator can do, so MINOR.
…-and-video Brings in 1.13.1 to 1.15.0 (#2324 among them). Main took 0160 to 0169, so this branch's 0160_generated_media becomes 0170_generated_media on 0169_starters_per_membership. The registry, worker and capability tables keep both sides: speech and video beside follow-ups, the media sweep beside the proactive sweeps.
What this changes
The three agents a new deployment meets first - the starter agent, the Architect and a blank new agent - answered like a reference manual. This makes them guide people: lead with the answer, ask one question with proposed answers when a request is ambiguous, use what they have without being asked, and offer the one next step that fits. Closes #2301.
general/agenticos,avatar.pngrendered fromdocs/assets/logo.svg). Only new organizations get the new name: an agent's handle never changes, so@claude-code-likeon existing deployments stays as it is, and rerunning bootstrap there installs AgenticOS beside it.from_starter: true, and the server fills in the starter's prompt (it opens with{{agent_name}}) plus whatever of its capabilities, skills, platform MCP binding, starters and budget the creator left empty. Without the flag,POST /agentsonly gives a spec with no instructions the starter's prompt.default_instructions.pyis removed; the template is the one source.app/agents/setup_briefing.py): the capabilities it has, in the Toolbox's words, and the selectable ones it lacks, with their ids. Plumbing capabilities are left out.update_agent_draft,test_agent_draft,publish_agent(needsagents:publish, always held for approval because the platform binding cannot benone),list_models,list_routines/create_routine/update_routine/run_routine_now/delete_routine,search_mcp_servers,list_my_connectionsandset_my_language.set_my_languageis the one write no binding holds for approval (UNGATED, mirrored inPLATFORM_UNGATED_TOOLS, with a test that keeps them equal), and the Builder's platform card labels it.users.localeandPUT /users/me/locale. The console follows the account on every device (AccountLocale), the language menu saves the choice, and when an agent'sset_my_languagecall answers, the open page switches without a reload.AgentSpec.starters(up to four, max 200 chars, blank ones dropped so the Builder can save while you type; the field is optional, soSPEC_VERSIONis unchanged). Builder card under the instructions with a tour stop; the empty chat offers them, and an agent without starters gets the chat's own openers, which now include "What can you do?" and "Set up a routine". The Architect ships with four.POST /agents/{id}/runtakes"draft": true(refused withPrefer: respond-async). The trigger routes,GET /providers/model-profiles,GET /me/mcp-connectionsand the locale route are reachable with an organization key; the last two need a key issued foragents:run.prompting.md, with reference reading of the public Codex, Grok and OpenClaw prompts.Round 2 (the second Q&A)
follow_upscapability:suggest_next_stepstakes up to three steps of at most 80 characters, and the console draws them as buttons under the latest answer (TurnExtras). A click sends one. On in AgenticOS and the Architect;voice="never", since a call has nowhere to show them.request_capability. Its card lets someone holdingagents:editswitch the capability on (POST /agents/{id}/capabilities/{capability_id}/enable). It is bound as the starter binds it and validated like a publish, and it goes live at once only when the draft equalled the published version and the caller may publish; otherwise it waits in the draft. Anyone else asks the owner (/request, newcapability_requestedevent). Both routes are console-only.architect-ask-store). Under an answer: "Remembered: … · Manage" / "Forgot: …", and the memory capability's preamble now tells the agent to usedelete_memorywhen asked to forget.users.time_zone(validated against IANA),job_titleandabout. They are set from the walkthrough's first card (role) and Settings → Profile, and the time zone comes from the browser until one is chosen.app/agents/person_briefing.pyappends a "The person you are talking to" section after the instructions on every run that is about a real person, and a schedule reads times in the account's zone._notifyno longer sends the genericrun_completedforSCHEDULE. Aweekly_tipstrigger template, which AgenticOS offers once.agents:run. Each step is ticked from real state, not from clicks.Migrations, after main took 0159 for the default organization:
0160_user_profile(nullablelocale,time_zone,job_title,about; nothing backfilled) and0161_capability_requested(both event-type CHECKs).Testing
Run locally (targeted, per the repo rules):
uv run pyteston every touched file, plus the guards that read them: registry (includingenable_capability/ask_for_capability), notifications (routine_finished,capability_requested), triggers, runner, prompt variables, the newtest_follow_ups_capability.py,test_person_briefing.pyandtests/api/test_capability_card_routes.py, users, privilege escalation, API key service, capability registry, voice, coverage gate, Architect guide, and the files main's merge touched. Last batch: 1560 passed, then 605 after the merge.bunx vitest runon the new and touched specs: turn extras (lib and component), turn shortcuts, capability requests API, the getting-started widget, account time zone, agent-context settings, the profile hook, the Architect ask store and widget, tour role and tour, message item and list, dashboard registry and layouts, create dialog, use-agents. All passed, and the new files are at 100% except two branches in pre-existing code.make lint-backend,make lint-frontend,make docs-build: clean. Docs updated in en, pl, de and es and stamped.alembic checkclean; the integration tests for proactivity (8) and channel prompts (5, including thefollow_upcheck constraint) pass against it. Unit tests for every touched module (proactive service, suggestions, channel welcome, next steps, prompts, router offer, templates and their?highlight=anchors), and vitest for the suggestion cards, setup cards, skill shortcut, message list and item, turn extras and account context - the new frontend files at 100%.make lint-backend,make lint-frontendandmake docs-build --strictclean after merging main (1.12.2).Not done here, by agreement: the before/after evaluation the issue lists. Kacper tests the prompts himself.
Noticed, not fixed
make platform-bootstrap) gets the Architect on first look but no AgenticOS agent; only bootstrap installs the starter.Round 3 (decided 2026-10-22)
Everything proactive runs as a background job on the worker queue or a schedule, never inside a request. What it proposes lands in the bell (new
suggestionevent) and as cards in the empty AgenticOS chat. Every model call it makes is a run from the newproactivesurface, capped per person per month by the organization'sproactive_limit_usd($1 by default, 0 switches it off, set beside the spending limit, needsbudgets:manage).Onboarding
set_my_profileplatform tool (PATCH /users/me/agent-context, held for approval like every write; the open console adopts it) and ends with up to threepropose_setupcards - a routine (the routine dialog filled in), an agent (a question to the Architect) or a connection (MCP servers at its add button).core/catalog/role_packs.json); accepting it queuesINSTALL_ROLE_PACK.GET /me/suggestions/starters) and shown after the agent's own starters in the empty AgenticOS chat.WELCOME_MEMBER(one attempt): each active bot finds the person by email and sends one DM in their console language. The Slack manifest gainsusers:read.email; an existing Slack app keeps working and welcomes nobody until reinstalled.Proactivity
PROACTIVE_SWEEPhourly, people at local 4-6 who are due), only when something new happened. A dismissed proposal is kept so it is never made again.daily_briefingtemplate, like the weekly tips.From chat to something kept
skills:edit; AgenticOS and the Architect save it with the newcreate_skillplatform tool, held for approval like every write.Surfaces
0162_teams_channel); feat(channels): a Microsoft Teams bot #2188 closed as superseded. Closes Channels: Microsoft Teams bot - personal chat, channel mentions, approvals as cards #1985.channel_promptsrow of the new kindfollow_up; a press is replayed through the router as the presser's next message, so the link, access policy and rate limit apply. Its own value prefix (aosnx:), claimed once.?highlight=anchors, and a link an agent writes in the chat opens in the console and points at the control. A test checks every?highlight=a shipped template writes against the console'sdata-touranchors.?agent=<slug>in a chat link selects the agent.Migrations for round 3:
0163_proactivity(suggestions,users.working_hours,users.personal_starters(_at),organizations.proactive_limit_usd, thesuggestionevent) and0164_channel_next_steps(channel_prompts.chat_type, thefollow_upkind). Every migration on the branch, Teams' included, was applied from scratch, reverted and reapplied on a pgvector database, withalembic checkclean.Considered and dropped: the router to specialists (subagents and
@mentions already cover it), the quality loop, shareable recipes, the prompt improver, pinned example conversations, a weekly summary and onboarding by voice. The setup cards are console-only; a chat app shows the answer without them.The Codex round (2026-10-23)
All 28 open threads are answered and resolved. Twelve were already fixed by earlier commits (
b2ccfe243and the Teams fixes), and the threads now name the commit. Fixed in this round:set_my_profileungated: a page an agent read could persist a profile into every later runset_my_languagestays ungated (ca8723772, docs ×4)RunUsageaccumulated and priced on failure; the run is committed before the provider call (f8f488e36)agents:editresolve_accessdecides) and asks the owner on a 403 (c47c0a7a6)dedupe_key+dedupe_activeon every per-person and per-watch job (13eba546c)onCreatedonly (15e86e4b4)organization_members(0169_starters_per_membership), read per organization, exported with the membership (56b6caa6c)PinnedAsyncClient; each regex scan stops at the next<(c5762576d)Not changed, as false positives: CodeQL's log injection (
TeamsAuthErrormessages are constant), and the two OAuth return-cookie alerts (an app path read back throughisSafeReturnPath).Verified locally: the touched backend files (871 tests after merging main 1.14.0), the touched vitest specs,
make lint-backendandmake lint-frontend. The chain to0169was applied, reverted and reapplied on a scratch pgvector database withalembic checkclean, and the personal-data and proactivity integration tests pass against it.