Atlas recap · team intro

2026-10-12

Agents that wake up on their own

Fimo agents are chats that keep routines. A routine now wakes up by hand, on a schedule, or when something happens in the project. Next, it wakes up when another website changes. Read step 1 in 10 minutes. Open the other steps for detail.

Scope Multi-chat project · triggers, agents, watcher Base origin/develop 56d56d1 · triggers branch ab5b56d Depth Normal · step 1 in 10 minutes Evidence code reading · 1 live Dev Remote run · mockups · Linear In progress

In progress

Start here · 10 minutes

Everything in one page. Read this step. Open the other steps only for the topic you care about.

Outcome

A Fimo agent is now a chat that you keep. It has a starting prompt and routines. A routine is a task that runs without a person: by hand, on a schedule, and now when something happens. The event can come from inside the project (a publish, a content change, a form) or, next, from another website.

You never write a rule. You or the agent say it in plain words: "after each publish", "when a French blog post changes". Fimo turns the words into a small JSON rule. Code checks most of the rule for free. A very small model (Jev) answers a yes/no question only when code cannot decide.

We use this engine to build the six agents that the marketing site promises: SEO, GEO, Content, Performance, Accessibility and Compliance. Version 1 will not be good. The plan is to ship, look at real runs and iterate fast: mostly on how agents ask questions, and on moving users off the old Agents tab.

The model

An agent is a chat with routines

There is only one agent underneath. A named chat adds a lens: a starting prompt and its routines. Each routine runs in its own hidden thread.

The agent chat hears about a run only when it is worth your attention. A quiet run folds into one gray line.

Agents live in the chat listDesktop · Dev Remote · develop, PR #2970 · 9 Oct
Quiet runs fold into one lineDesktop · Dev Remote · develop, PR #2970 · 9 Oct
flowchart LR
  W[Wake-up] --> R[Routine run
own thread] R --> Q{Worth telling?} Q -->|no| S[One gray line] Q -->|yes| C[Agent chat:
message or question]

One routine run, from wake-up to the agent chat.

Wake-ups

Three ways to wake up. The third one is new

By hand and schedule are on develop. Event is the smart-trigger work. It is on a branch with 27 commits and is not merged yet.

By handon develop
Example
Run now
Use
test, one-off
Scheduleon develop
Example
Every Monday 08:00
Floor
15 min between runs
Eventbranch
Example
"After each publish"
Kinds
13 internal events
A routine with an event triggerDesktop · Dev Remote · fixture project · triggers branch
Same page on a phoneMobile 390 · Dev Remote · fixture project · triggers branch

Plain words

You say it in words. Fimo stores a rule and explains it back

The agent calls its routines tool with trigger: "...". One model call compiles the words into a rule, or refuses with a reason. The explanation that people read is built from the rule by code, so it cannot drift from what runs.

Plain wordsCompiler (1 model call)Validate against projectRule + explanationSaved on the routine
event_trigger (stored)The simplest rule: after each publish
{
  "text": "After each publish",                      // what the person or agent wrote
  "explanation": "Runs after each publish of the site.",  // built from the rule by code
  "rule": {
    "version": 1,
    "when": [ { "on": "site.published" } ],
    "limit": { "runsPerDay": 24 }
  }
}
"Run the weekly SEO check after each publish"Desktop · Dev Remote · fixture project · triggers branch
"…whenever a story changes in French" became a ruleDesktop · Dev Remote · fixture project · triggers branch

Internal events

13 project events can start a routine

All of them already exist on our event bus. Rules use product names, so a bus rename does not break saved rules.

Site

site.publishedafter a publish
site.publish_failedfailure code
domain.added / removedhostname

Data

content.changedtype · locale · fields · values
asset.changedname · mime type
form.submittedanswers
schema / form / locale.changeddefinitions

Code + chains

code.changedpath glob
branch.mergedsource branch
routine.finishedchains, 1 hop

Cost

Code filters first. A small model only when a question needs it

"When the price changes" is a code check: changedFields includes price. It is free. "When a post mentions a competitor" needs reading, so Jev answers yes or no. If Jev is unsure, the routine runs and is told to check first: a missed change is worse than an extra run.

flowchart LR
  E[Event] --> F[Code filters]
  F -->|no match| X[Nothing]
  F -->|match| J{Question?}
  J -->|no| RUN[Run]
  J -->|yes| JEV[Jev yes/no]
  JEV -->|≥ 0.7| RUN
  JEV -->|0.35–0.7| U[Run, marked unsure]
  JEV -->|< 0.35| X
  

Thresholds from rule.ts on the triggers branch.

External websites

Next: watch other websites with the same engine

Competitor pages are not in our event bus. The watcher fetches them, compares only the part you care about, and sends external.changed with values before and after. After that event, it is the same rule, Jev and run path.

Mockup · A watched price changedDesktop · fimo-mockups · chats-agents/13

What we build

Six specialist agents, 28 routines, from the marketing site

The marketing site already lists them. Each routine has a pace: daily, weekly, monthly or on publish. "On publish" is exactly an event trigger.

SEOdone
Routines
10
Example
Meta tags · on publish
GEOin progress
Routines
4
Example
Structured data · on publish
Contentnext
Routines
5
Example
Competitor monitoring · daily
Performancenext
Routines
3
Example
Image compression · on publish
Accessibilitynext
Routines
3
Example
Contrast · on publish
Compliancenext
Routines
3
Example
Brand claims · on publish

Iterate

Version 1 will be rough. We iterate on questions and on the move off the old tab

Agents ask questions with a form in the chat today. With many routines, questions pile up. We have three grouping ideas in mockups (group, triage, one at a time) and a planned Needs you list.

The old Agents tab (config-file agents) goes away. 88 real agents in 31 organizations move to agent chats with routines, with a reviewed migration.

Today: one question as a formDesktop · Dev Remote · develop, PR #2970 · 9 Oct
Mockup · Idea: 12 decisions in 3 groupsDesktop · fimo-mockups · agents-workspace 3a

Where we are

On develop, on a branch, or only designed

Status on 12 Oct, from code on origin/develop and the triggers branch, and from Linear. Green means it is on develop today. Amber means the code exists on a branch. Gray means designed only: a mockup, a plan or a Linear issue.

VerifiedAgent chats + routines (hand, schedule)

On develop: PRs #2970, #2988.

VerifiedSEO agent

On develop: PR #3003 (FIMO-2791).

PartialSmart triggers (13 events, Jev)

Branch feat/fimo-2804-publish-trigger, not merged. Migrations 0164/0165 clash with develop.

PartialGEO agent

Branch feat/fimo-2792-geo-agent, not merged.

VerifiedOne live event run

Dev Remote, triggers branch: a French story edit started a routine end to end. Rough edges in step 6.

UnknownWebsite watcher

Designed + spike. No code found.

UnknownQuestion grouping, Agents tab migration

Designed in mockups and Linear. Not built.

Branch

Smart triggers · how a rule works

The rule format, the words-to-rule compiler, the matcher and its noise controls.

Outcome

A routine can store one event trigger. People and agents only see two strings: the words and the explanation. The rule stays on the server.

The trigger lives in agent_thread_routines.event_trigger (jsonb) plus an event_trigger_on array of event kinds. The array is indexed, so one event costs one indexed lookup per project, however many routines exist.

The code is complete on the branch with unit, live-model and eval specs. It is not merged. Before merge, the migrations need new numbers, because develop already uses 0164 and 0165.

Rule anatomy

OR between clauses, AND inside a clause, one optional question

Each clause listens to exactly one event kind, so its fields are always clear. Anything more complex than one level of any becomes a Jev question.

RoutineTriggerRuletriggers/rule.ts
{
  "version": 2,                       // 2 = at least one clause asks Jev
  "when": [                           // OR: any clause starts the routine
    {
      "on": "content.changed",        // one event kind per clause
      "where": [                      // AND: every condition must be true
        { "field": "contentType",   "op": "eq",       "value": "blogPost" },
        { "field": "locale",        "op": "in",       "value": ["fr", "es"] },
        { "any": [                    // one level of OR inside a clause
          { "field": "changedFields", "op": "includes", "value": "body" },
          { "field": "changedFields", "op": "includes", "value": "title" }
        ] }
      ],
      "judge": {                      // optional: a yes/no question for Jev
        "question": "Does this post mention a competitor?",
        "guidance": "Competitors are Contentful and Sanity (the CMS) ...",
        "threshold": 0.7
      }
    }
  ],
  "limit": { "runsPerDay": 24 }       // hard cap, at most 24
}
  • Operatorseq · in · not_in · includes (lists) · gt · gte · lt · lte · matches (glob)
  • entry.<field>Reads the entry's current value at match time (FIMO-2806)
  • Limits≤ 10 clauses · ≤ 10 conditions per clause · runsPerDay ≤ 24
  • Version2 if and only if a clause has a judge. An old worker refuses v2 instead of running on every match

Worked examples

Three more shapes: a value, a question, a chain

These are built from the schema on the branch. The comment line is the words a person would type.

"When a product's price changes to over 100"code only, free
{
  "version": 1,
  "when": [ {
    "on": "content.changed",
    "where": [
      { "field": "contentType",   "op": "eq",       "value": "product" },
      { "field": "changedFields", "op": "includes", "value": "price" },
      { "field": "entry.price",   "op": "gt",       "value": "100" }   // current value
    ]
  } ],
  "limit": { "runsPerDay": 24 }
}
"When a big company submits the contact form"code filter + Jev
{
  "version": 2,
  "when": [ {
    "on": "form.submitted",
    "where": [ { "field": "formId", "op": "eq", "value": "contact" } ],
    "judge": {
      "question": "Is this request from a company with more than 200 employees?",
      "threshold": 0.7
    }
  } ],
  "limit": { "runsPerDay": 24 }
}
"After the SEO check finds something, or when a publish fails"chain + OR
{
  "version": 1,
  "when": [
    { "on": "routine.finished", "where": [
        { "field": "routineId", "op": "eq", "value": "<seo-check-id>" },
        { "field": "outcome",   "op": "in", "value": ["reported", "decision"] } ] },
    { "on": "site.publish_failed" }   // OR: also when a publish fails
  ],
  "limit": { "runsPerDay": 10 }
}

Compiler

One model call turns words into a rule, or refuses with a reason

The compiler is google/gemini-3.5-flash, one structured call, 20 s timeout, no retry loop. It gets the project's real content types, forms, locales and routines, so it cannot invent a field.

A refusal goes back to the agent. The agent rephrases or tells the person. Fimo refuses what it cannot see as an event: traffic, rankings, other websites, times (use a schedule), "before publish" and before/after comparisons.

refusaltriggers/compile.ts · SCHEDULE_INSTEAD
// "Run this when our competitor changes their pricing page"
{
  "refused": "routine_trigger_unsupported",
  "message": "Fimo cannot see changes on other web sites. Use a schedule instead:
              the routine runs at set times, checks this itself and stops when
              there is nothing to do."
}
Agent: "runs whenever a French story changes"Desktop · Dev Remote · fixture project · triggers branch
Explanation: content changes on main, type Story, locale frDesktop · Dev Remote · fixture project · triggers branch
Competitor pricing page: refused, schedule offeredDesktop · Dev Remote · fixture project · triggers branch

Judge

Jev reads one short document per item and answers all questions at once

Jev is a very small model. It cannot ask for more context, so Fimo builds the text: the event line, the changed fields, and the entry text, cut at about 8k tokens. One call per entry answers every question of a routine. Answers are stored, so a retried job asks only what is still open.

sequenceDiagram
  participant F as Fire job
  participant D as Decisions table
  participant J as Jev
  F->>D: 3 matched entries: answered?
  D-->>F: entry A: yes
  F->>J: entries B, C (all questions)
  J-->>F: B 0.82 · C 0.41
  F->>D: store B, C
  Note over F: run with A, B · C marked unsure
  

A retried job never pays twice for the same answer.

  • ≥ 0.7Matched: the run starts
  • 0.35 – 0.7Unsure: the run starts and is told to check first
  • < 0.35No run
  • ≤ 50Entries judged per fire

Noise control

A routine never starts itself, and people's changes are told apart from routines'

Routine runs write as their own actor (FIMO-2766). So the matcher knows who changed what, and most kinds react only to people's changes. Without this, a routine that edits a post would start itself again on its own edit.

flowchart LR
  A[Routine A
edits a post] -->|cause: routine A| E[content.changed] E -.-x|own change| A E -.-x|people only| B[Routine B] P[Person edits] --> E2[content.changed] --> B A2[Routine A ends] -->|routine.finished| C[Routine C] C -.-x|one hop| D[Routine D]

Three guards: own change, people only, one hop.

  • Self-loopA routine never starts from its own change or its own end
  • Chainsroutine.finished is one hop: a chained run's end starts nothing
  • People onlycontent, assets, code, schema, forms, merges, locales: only people's changes
  • Main onlyMost kinds react on main only
  • Daily caprunsPerDay counted on the run thread over 24 h
  • DedupOne job per routine + event id; a changed trigger revision skips stale jobs

A real run

One edit to a French story started the routine, end to end

On Dev Remote we changed the French title of one story with the CLI. The routine started from content.changed, worked for 5 min 54 s, and wrote its report. We set the publish trigger too, but did not fire it: one run cost about 2,200 credits.

"ran after a content change": the run's reportDesktop · Dev Remote · fixture project · triggers branch
The agent chat after the run: one row, no reportDesktop · Dev Remote · fixture project · triggers branch

Code map

Where to read the code

All paths are on the triggers branch at ab5b56d. Open a row to read the file. The triggers folder is new; the routines tool already exists on develop with its trigger parameter.

Trigger engine7 files
⌄▱apps/api/src/domain/agents/chat/triggers
⌄▱apps/api/src/domain/agents/chat/triggers/catalog
⌄▱packages/agents/src/fimo/agents/studio/tools

1 of 6 done

The agents we build next

Six specialist agents from the marketing site, built as chats with routines and smart triggers.

Outcome

The marketing site (feat/marketing-site, src/data/agent-team.ts) promises six agents and 28 routines. That list is our backlog. No agent is configured on that project yet: it is copy, not product.

Each default agent ships as a code template: a starting prompt, skills and routines. A routine that runs "on publish" ships with a stored, compiled rule, like a lock file, so a new project needs no compiler call (FIMO-2809). New projects get default agents with routines paused.

SEO is done. GEO is on a branch. Site health, Writer and Translator are placeholders and will be removed (FIMO-2797).

Today

The SEO agent shows the pattern

The SEO agent is on develop. Its daily monitoring routine crawls the site, stores a per-page snapshot in the routine's thread, and reports only the diff: pages gone, redirected, no-index, new findings. A quiet run reports nothing.

SEO agent settings: 3 routines (cards do not show event triggers yet)Desktop · Dev Remote · fixture project · triggers branch
Agent settingsDesktop · Dev Remote · develop, PR #2970 · 9 Oct
The SEO agent chatDesktop · Dev Remote · develop, PR #2970 · 9 Oct

The library

Six agents, and where an event trigger replaces a schedule

"On publish" routines need the event trigger. Until it merges, the plan runs them daily, which costs more and reacts later. Counts are routines per agent, from the marketing site.

SEOdone · 10 routines
Daily
technical SEO, broken links, monitoring
On publish
meta tags, image SEO, hreflang
Weekly / monthly
keywords, internal links, cannibalization
GEObranch · 4
Weekly
AI visibility, citation optimization
On publish
structured data, AI readiness
Contentnext · 5
Daily
competitor monitoring (needs the watcher)
Weekly
refresh, SEO writing
On publish
translation
Performancenext · 3
Daily
Core Web Vitals
On publish
image compression, mobile
Accessibilitynext · 3
On publish
contrast, headings and labels
Weekly
keyboard navigation
Compliancenext · 3
On publish
brand compliance
Weekly / monthly
cookie consent, legal pages

One routine

A default routine is instructions plus a stored trigger

This is the shape a template ships. The person sees the name, the instructions and the explanation.

default routine (template)"Meta tags · on publish"
{
  "name": "Meta tags",
  "instructions": "Check titles and descriptions on the pages this publish changed ...",
  "schedule": null,
  "event": {
    "text": "After each publish",
    "explanation": "Runs after each publish of the site.",
    "rule": { "version": 1, "when": [ { "on": "site.published" } ],
              "limit": { "runsPerDay": 24 } }      // stored: no compiler call
  }
}

Designed

Website watcher

Watch pages on other websites and start a routine when the part you care about changes.

Outcome

You tell the agent: "watch Contentful's pricing page". The agent builds a watch spec: the part of the page, what to ignore, and the values to extract. The watcher checks the page on time and sends external.changed only when that part changes.

The watcher is only a new event source. It has no rules, judge or run path of its own. After the event, it is the same engine as internal triggers. So "a price changes" is a code check on values, and "a new feature claim" is a Jev question on the diff.

We build it in-house instead of Firecrawl Monitor: about $10–20 per month instead of $180–240 for 10k pages a day (FIMO-2765). A spike on 200 real competitor pages set the approach (FIMO-2787). Linear marks the issues Done, but no watcher code exists on develop or on any branch. Please confirm the status before you rely on it.

Design

One engine, two event sources

Site events come from our bus. Watched pages come from the watcher. Both feed the same trigger rule.

flowchart LR
  B[Project events] --> R[Trigger rule]
  W[Watcher] -->|external.changed| R
  R --> F[Code filters]
  F --> J[Jev, optional]
  J --> RUN[Routine run]
  

From watcher-plan.md: the watcher must not grow its own rules or run path.

Watch spec

A small, closed language: one selector, ignores, named values

CSS only, one each level, no scripts. The hash covers the selected part after ignores. Two projects watching the same URL with the same spec share one fetch.

watch specwatcher-plan.md
{
  "version": 1,
  "url": "https://contentful.com/pricing",
  "select": "main [data-section=pricing]",       // one CSS selector: the part we watch
  "ignore": ["time", "[data-nonce]", "re:/\\d+ teams signed up/"],  // noise
  "extract": {                                     // named values to compare
    "plans": { "each": ".plan", "fields": { "name": "h3", "price": ".price" } }
  },
  "render": "auto"                                 // auto | never | always
}
external.changedwhat a rule can test
{
  "on": "external.changed",
  "kind": "values",
  "url": "https://contentful.com/pricing",
  "values": {
    "plans[Lite].price": { "before": "$300 / mo", "after": "$489 / mo" }
  }
}

Change rules

Most checks stop early. Only real changes make an event

This is what keeps the noise low: most checks end at the first test and store nothing. Only a change in the watched part makes an event, and only a value change carries before and after.

flowchart TB
  F[Fetch page] --> X{Selector found?}
  X -->|no, 2×| B[external.broken
repair spec] X -->|yes| H{Hash same?} H -->|yes| S[Stop] H -->|no| V{Values same?} V -->|yes| C[content change] V -->|no| D[values change
before + after]

From watcher-plan.md.

  • Hash sameStop. Nothing stored
  • Hash differs, values sameSnapshot, external.changed { kind: content }
  • Values differSnapshot, external.changed { kind: values, before, after }
  • Selector finds nothing 2×external.broken once; the spec builder repairs it; tell the chat once
  • Blocked 3×Move the page to the fallback fetcher and record the cost

Product

Four moments in the chat

Mockups from the planning work. They show the intended product, not a build: ask, see the routine and its pages, get a change with before and after, and open one watched page.

Mockup · Ask to watch a pageDesktop · chats-agents/11
Mockup · Routine with watched pagesDesktop · chats-agents/12
Mockup · A watched price changedDesktop · chats-agents/13
Mockup · One watched pageDesktop · chats-agents/14

Branch + plan

How triggers scale

From an event to an agent turn, which parts carry the load, and the known limits.

Outcome

An event costs almost nothing when no routine listens. Each event kind has one listener per API process, not one per routine. The listener does one indexed lookup per project: routines whose event_trigger_on contains that kind.

A match becomes a QStash job. Any API pod can take it. The job reads the entries, asks Jev if needed, and puts a message on the routine's run-thread queue in Postgres. One thread runs one turn at a time; different threads run in parallel across pods.

We have not measured capacity. The known gaps: no outbox (a crash can lose an event), no per-project flow control on routine jobs, and no batch window yet.

Path

Event → listener → QStash job → thread queue → agent turn

Every hop is one that already exists for chats and schedules. Triggers add the listener and the fire job.

flowchart TB
  P[API write:
publish, edit, form] --> L[Listener per kind
in-process] L --> Q[QStash
routine-fire job] S[Minute sweep
schedules] --> Q Q --> F[Fire: limits,
entries, Jev] F --> T[Run-thread queue
Postgres] T --> A[Agent turn
sandbox + tools] A --> C[Agent chat
if worth it]

Solid boxes on develop; listener and Jev on the triggers branch.

Who does what

API pods compute, QStash delivers, Postgres owns order

More pods add compute, up to the shared limits of the database, model providers and sandboxes. A burst multiplies: 100 events with 3 listening routines make 300 fire jobs, because there is no batching yet.

Delivery

QStashRetries on 500; dedup id per routine + event
Minute cronClaims due schedules, 100 per batch

Compute

API pod AListeners + fire jobs + turns
API pod B…NSame code, same registry

State

PostgresRoutines, thread queues, Jev decisions, leases
RedisLive stream replay
Models + sandboxesJev, agent model, project execution

Watcher (plan)

The watcher splits a control plane from a data plane

The plan keeps fetching off the API pods. Cloudflare Workers fetch and diff; the API only plans, stores and sends the result to each subscribed routine.

Control · API + Postgres

Spec builderWords + URL → spec
watched_pagesShared per URL + spec, lease, next check

Schedule

QStash tickEvery 15 min: lease due pages, group by host

Data · Cloudflare Worker + Queue

FetchSSRF guard, robots, ETag, per-host limit
Normalize + diffHash, values, R2 snapshot

Back to API

Fan outOne external.changed per subscribed watch

Limits

What protects us today, and what is missing

This is a reading of the code, not a measurement. Green rows are mechanisms we saw in code. Amber rows are known gaps we accept for v1. Gray is not known.

VerifiedIdempotency

QStash dedup id, provider message id, stored Jev decisions.

VerifiedOrdering

One live turn per thread through a database claim and lease.

VerifiedCaps

runsPerDay ≤ 24, 50 items per run, 50 judged entries per fire, 15 min schedule floor.

PartialEvent loss

No outbox: an event lost before handoff is lost. Accepted for v1.

PartialBursts

No per-project flow control on routine jobs; no 60 s batch window yet.

UnknownCapacity

No load test, replica count or provider quota checked.

Code map

Where the scaling decisions live

Paths on the triggers branch at ab5b56d. The listener is in the trigger engine tree in step 2.

Runtime3 files
⌄▱apps/api/src/domain/agents/chat
⌄▱apps/api/src/jobs

Plan

v1 will be rough · how we iterate

What we expect to get wrong, how we see it, and the two areas we change first.

Outcome

The first agents will run too often, say too little or too much, and ask questions in a way that does not scale. That is expected. The goal is a short loop: ship to internal projects, read real runs, change prompts and grouping, ship again.

Two areas need the most work. First, questions: with many routines, decisions pile up and one form per question does not work. Second, the old Agents tab: config-file agents must move to agent chats before we remove the tab.

Everything on this page is designed or decided in Linear. None of the grouping or the migration is built yet.

Signals

We see what is wrong from runs, not from opinions

Every Jev decision and every refused trigger is stored. That gives us numbers per agent. We read them each week and change prompts, thresholds and grouping.

flowchart LR
  S[Ship to internal
projects] --> R[Read real runs
+ numbers] R --> C[Change prompts,
thresholds, grouping] C --> S

The loop for v1. Customers come after the internal canary.

  • Refused triggersWhat people ask for that Fimo cannot do (FIMO-2805)
  • Unsure rateHow often Jev is unsure, per routine
  • False startsRuns that end with nothing to tell
  • LoopsDaily cap or chain depth reached
  • CostJev and agent cost per project per day

First run

Our first live run already shows eight rough edges

One Dev Remote session on the triggers branch: two triggers set, one refused, one real run. This is the list to fix or decide before customers see it. Nothing here is a surprise; it is why we ship to internal projects first.

Run said "needs a person"; chat shows only "1 run"Desktop · Dev Remote · fixture project · triggers branch
Event-only routine card says "By hand"Desktop · Dev Remote · fixture project · triggers branch
  • Run vs reportRun marked Quiet, but its text says a person must decide. The report did not reach the chat
  • Settings cardsCards ignore the event trigger: "By hand" or schedule only
  • Words vs explanationThe page shows only the technical sentence ("on the main branch, locale is fr"), not the person's words
  • Side effectSetting a trigger on a paused routine turned it on and restarted its Monday schedule
  • Hidden tool callThe chat shows the agent's summary, never the trigger it set
  • Time zones"Every Monday at 08:00 (UTC) · next Mon 10:00" mixes UTC and local
  • ScopeA title review also changed the site template, merged to main and reported to Fimo support
  • Two Agents surfacesThe old Agents tab does not list routine runs

Questions today

One question is one form in the chat

A routine never asks. It reports a decision; the agent then asks with a form. A question never expires. When it is not the last message, it folds to one line and stays answerable (FIMO-2713).

The agent asksDesktop · Dev Remote · develop, PR #2970 · 9 Oct
AnsweredDesktop · Dev Remote · develop, PR #2970 · 9 Oct
Mockup · Questions that last: fold and reopenDesktop · agents-workspace/lasting-questions

Grouping ideas

Three ways to show 12 decisions at once

These are the options to test on real runs. A planned Needs you list above the input shows the top 3 open items (decision, change to review, connection to make).

Mockup · 3a · Grouped, recommendations pre-selectedDesktop · agents-workspace/questions
Mockup · 3b · Triage: do the confident 5 in one tapDesktop · agents-workspace/questions
Mockup · 3c · One at a timeDesktop · agents-workspace/questions

Old Agents tab

Config-file agents move to agent chats, then the tab goes

Production has 1,534 deployed config-file agents. 1,419 are welcome-guide copies with nothing to move. 88 real agents with runs, in 31 organizations, need migration; 75 ran in the last 30 days.

Old Agents tab: config-file runs onlyDesktop · Dev Remote · fixture project · More → Agents
SOUL.md + description→
Becomes
the chat's starting prompt
GOAL.md→
Becomes
the routine's instructions
Schedule, manual→
Becomes
routine triggers
Webhook, model, secrets, capabilitiesdropped
Run history
not kept
flowchart LR
  A[Routines in
production] --> B[Internal projects
canary] B --> C[4 heavy customers
plan + reviewed apply] C --> D[Long tail
batch] D --> E[Tell owners] --> F[Remove the tab]

Order from FIMO-2721. apply pauses the old agent in the same transaction that creates the routine (FIMO-2817).

In progress

Plan and status

The Linear project Multi-chat, grouped by state on 12 Oct.

Outcome

One Linear project holds all of this: Multi-chat. Its idea: the chat is the only concept. An agent is a chat you keep on purpose, with a starting prompt, routines and memory.

The order is: several chats, routines, results reach the chat, site-event triggers, open questions, memory and reports, then ready-made agents, people outside Fimo, and activity.

Linear status is shown as written. Where code says otherwise (the watcher), the row says so.

Done

Shipped on develop

The base of the work. These are merged on develop; production follows the normal release train.

VerifiedFIMO-2708 · Several chats per project

The base of multi-chat.

VerifiedFIMO-2722 · A routine's result reaches its chat only when worth it

Agents are chats with routines.

VerifiedFIMO-2719 · See every routine run

Activity view, silent runs too.

VerifiedFIMO-2791 · SEO agent

PR #3003, 12 Oct.

Triggers

Trigger issues: Done in Linear, waiting to merge

Linear marks most of these Done, but all of them live on the triggers branch. Merge needs the migration renumber: 0164 and 0165 clash with develop.

PartialFIMO-2781 · Rule core: schema, validator, explainer, matcher

Branch.

PartialFIMO-2782 · Compile from words, or refuse with a reason

Branch.

PartialFIMO-2783 · Site events start matching routines

Branch.

PartialFIMO-2766 · Routine runs write as their own actor

Needed to stop self-triggers.

PartialFIMO-2809 · Default agents ship a stored rule

Lock-file style.

PartialFIMO-2784 · Jev judges matched items

In review.

PartialFIMO-2806 · Conditions on current values

In review.

PartialFIMO-2807 · More events: forms, assets, code, merges…

In progress.

Next

In progress and next

What the team picks up next. Gray rows are not started in code, or their Linear status does not match the code.

PartialFIMO-2792 · GEO agent

Branch, 4 commits.

PartialFIMO-2713 · Questions stay open and visible

PR #2891; Needs you list not built.

PartialFIMO-2716 · Memory: rules and facts

In progress.

UnknownFIMO-2720 · Six default agents from the library

Todo.

UnknownFIMO-2765 · Website watcher

Linear: Done. Code: none found.

UnknownFIMO-2721 · Remove the Agents page and migrate users

Backlog, inventory done.

UnknownFIMO-2739 · A routine's changes wait for review

Backlog.

UnknownFIMO-2715 · Measure Jev's accuracy and threshold

Backlog.

Source peek

Open at head
Path copied