NaramAlhasani

I design, architect and build software products.

2 product slots open for Q4
  1. Built MATTER, the project platform that replaced Procore at Delta Construction, a $9M general contractor: about 180 active projects, $14M in contracts, and a $48K-a-year bill gone.

  2. Recovered 25 years of a contractor’s history from a locked Access database: $54M of past projects and 4,500 client contacts, now a cloud ERP.

  3. Built a 234-tool MCP server so Claude can work inside a live construction platform with each person’s exact permissions.

Read my work

Things I’ve built

10 systems, 7 with live sites

  1. 01.1

    MATTER

    Construction project platform. Runs about 180 active projects and $14M in contracts at Delta Construction: chat, RFIs, submittals and bids in one place, showing who owes the next move.

    Live · runs Delta Construction

    Full page →
    Fig.A project platform for design-build teams, made for the people on site with a phone or an iPad. Delta Construction, a $9M general contractor, runs on it, as Delta Portal.

    Architecture

    1. AClients· 4Web app · Respond by link · Missive sidebar · Claude & MCP clients
      • Web appNext.js 15 · React 19UI

        UI · Next.js 15 · React 19

        The app people use on site and in the office, built mobile-first for phones and iPads with gloves on. Its types are generated from the Java DTOs, so the front end and back end can’t drift.

        Talks to

        • → Public API (HTTPS · JWT)
        • → Live sockets (live)
      • Respond by linkRFI · submittal · bid · exhibitUI

        UI · RFI · submittal · bid · exhibit

        Pages outside the app that architects, engineers, subs and clients open from an emailed link or a short typed code: answer an RFI, review a submittal, submit a bid, approve a drawing exhibit, join a contractor’s network. No account needed.

        Talks to

        • → Public API (token)
      • Missive sidebarCRM in the inboxUI

        UI · CRM in the inbox

        A panel inside the shared inbox: it recognises the contact on an email, logs the interaction, and sets a follow-up without leaving the conversation.

        Talks to

        • → Public API
      • Claude & MCP clientssigned in as a userEXTERNAL

        EXTERNAL · signed in as a user

        Claude Desktop or any MCP client, signed in as a real person through OAuth. It gets exactly what that person could do in the app.

        Talks to

        • → MCP endpoint (MCP)
        • → OAuth server (OAuth)
    2. BGateway· 3Public API · Live sockets · MCP endpoint
      • Public APISpring Boot · JWT · keysSERVICE

        SERVICE · Spring Boot · JWT · keys

        The only door in. It checks the JWT or an integration API key, resolves the user, company and tenant once, throttles the endpoints that could be abused, and forwards each request to the platform with signed identity headers.

        Talks to

        • ← Web app (HTTPS · JWT)
        • ← Respond by link (token)
        • ← Missive sidebar
        • → AI service (proxy)
        • → Projects (REST)
      • Live socketsWebSocketsREALTIME

        REALTIME · WebSockets

        Held by the gateway: chat, notifications, who is on which drawing, which conversation each tab is reading, and the notice that a new version of the app is out.

        Talks to

        • ← Web app (live)
        • ← Redis 7 (pub/sub)
      • MCP endpointJSON-RPCAI

        AI · JSON-RPC

        The MCP transport. Claude’s tool calls arrive here and run as the signed-in user.

        Talks to

        • ← Claude & MCP clients (MCP)
        • → Tool registry (as the user)
    3. CAI & MCP· 6Catalogue ingestion · AI service · Agents · Workflows · Tool registry · OAuth server
      • Catalogue ingestionfrom past documentsAI

        AI · from past documents

        Reads a company’s past project documents and proposes budget and qualification catalogue entries. Nothing lands until a person with the right permission accepts it.

        Talks to

        • → Catalogues
      • AI serviceNode · FastifyAI

        AI · Node · Fastify

        Runs the assistant’s and the agents’ turns: streams the model, offers the tool list, applies each company’s model policy and evaluates hooks once per turn. It also transcribes voice notes and drafts meeting minutes.

        Talks to

        • ← Public API (proxy)
        • → Tool registry (list · call)
        • ← Agents
        • → Claude · OpenRouter (stream)
        • → Daily logs
      • Agentscommands · skills · hooksAI

        AI · commands · skills · hooks

        Each company’s named AI agents: built-in construction commands, their own skills, hooks with an audit trail, and delegation to one other agent at most.

        Talks to

        • → AI service
      • Workflowstriggers · schedulesJOB

        JOB · triggers · schedules

        Workflow definitions wired step to step, each output checked against the next input, run on a trigger or a schedule as the person who owns them.

      • Tool registry234 tools · 24 domainsAI

        AI · 234 tools · 24 domains

        Every action an AI may take, declared on the platform’s own service methods, with a schema derived from the DTO and the caller’s permissions checked on every call. Read, write and workflow tools are marked apart, so clients know which ones change things.

        Talks to

        • ← MCP endpoint (as the user)
        • ← AI service (list · call)
        • → Projects (every domain)
      • OAuth serverOAuth 2.1SERVICE

        SERVICE · OAuth 2.1

        Lets MCP clients sign in as a person. Redirect addresses are checked strictly so the consent step can’t be abused.

        Talks to

        • ← Claude & MCP clients (OAuth)
    4. DPrecon· 7Leads & CRM · Estimating schedule · Scope & estimate · Catalogues · Bidding · Client proposals · Sub network
      • Leads & CRMaccounts · follow-upsSERVICE

        SERVICE · accounts · follow-ups

        Leads with statuses each company sets, client accounts, contacts, interactions and follow-ups, and a won/lost analysis the AI can write up on a schedule.

        Talks to

        • → Estimating schedule
        • ← Missive (webhooks)
      • Estimating schedulewho · when · hoursSERVICE

        SERVICE · who · when · hours

        Which estimator is on which bid, on which dates, with hours planned next to hours spent.

        Talks to

        • ← Leads & CRM
        • → Scope & estimate
      • Scope & estimateROM · conceptual · bidSERVICE

        SERVICE · ROM · conceptual · bid

        The estimate as a tree of divisions, subtrades and cost lines, taken through ROM, conceptual and formal-bid stages, with a snapshot and a diff at every revision. Drawn in full below.

        Talks to

        • ← Estimating schedule
        • ← Catalogues
        • ← Bidding (carry a bid)
        • → Client proposals (priced)
      • Cataloguesbudget · qualificationsSERVICE

        SERVICE · budget · qualifications

        Each company’s standing budget items and qualifications, applied to a new scope automatically and shared across all its projects.

        Talks to

        • ← Catalogue ingestion
        • → Scope & estimate
      • Biddingpackages · levelingSERVICE

        SERVICE · packages · leveling

        Bid packages per trade, invitations, addenda and questions, bids with a schedule of values and alternates, leveling, and the award.

        Talks to

        • → Scope & estimate (carry a bid)
        • → Contracts & SOV (award)
      • Client proposalsversions · decisionSERVICE

        SERVICE · versions · decision

        The proposal the client sees, generated from the priced scope: versions, hand edits, an optional review, send, and the client’s decision. Accepting a version locks the scope’s prices.

        Talks to

        • ← Scope & estimate (priced)
        • → Contracts & SOV (accepted)
      • Sub networkjoin links · scoresSERVICE

        SERVICE · join links · scores

        The subcontractors a contractor works with: they join from a link, and the contractor scores their work against weights it sets.

    5. EDelivery· 8Projects · RFIs · Submittals · Drawings · Daily logs · Schedule · Meetings · Forms
      • Projectsdashboard · directorySERVICE

        SERVICE · dashboard · directory

        The centre of the model. Everything belongs to a project and the companies and people on it, each with a permission level per tool.

        Talks to

        • ← Tool registry (every domain)
        • ← Public API (REST)
        • ← Procore (import)
      • RFIsball in courtSERVICE

        SERVICE · ball in court

        Requests for information, one question each, with drafts, assignees, watchers and a due date set by urgency in business days. Drawn in full below.

        Talks to

        • → Notifications (ball moved)
      • Submittalsrevisions · votesSERVICE

        SERVICE · revisions · votes

        Submittals go round in revisions. Every assigned reviewer gives an official answer, and the most restrictive one decides the revision.

      • Drawingssplit · diff · markupSERVICE

        SERVICE · split · diff · markup

        Splits a plan set into sheets, keeps every revision, renders a diff between two, and holds markups, comments and location pins. Drawn in full below.

        Talks to

        • → Object storage
        • ← Exhibit approvals
      • Daily logsdictation · approvalSERVICE

        SERVICE · dictation · approval

        The day on site: entries, attachments and a calendar, submitted for approval. A voice note can be turned into proposed entries for the person who spoke it to confirm.

        Talks to

        • ← AI service
      • Scheduleactivities · critical pathSERVICE

        SERVICE · activities · critical path

        Schedule activities with owners and dates, a Gantt view and the critical path.

      • Meetingsagenda · AI minutesSERVICE

        SERVICE · agenda · AI minutes

        Series, agendas, attendance and minutes. A pasted transcript becomes drafted minutes and action items; accepting the draft turns the actions into assigned tasks.

      • Formstemplates · submissionsSERVICE

        SERVICE · templates · submissions

        Company form templates deployed to projects and filled in on site.

    6. FMoney· 4Change orders · Contracts & SOV · Pay applications · Budget & costs
      • Change ordersevents → ordersSERVICE

        SERVICE · events → orders

        Change events priced line by line, then change orders that are submitted, approved or rejected against a contract.

        Talks to

        • → Contracts & SOV
      • Contracts & SOVprime · subcontractsSERVICE

        SERVICE · prime · subcontracts

        Prime contracts and subcontracts with schedules of values. Contract sums are derived from the lines, never stored, and once a schedule of values is locked its values change only through a change order.

        Talks to

        • ← Client proposals (accepted)
        • ← Bidding (award)
        • ← Change orders
        • → Pay applications
      • Pay applicationsAIA G702 / G703SERVICE

        SERVICE · AIA G702 / G703

        Applications for payment on the AIA forms, by billing period with retainage: who may create, submit, certify and pay each one, rendered to PDF.

        Talks to

        • ← Contracts & SOV
      • Budget & costscost codes · direct costsSERVICE

        SERVICE · cost codes · direct costs

        The project budget by cost code, and direct costs with their attachments.

    7. GCollaboration· 4Chat · Notifications · Tasks · Calendar
      • Chatreal timeSERVICE

        SERVICE · real time

        Project, group and direct conversations with mentions and attachments. Drawn in full below.

        Talks to

        • → Redis 7 (publish)
      • Notificationsin-app · emailSERVICE

        SERVICE · in-app · email

        Tells the right people when something moves, in the app and by email, by each person’s own settings.

        Talks to

        • ← RFIs (ball moved)
        • → Redis 7
        • → Mail queue
        • ← Scheduled jobs
      • Tasksboards · initiativesSERVICE

        SERVICE · boards · initiatives

        Tasks with statuses each team sets, watchers, comments and attachments, grouped into initiatives, on boards, a timeline and a calendar.

      • Calendarslots · bookingsSERVICE

        SERVICE · slots · bookings

        Everyone’s meetings, tasks and personal blocks in one place, with free-slot finding across people and appointment booking.

    8. HDocuments· 6Files & folders · Documents · Photos · Exhibit approvals · 3D models · Search
      • Files & folderscompany · projectSERVICE

        SERVICE · company · project

        One library for files at company and project level, with folder templates for new projects, share lists and markups.

        Talks to

        • → Autodesk APS
      • Documentsmarkdown · branded PDFSERVICE

        SERVICE · markdown · branded PDF

        Documents written in the app or generated by it, with mentions, rendered to PDF on the server in each company’s own branding.

      • PhotosalbumsSERVICE

        SERVICE · albums

        Site photos in albums, with access granted per album.

      • Exhibit approvalssigned by linkSERVICE

        SERVICE · signed by link

        Sends one revision of a drawing out for approval and keeps the signed record of exactly which revision was agreed to.

        Talks to

        • → Drawings
      • 3D modelsIFC · three.jsSERVICE

        SERVICE · IFC · three.js

        IFC building models imported to a project and viewed in the browser.

      • Searchnames + meaningSERVICE

        SERVICE · names + meaning

        One search box over the projects you can reach: a pass for names and numbers and a pass for meaning, then each item’s own access check.

    9. IData & jobs· 5PostgreSQL 16 · Redis 7 · Object storage · Scheduled jobs · Mail queue
      • PostgreSQL 16Liquibase migrationsSTORE

        STORE · Liquibase migrations

        The system of record for every module, with versioned schema migrations.

      • Redis 7cache · pub/subSTORE

        STORE · cache · pub/sub

        Caching, plus the pub/sub channels that carry chat, notification, presence and viewing events between servers.

        Talks to

        • ← Chat (publish)
        • ← Notifications
        • → Live sockets (pub/sub)
      • Object storageS3-compatibleSTORE

        STORE · S3-compatible

        Drawing sheets, diff overlays, photos, models and documents, served through short-lived signed links.

        Talks to

        • ← Drawings
      • Scheduled jobs19 · one server eachJOB

        JOB · 19 · one server each

        Overdue RFIs and submittals, follow-up cadences, tasks due soon, workflow triggers, search indexing and cleanup. Each job takes a lock, so it runs on one server only.

        Talks to

        • → Notifications
      • Mail queueoutbox · retriesQUEUE

        QUEUE · outbox · retries

        Outgoing email is queued and sent in the background, through each company’s own mail server.

        Talks to

        • ← Notifications
        • → Company mail (SMTP)
    10. JOutside· 5Procore · Missive · Autodesk APS · Company mail · Claude · OpenRouter
      • Procoreone-way importEXTERNAL

        EXTERNAL · one-way import

        Projects, RFIs, submittals, drawings, documents, photos and financial history are imported from Procore over OAuth. Nothing is written back.

        Talks to

        • → Projects (import)
      • MissivewebhooksEXTERNAL

        EXTERNAL · webhooks

        The shared inbox. Its signed webhooks bring email activity into sales.

        Talks to

        • → Leads & CRM (webhooks)
      • Autodesk APSOAuth · filesEXTERNAL

        EXTERNAL · OAuth · files

        Autodesk Platform Services: linked projects, folders and files.

        Talks to

        • ← Files & folders
      • Company mailSMTP per companyEXTERNAL

        EXTERNAL · SMTP per company

        Each company sends from its own mail server, so email comes from them, not from MATTER.

        Talks to

        • ← Mail queue (SMTP)
      • Claude · OpenRoutermodelsEXTERNAL

        EXTERNAL · models

        The models behind the assistant and the agents, chosen per company within the platform’s policy, optionally on the company’s own keys.

        Talks to

        • ← AI service (stream)
    Connections · 36

    → request · ⇢ webhook, queue or schedule

    1. Web app → Public API · HTTPS · JWT
    2. Respond by link → Public API · token
    3. Missive sidebar → Public API
    4. Web app → Live sockets · live
    5. Claude & MCP clients → MCP endpoint · MCP
    6. Claude & MCP clients → OAuth server · OAuth
    7. Public API → AI service · proxy
    8. MCP endpoint → Tool registry · as the user
    9. AI service → Tool registry · list · call
    10. Agents → AI service
    11. AI service → Claude · OpenRouter · stream
    12. Catalogue ingestion → Catalogues
    13. Tool registry → Projects · every domain
    14. Public API → Projects · REST
    15. Leads & CRM → Estimating schedule
    16. Estimating schedule → Scope & estimate
    17. Catalogues → Scope & estimate
    18. Bidding → Scope & estimate · carry a bid
    19. Scope & estimate → Client proposals · priced
    20. Client proposals → Contracts & SOV · accepted
    21. Bidding → Contracts & SOV · award
    22. Change orders → Contracts & SOV
    23. Contracts & SOV → Pay applications
    24. AI service → Daily logs
    25. RFIs → Notifications · ball moved
    26. Chat ⇢ Redis 7 · publish
    27. Notifications ⇢ Redis 7
    28. Redis 7 ⇢ Live sockets · pub/sub
    29. Notifications ⇢ Mail queue
    30. Mail queue ⇢ Company mail · SMTP
    31. Scheduled jobs ⇢ Notifications
    32. Drawings → Object storage
    33. Exhibit approvals → Drawings
    34. Files & folders → Autodesk APS
    35. Procore ⇢ Projects · import
    36. Missive ⇢ Leads & CRM · webhooks

    Inside

    Preconstruction is one pipeline, not five tools. A lead becomes a project with a scope, the scope is priced from catalogues and real bids, the client accepts a proposal, and the contract and its schedule of values are generated from what they accepted.

    1. ASales· 4Leads · Follow-ups · Estimating slot · Win/loss analysis
      • Leadsstatuses you setSERVICE

        SERVICE · statuses you set

        Every opportunity, moving through statuses the company defines, tied to a client account and its contacts.

        Talks to

        • → Follow-ups
        • → Estimating slot (scheduled)
        • → Win/loss analysis (won · lost)
        • → Estimate stages (becomes a project)
      • Follow-upscalls · emails · inboxSERVICE

        SERVICE · calls · emails · inbox

        Calls and emails due on a lead, logged as interactions, including the ones logged from the shared inbox.

        Talks to

        • ← Leads
      • Estimating slotestimator · dates · hoursSERVICE

        SERVICE · estimator · dates · hours

        The bid on the estimating schedule: which estimator, which dates, hours planned and hours spent.

        Talks to

        • ← Leads (scheduled)
      • Win/loss analysiswritten by the AIAI

        AI · written by the AI

        A report on why leads were won or lost, written by the model from the pipeline’s own data, on demand or on a schedule.

        Talks to

        • ← Leads (won · lost)
    2. BScope· 7Estimate stages · Scope tree · Catalogues · Revisions · Bid packages · Carry a bid · Pricing
      • Estimate stagesROM · conceptual · bidSERVICE

        SERVICE · ROM · conceptual · bid

        One estimate per stage. Moving a project to ROM starts tracking its scope; conceptual and formal bid follow, and a stage can be stepped back.

        Talks to

        • ← Leads (becomes a project)
        • → Scope tree
      • Scope treedivisions · subtrades · linesSERVICE

        SERVICE · divisions · subtrades · lines

        Divisions, subtrades and cost lines, each subtrade assignable to a company, with notes and attachments, and an audit log of every change.

        Talks to

        • ← Estimate stages
        • ← Catalogues
        • → Revisions (snapshot)
        • ← Carry a bid (prices lines)
        • → Pricing
      • Cataloguesbudget · qualificationsSERVICE

        SERVICE · budget · qualifications

        Standing budget items and qualifications that apply themselves to a new scope, shared by every project in the company.

        Talks to

        • → Scope tree
      • Revisionssnapshot · diffSERVICE

        SERVICE · snapshot · diff

        Each revision snapshots the whole scope and every stage estimate, so any two can be compared line by line.

        Talks to

        • ← Scope tree (snapshot)
      • Bid packagesinvite · level · awardSERVICE

        SERVICE · invite · level · award

        A trade’s scope packaged for bidding. Subs bid from a link with a schedule of values and alternates, and the bids are levelled side by side.

        Talks to

        • → Carry a bid
        • → Subcontracts (award)
      • Carry a bidone transactionSERVICE

        SERVICE · one transaction

        Carries one bid across a subtrade at once: every line it prices takes its number, the rest keep theirs, and nothing is written if it prices none.

        Talks to

        • ← Bid packages
        • → Scope tree (prices lines)
      • Pricingbasis · markup · GRSERVICE

        SERVICE · basis · markup · GR

        Each line’s carried cost basis, markups and general requirements. Amounts are computed on the server, never taken from the browser.

        Talks to

        • ← Scope tree
        • → Client proposal (priced scope)
        • ← Client’s decision (locks prices)
    3. CProposal· 3Client proposal · Review & send · Client’s decision
      • Client proposalversions · editsSERVICE

        SERVICE · versions · edits

        Generated from the scope’s client view. A draft can be edited by hand and refreshed from the scope without losing those edits.

        Talks to

        • ← Pricing (priced scope)
        • → Review & send
      • Review & sendoptional reviewSERVICE

        SERVICE · optional review

        An optional internal review, then send. Sending records the recipients and writes a revision.

        Talks to

        • ← Client proposal
        • → Client’s decision
      • Client’s decisionaccepted · declinedSERVICE

        SERVICE · accepted · declined

        The client’s answer, recorded against the version they saw. Accepting it locks the scope’s prices.

        Talks to

        • ← Review & send
        • → Pricing (locks prices)
        • → Prime contract (accepted)
    4. DContract· 4Subcontracts · Pay applications · Prime contract · Change orders
      • SubcontractsSOV from the awardSERVICE

        SERVICE · SOV from the award

        An awarded bid’s schedule of values, line detail and all, carried onto a payable subcontract.

        Talks to

        • ← Bid packages (award)
        • → Pay applications
      • Pay applicationsG702 / G703 · retainageSERVICE

        SERVICE · G702 / G703 · retainage

        Billing by period on the AIA forms, with retainage, certification and payment.

        Talks to

        • ← Subcontracts
        • ← Prime contract
      • Prime contractSOV from the proposalSERVICE

        SERVICE · SOV from the proposal

        Generated from the accepted proposal, with its schedule of values built from the scope.

        Talks to

        • ← Client’s decision (accepted)
        • → Pay applications
        • ← Change orders
      • Change ordersafter the SOV locksSERVICE

        SERVICE · after the SOV locks

        Once a schedule of values is locked, its values change only through an approved change order.

        Talks to

        • → Prime contract
    Connections · 19

    → request · ⇢ webhook, queue or schedule

    1. Leads → Follow-ups
    2. Leads → Estimating slot · scheduled
    3. Leads → Win/loss analysis · won · lost
    4. Leads → Estimate stages · becomes a project
    5. Estimate stages → Scope tree
    6. Catalogues → Scope tree
    7. Scope tree → Revisions · snapshot
    8. Bid packages → Carry a bid
    9. Carry a bid → Scope tree · prices lines
    10. Scope tree → Pricing
    11. Pricing → Client proposal · priced scope
    12. Client proposal → Review & send
    13. Review & send → Client’s decision
    14. Client’s decision → Pricing · locks prices
    15. Client’s decision → Prime contract · accepted
    16. Bid packages → Subcontracts · award
    17. Subcontracts → Pay applications
    18. Prime contract → Pay applications
    19. Change orders → Prime contract

    Four flows

    An RFI changes hands

    Walk through it and each step lights the parts it runs through in the drawings above.

    By count

    actions Claude can take in it
    234
    active projects at Delta
    ~180
    in contracts managed through it
    $14M
    things people outside do from a link, with no account
    5

    Notes

    1. N.1Nobody updates ball-in-court by hand. It follows the RFI: while it’s open it sits with the company that has to answer, once it’s answered it goes back to whoever asked, and closing it clears it. Only an official answer moves it.
    2. N.2I didn’t give the AI its own way in. Claude, the assistant and every agent use the same actions a person has, as that person, and anything that moves a record through a workflow only runs when someone asks for it.
    3. N.3A proposal the client accepts locks the scope’s prices, and the contract and its schedule of values are generated from it, so what was sold is what gets billed.
    4. N.4Presence runs on a heartbeat, not on the connection. An iPad that loses signal on site drops off the sheet by itself instead of leaving a ghost behind.
    runsraisesanswered byrevised asemploysstaffed bycollectsOrganizationGC, sub or clientProjectthe jobRFIball in courtResponsemay supersede oneMembera person, a roleSubmittalapproved as noted …Revisionrevise & resubmit
    Fig.Swipe across to see all of it. MATTER’s core data model.
    MATTER website
  2. 01.2

    OutreachSphere

    Sales CRM. Turns a cold lead list into deals: it fills in missing contacts, runs email and LinkedIn sequences, and sorts replies so only real leads reach a person.

    Live · Formwork and its clients

    Full page →
    Fig.Cold outreach for Formwork and its clients, from a raw lead list to a deal in the CRM.

    Architecture

    1. APeople· 4Campaign managers · SDR desk · Client portal · Claude
      • Campaign managersNext.js 15 · React 19UI

        UI · Next.js 15 · React 19

        Formwork’s team: lead lists, campaigns, sequences and the CRM, across every client, each client’s data kept apart.

        Talks to

        • → Lead lists (CSV)
      • SDR deskcalls · follow-upsUI

        UI · calls · follow-ups

        Where reps work the follow-up queue, approve drafted replies and log calls.

        Talks to

        • → Reply approvals (approve)
      • Client portalper clientUI

        UI · per client

        Each client sees their own campaigns, leads, pipeline and campaign health.

        Talks to

        • → CRM (their pipeline)
      • ClaudeMCP clientEXTERNAL

        EXTERNAL · MCP client

        Claude, connected with a personal token, working the same data through MCP.

        Talks to

        • → MCP server (MCP · token)
    2. BApp· 10Lead lists · Enrichment · Sequences · Webhook intake · MCP server · CRM · Opportunities · Reply approvals · Reply triage · Research & prep
      • Lead listsCSV · domain dedupeSERVICE

        SERVICE · CSV · domain dedupe

        Uploaded lists, cleaned and matched to companies by web domain. Uploading never marks anyone as contacted.

        Talks to

        • ← Campaign managers (CSV)
        • → Enrichment (gaps)
        • → Sequences (filtered)
      • Enrichmentwaterfall per fieldSERVICE

        SERVICE · waterfall per field

        Fills each missing field (email, phone, title, location) by trying providers in priority order, with rate limits and caching.

        Talks to

        • ← Lead lists (gaps)
        • ← Enrichment drain (queued)
        • → Data providers (in turn)
      • Sequencesemail · LinkedInSERVICE

        SERVICE · email · LinkedIn

        A sequence filters a live list into the leads it will contact, then hands them to the sender for its channel.

        Talks to

        • ← Lead lists (filtered)
        • → Smartlead (push)
        • → Valley
      • Webhook intakeevents · repliesSERVICE

        SERVICE · events · replies

        Receives the senders’ events. Only these can mark a contact as reached, which keeps the numbers honest.

        Talks to

        • ← Smartlead (webhooks)
        • ← Valley (webhooks)
        • ← Nylas (webhooks)
        • → Reply triage (replies)
      • MCP server100 tools by roleAI

        AI · 100 tools by role

        Tools grouped by area and composed per role: an admin sees all of them, other roles only their own. Tokens are stored hashed.

        Talks to

        • ← Claude (MCP · token)
      • CRMcompanies · contactsSERVICE

        SERVICE · companies · contacts

        Warm contacts and their companies, with status, temperature, notes and a relationship score from 0 to 100.

        Talks to

        • ← Reply approvals (promote)
        • → Opportunities (deal)
        • ← Client portal (their pipeline)
        • → PostgreSQL
      • Opportunitiesproposal → won / lostSERVICE

        SERVICE · proposal → won / lost

        Deals, from proposal to won or lost.

        Talks to

        • ← CRM (deal)
      • Reply approvalsdrafted answersSERVICE

        SERVICE · drafted answers

        Real leads queue here with a reply drafted. A person approves it before it goes.

        Talks to

        • ← Reply triage (real leads)
        • ← Reply pre-drafts (drafts)
        • ← SDR desk (approve)
        • → Smartlead (reply)
        • → CRM (promote)
      • Reply triagerules → ClaudeAI

        AI · rules → Claude

        Cheap rules catch bounces, unsubscribes and warmup mail first. Claude sorts the rest into six kinds, and says unsure rather than guess.

        Talks to

        • ← Webhook intake (replies)
        • → Claude · OpenAI (classify)
        • → Slack (alert)
        • → Reply approvals (real leads)
      • Research & prepClaude · FirecrawlAI

        AI · Claude · Firecrawl

        Researches a contact or their company and preps a sales meeting, and answers questions about the CRM.

        Talks to

        • → Vector store
    3. CJobs· 3Enrichment drain · Reply pre-drafts · Sender sync
      • Enrichment draincronJOB

        JOB · cron

        Works through queued enrichment in the background.

        Talks to

        • → Enrichment (queued)
      • Reply pre-draftscronJOB

        JOB · cron

        Drafts answers ahead of time for confident real leads, so the queue is ready when someone opens it.

        Talks to

        • → Reply approvals (drafts)
      • Sender synccronJOB

        JOB · cron

        Pulls campaign stats from Smartlead and sends replies scheduled for later.

        Talks to

        • → Smartlead
    4. DData· 2PostgreSQL · Vector store
      • PostgreSQLPrismaSTORE

        STORE · Prisma

        Every client’s leads, lists, campaigns and CRM, scoped by client.

        Talks to

        • ← CRM
      • Vector storePostgres · embeddingsSTORE

        STORE · Postgres · embeddings

        A separate database of contact embeddings for semantic search in the assistant.

        Talks to

        • ← Research & prep
    5. EOutside· 6Data providers · Smartlead · Valley · Nylas · Claude · OpenAI · Slack
      • Data providersProxycurl · Findymail …EXTERNAL

        EXTERNAL · Proxycurl · Findymail …

        Proxycurl, Findymail, Apollo and Hunter, among others, tried in turn for each missing field.

        Talks to

        • ← Enrichment (in turn)
      • SmartleademailEXTERNAL

        EXTERNAL · email

        Sends the email sequences, and sends approved replies on the same thread.

        Talks to

        • ← Sequences (push)
        • → Webhook intake (webhooks)
        • ← Reply approvals (reply)
        • ← Sender sync
      • ValleyLinkedInEXTERNAL

        EXTERNAL · LinkedIn

        Runs the LinkedIn sequences.

        Talks to

        • ← Sequences
        • → Webhook intake (webhooks)
      • NylasmailboxesEXTERNAL

        EXTERNAL · mailboxes

        Connected mailboxes, for replies that arrive outside a sequence.

        Talks to

        • → Webhook intake (webhooks)
      • Claude · OpenAImodelsEXTERNAL

        EXTERNAL · models

        Claude for triage, drafting and research; OpenAI for embeddings.

        Talks to

        • ← Reply triage (classify)
      • Slacktriage alertsEXTERNAL

        EXTERNAL · triage alerts

        Triage posts real leads to the team’s channels.

        Talks to

        • ← Reply triage (alert)
    Connections · 24

    → request · ⇢ webhook, queue or schedule

    1. Campaign managers → Lead lists · CSV
    2. Lead lists → Enrichment · gaps
    3. Enrichment drain ⇢ Enrichment · queued
    4. Enrichment → Data providers · in turn
    5. Lead lists → Sequences · filtered
    6. Sequences → Smartlead · push
    7. Sequences → Valley
    8. Smartlead ⇢ Webhook intake · webhooks
    9. Valley ⇢ Webhook intake · webhooks
    10. Nylas ⇢ Webhook intake · webhooks
    11. Webhook intake → Reply triage · replies
    12. Reply triage → Claude · OpenAI · classify
    13. Reply triage ⇢ Slack · alert
    14. Reply triage → Reply approvals · real leads
    15. Reply pre-drafts ⇢ Reply approvals · drafts
    16. SDR desk → Reply approvals · approve
    17. Reply approvals → Smartlead · reply
    18. Reply approvals → CRM · promote
    19. CRM → Opportunities · deal
    20. Client portal → CRM · their pipeline
    21. Claude → MCP server · MCP · token
    22. Sender sync ⇢ Smartlead
    23. Research & prep → Vector store
    24. CRM → PostgreSQL

    Inside: reply triage

    Most replies to cold email are noise. Triage stores every reply first, lets cheap rules catch the obvious, has Claude sort the rest, and only ever lets a person send, with the CRM updated before the one step that can’t be undone.

    1. AArrive· 3Smartlead · Nylas · Webhook event
      • Smartleadreply webhooksEXTERNAL

        EXTERNAL · reply webhooks

        Replies to the email sequences, including ones from a colleague of the person emailed.

        Talks to

        • → Webhook event
      • Nylasmailbox webhooksEXTERNAL

        EXTERNAL · mailbox webhooks

        Replies that land in connected mailboxes.

        Talks to

        • → Webhook event
      • Webhook eventstored firstSTORE

        STORE · stored first

        Every reply is saved before it is classified, so nothing is lost and anything can be reclassified later.

        Talks to

        • ← Smartlead
        • ← Nylas
        • → Field extraction
    2. BSort· 5Field extraction · Rules · Classifier · Confidence floor · Kill switch
      • Field extractionevery known aliasSERVICE

        SERVICE · every known alias

        Smartlead has used several names for each field over time; extraction tries all of them.

        Talks to

        • ← Webhook event
        • → Rules
      • Ruleswarmup · bounces · vendorsSERVICE

        SERVICE · warmup · bounces · vendors

        Catch warmup mail, auto-replies, unsubscribes and bounces without a model call. Vendor domains an admin pins are a hard rule.

        Talks to

        • ← Field extraction
        • → Classifier (undecided)
      • ClassifierClaude Haiku · six kindsAI

        AI · Claude Haiku · six kinds

        Sorts what the rules can’t decide into a real lead, unsure, vendor mail, automated, spam or warmup noise, with a confidence and a one-line reason. A bid invitation from a platform counts as real money.

        Talks to

        • ← Rules (undecided)
        • → Confidence floor
      • Confidence floorlow → unsureSERVICE

        SERVICE · low → unsure

        A low-confidence answer becomes unsure, so a person sees it.

        Talks to

        • ← Classifier
        • → Hot channel (lead · unsure)
        • → Vendor channel (vendor)
        • → Firehose
        • → Review queue (real leads)
      • Kill switcheverything to peopleSERVICE

        SERVICE · everything to people

        One setting sends every reply to the hot channel for a person to read.

        Talks to

        • → Hot channel (override)
    3. CRoute· 4Hot channel · Vendor channel · Firehose · Review queue
      • Hot channelreal leads · unsureEXTERNAL

        EXTERNAL · real leads · unsure

        Slack, for replies a person should see now.

        Talks to

        • ← Confidence floor (lead · unsure)
        • ← Kill switch (override)
      • Vendor channelSlackEXTERNAL

        EXTERNAL · Slack

        Vendor mail, kept apart.

        Talks to

        • ← Confidence floor (vendor)
      • Firehoseevery replyEXTERNAL

        EXTERNAL · every reply

        Every classification, whatever the category, as an audit trail.

        Talks to

        • ← Confidence floor
      • Review queueone per replySERVICE

        SERVICE · one per reply

        Real leads queue for a drafted answer; creating the entry twice for the same reply is impossible.

        Talks to

        • ← Confidence floor (real leads)
        • → Draft + suggestions
    4. DAnswer· 5Pre-drafts · Draft + suggestions · Approve · Thread resolver · Send or schedule
      • Pre-draftscronJOB

        JOB · cron

        Drafts ahead of time for confident real leads; everything else drafts when someone opens it.

        Talks to

        • → Draft + suggestions
      • Draft + suggestionsreply · tags · temperatureAI

        AI · reply · tags · temperature

        One call writes the reply and suggests tags (only from the client’s existing ones, never invented), a CRM status and a temperature from cold to burning.

        Talks to

        • ← Review queue
        • ← Pre-drafts
        • → Approve
      • ApproveCRM first, send lastUI

        UI · CRM first, send last

        The reversible work (status, temperature, tags) is applied first; the send, which can’t be undone, comes last.

        Talks to

        • ← Draft + suggestions
        • → Thread resolver
      • Thread resolvercolleague repliesSERVICE

        SERVICE · colleague replies

        Finds the right thread even when the person replying was never in the campaign, using the id the original webhook carried.

        Talks to

        • ← Approve
        • → Send or schedule
      • Send or scheduleSmartlead inboxSERVICE

        SERVICE · Smartlead inbox

        Sends now or at a set time on the same thread, logs it, and marks the contact as replied.

        Talks to

        • ← Thread resolver
    Connections · 16

    → request · ⇢ webhook, queue or schedule

    1. Smartlead ⇢ Webhook event
    2. Nylas ⇢ Webhook event
    3. Webhook event → Field extraction
    4. Field extraction → Rules
    5. Rules → Classifier · undecided
    6. Classifier → Confidence floor
    7. Confidence floor → Hot channel · lead · unsure
    8. Confidence floor → Vendor channel · vendor
    9. Confidence floor ⇢ Firehose
    10. Kill switch → Hot channel · override
    11. Confidence floor → Review queue · real leads
    12. Review queue → Draft + suggestions
    13. Pre-drafts ⇢ Draft + suggestions
    14. Draft + suggestions → Approve
    15. Approve → Thread resolver
    16. Thread resolver → Send or schedule

    Two flows

    A lead list becomes a pipeline

    Walk through it and each step lights the parts it runs through in the drawings above.

    By count

    channels: email and LinkedIn
    2
    kinds of reply, sorted
    6
    actions Claude can take in it
    100

    Notes

    1. N.1Nobody counts as contacted until the email has actually gone out, so the numbers a client sees are real.
    2. N.2An invitation to bid sent by a bid platform is automated, but it’s still real money. The sorter is told that, and when it isn’t sure it says so and a person looks.
    3. N.3Clients get their own portal with their campaigns, leads and pipeline.
    OutreachSphere website
  3. 01.3

    SIGIL

    Sound-design instrument. A synth with six ways to make sound that plays in a browser tab or inside your DAW. Hunt breeds new patches from the ones you keep, so you find sounds by ear.

    Invite-only for now · demos public

    Full page →
    Fig.A sound-design instrument: six engines, in a browser tab or inside your DAW.

    Architecture

    1. APlay· 4Browser tab · MIDI · keyboard · Your DAW · Claude
      • Browser tabNext.js 16 · ReactUI

        UI · Next.js 16 · React

        The instrument in a browser. The public build keeps everything in the browser, with no accounts and nothing stored on a server.

        Talks to

        • → React UI
        • → Server routes (gate)
      • MIDI · keyboardWebMIDI · computer keysUI

        UI · WebMIDI · computer keys

        Play from a controller or the computer keyboard, in a chosen key and scale. Every browser API is optional; missing ones fail quietly.

        Talks to

        • → React UI (notes)
      • Your DAWVST3 · standaloneEXTERNAL

        EXTERNAL · VST3 · standalone

        Ableton or any VST3 host, on Apple Silicon, loading the plugin build.

        Talks to

        • ← Bounce · record (drag WAV)
        • ← JUCE plugin (VST3)
      • ClaudeMCP clientEXTERNAL

        EXTERNAL · MCP client

        Claude can list engines and presets, make and change patches, and write chord progressions.

        Talks to

        • → MCP endpoint (MCP)
    2. BInterface· 5Bounce · record · React UI · Hunt · Names & glyphs · MCP endpoint
      • Bounce · recordWAV · drag outSERVICE

        SERVICE · WAV · drag out

        Renders a sound offline to WAV, or records it, then lets you drag the file onto a DAW track (in Chrome) or download it.

        Talks to

        • ← React UI
        • → Your DAW (drag WAV)
      • React UIone UI for bothUI

        UI · one UI for both

        The same interface in the browser and inside the plugin: engines, macros, the XY pad, presets and Hunt.

        Talks to

        • ← Browser tab
        • ← MIDI · keyboard (notes)
        • ← Hunt (six takes)
        • → AudioWorklet (params · notes)
        • → Bounce · record
        • → JUCE plugin (bundled)
      • Huntmutate · breed · tasteSERVICE

        SERVICE · mutate · breed · taste

        Six variations at a time, judged by ear. Keeping some nudges the next generation toward them, within limits, and the nudge fades unless you keep choosing it.

        Talks to

        • ← Presets (seeds)
        • → Names & glyphs (name · mark)
        • → React UI (six takes)
      • Names & glyphsfrom parametersSERVICE

        SERVICE · from parameters

        A patch’s name and mark are computed from its parameters, so the same sound gets the same name everywhere, with nothing stored.

        Talks to

        • ← Hunt (name · mark)
      • MCP endpoint13 tools · JSON-RPCAI

        AI · 13 tools · JSON-RPC

        A plain HTTP POST endpoint. The protocol layer knows nothing about music; every tool body is a tested function.

        Talks to

        • ← Claude (MCP)
        • → Six engines (patches)
    3. CSound· 4Presets · DSP core · Six engines · FX & character
      • Presets84 across the banksSTORE

        STORE · 84 across the banks

        Starting points for every engine, plus a percussion bank.

        Talks to

        • → Hunt (seeds)
      • DSP coreTypeScript · referenceSERVICE

        SERVICE · TypeScript · reference

        The synthesis itself, in plain TypeScript: no browser APIs and no allocation in the render loops.

        Talks to

        • ← AudioWorklet (renders)
        • → Six engines
        • → Parity check (goldens)
      • Six enginesanalog · FM · physical …SERVICE

        SERVICE · analog · FM · physical …

        Analog, FM, physical modelling, granular, wavetable and sampler voices, under one voice manager.

        Talks to

        • ← DSP core
        • → FX & character
        • ← MCP endpoint (patches)
      • FX & charactertwo chainsSERVICE

        SERVICE · two chains

        An effects chain and a character chain, available on every engine.

        Talks to

        • ← Six engines
    4. DHosts· 3AudioWorklet · C++ engine · JUCE plugin
      • AudioWorkletseparate realmREALTIME

        REALTIME · separate realm

        Runs the DSP on the browser’s audio thread. It is bundled on its own and only hears what the page posts to it.

        Talks to

        • ← React UI (params · notes)
        • → DSP core (renders)
      • C++ enginehand portSERVICE

        SERVICE · hand port

        The same DSP in C++, kept in step with the TypeScript.

        Talks to

        • ← JUCE plugin (process)
        • → Parity check (compared)
      • JUCE pluginWebView UI insideSERVICE

        SERVICE · WebView UI inside

        Wraps the C++ engine as a VST3 and serves the React UI from inside the binary. Parameters are only ever appended, so saved automation never moves.

        Talks to

        • ← React UI (bundled)
        • → C++ engine (process)
        • → Your DAW (VST3)
    5. EBuild· 3Server routes · PostgreSQL · Parity check
      • Server routespasscode gate · sign-upsSERVICE

        SERVICE · passcode gate · sign-ups

        The private build sits behind a passcode; the public one has none. One setting decides, not a fork.

        Talks to

        • ← Browser tab (gate)
        • → PostgreSQL (SQL)
      • PostgreSQLsign-upsSTORE

        STORE · sign-ups

        Email sign-ups from the landing page.

        Talks to

        • ← Server routes (SQL)
      • Parity check197 golden rendersJOB

        JOB · 197 golden renders

        Renders fresh goldens from the TypeScript and measures the C++ against them on every build.

        Talks to

        • ← DSP core (goldens)
        • ← C++ engine (compared)
    Connections · 20

    → request · ⇢ webhook, queue or schedule

    1. Browser tab → React UI
    2. MIDI · keyboard → React UI · notes
    3. Presets → Hunt · seeds
    4. Hunt → Names & glyphs · name · mark
    5. Hunt → React UI · six takes
    6. React UI → AudioWorklet · params · notes
    7. AudioWorklet → DSP core · renders
    8. DSP core → Six engines
    9. Six engines → FX & character
    10. React UI → Bounce · record
    11. Bounce · record → Your DAW · drag WAV
    12. React UI → JUCE plugin · bundled
    13. JUCE plugin → C++ engine · process
    14. JUCE plugin → Your DAW · VST3
    15. DSP core → Parity check · goldens
    16. C++ engine → Parity check · compared
    17. Claude → MCP endpoint · MCP
    18. MCP endpoint → Six engines · patches
    19. Browser tab → Server routes · gate
    20. Server routes → PostgreSQL · SQL

    Inside: the engines and Hunt

    Each engine is a description plus a voice; the interface, the plugin parameters and Hunt are all built from the description. Hunt breeds sounds from a single seed, so a whole session can be replayed from one number.

    1. ADescribe· 3Engine registry · Descriptors · Built interface
      • Engine registryone line per engineSERVICE

        SERVICE · one line per engine

        Adding an engine is one line here plus its module. No app code changes.

        Talks to

        • → Descriptors
      • Descriptorsparams · ranges · groupsSTORE

        STORE · params · ranges · groups

        Every parameter with its range, default, curve and group. Linear and exponential parameters are normalised differently so a step means the same thing to the ear.

        Talks to

        • ← Engine registry
        • → Built interface (builds)
        • → Voice manager (params)
      • Built interfacefrom descriptorsUI

        UI · from descriptors

        The controls draw themselves from the descriptor.

        Talks to

        • ← Descriptors (builds)
    2. BVoices· 7Voice manager · Analog · FM · Physical · Granular · Wavetable · Sampler
      • Voice managerpolyphonySERVICE

        SERVICE · polyphony

        Owns polyphony so engines never think about it. Every voice is allocated up front, so playing a note allocates nothing.

        Talks to

        • ← Descriptors (params)
        • → Analog (voices)
        • ← Smoothing
        • → Granular
      • Analogantialiased saw · ladderSERVICE

        SERVICE · antialiased saw · ladder

        Subtractive voice with an antialiased sawtooth, so the top end sounds clean rather than harsh, into a ladder filter.

        Talks to

        • ← Voice manager (voices)
      • FMvelocity → brightnessSERVICE

        SERVICE · velocity → brightness

        Frequency modulation where playing harder opens the timbre, like a real tine, and nothing you do can push a preset past the brightness it was voiced at.

      • Physicalmembrane · wood · metal · glassSERVICE

        SERVICE · membrane · wood · metal · glass

        A bank of resonant modes shaped like a drum head, a wooden bar, a bell or glass. Bowed excitation is bounded so it can never build up forever.

        Talks to

        • → Effects chain (mix)
      • Granularshared buffersSERVICE

        SERVICE · shared buffers

        Grain clouds panned across the field, sharing one buffer across voices instead of megabytes per note, with tapered windows so grains never click.

        Talks to

        • ← Voice manager
      • Wavetablesine → metallicSERVICE

        SERVICE · sine → metallic

        Tables that run from pure to complex: sine, triangle, soft organic, square, saw, two vocal formants and metallic.

      • Sampleryour samplesSERVICE

        SERVICE · your samples

        Every voice plays one shared sample; swapping a 30 MB recording is a single reference swap between audio blocks.

    3. CSignal· 3Smoothing · Effects chain · Character chain
      • Smoothingevery parameterSERVICE

        SERVICE · every parameter

        Every parameter passes through a smoother. Unsmoothed changes cause zipper noise, the most common reason a digital synth sounds cheap.

        Talks to

        • → Voice manager
      • Effects chainchorus · delay · reverbSERVICE

        SERVICE · chorus · delay · reverb

        Where the signal becomes stereo. Each unit is skipped when its mix is silent.

        Talks to

        • ← Physical (mix)
        • → Character chain
      • Character chainbounded ±1.2SERVICE

        SERVICE · bounded ±1.2

        Effects that make a listener ask what that was, allocation-free and guarded against denormals, and bounded so nothing can push the output past ±1.2.

        Talks to

        • ← Effects chain
    4. DHunt· 6Seed · Mutate · Breed · Taste · Lineage · Name & glyph
      • Seedone numberSERVICE

        SERVICE · one number

        A deterministic generator: the same seed gives the same hunt on every machine, so a session can be shared as a single number.

        Talks to

        • → Mutate
      • Mutatesix distinct takesSERVICE

        SERVICE · six distinct takes

        Walks the current patch to six variations, retrying until they sound distinct from each other.

        Talks to

        • ← Seed
        • ← Breed
        • → Lineage (what changed)
      • Breedtwo kept parentsSERVICE

        SERVICE · two kept parents

        Crosses two patches you kept, with a little jitter.

        Talks to

        • → Mutate
        • ← Taste (bias)
      • Tastebounded · blended · fadingSERVICE

        SERVICE · bounded · blended · fading

        Turns what you keep into a direction for the next generation: capped so it can’t pin a parameter, blended so one odd keep doesn’t define you, and fading unless you keep choosing it.

        Talks to

        • → Breed (bias)
      • Lineage“brighter”, “looser”SERVICE

        SERVICE · “brighter”, “looser”

        Names the one or two things that changed in a player’s words, and keeps the trail of moves that found a sound.

        Talks to

        • ← Mutate (what changed)
        • → Name & glyph
      • Name & glyphfrom parametersSERVICE

        SERVICE · from parameters

        Computed from the parameter values, so the same sound always has the same name and mark.

        Talks to

        • ← Lineage
    Connections · 13

    → request · ⇢ webhook, queue or schedule

    1. Engine registry → Descriptors
    2. Descriptors → Built interface · builds
    3. Descriptors → Voice manager · params
    4. Voice manager → Analog · voices
    5. Smoothing → Voice manager
    6. Voice manager → Granular
    7. Physical → Effects chain · mix
    8. Effects chain → Character chain
    9. Seed → Mutate
    10. Breed → Mutate
    11. Taste → Breed · bias
    12. Mutate → Lineage · what changed
    13. Lineage → Name & glyph

    Two flows

    Finding a sound

    Walk through it and each step lights the parts it runs through in the drawings above.

    By count

    engines
    6
    presets
    84
    actions Claude can take in it
    13

    Notes

    1. N.1A patch’s name and glyph come from how it sounds. The same sound is called the same thing on every machine, and a heavy dark patch can’t come out called Bright Tide.
    2. N.2Hunt shows no knobs. You choose by ear, and each patch keeps the moves that found it, written the way a player would say them.
    3. N.3The plugin and the browser make the same sound, so a patch you find in a tab sounds identical in your DAW.
    SIGIL website
  4. 01.4

    Orbit

    AI testing platform. Point it at a GitHub repo and it tests the app for you: riskiest journeys first, in a real browser, with what broke explained in plain English.

    Live · in development

    Full page →
    Fig.An AI tester for small teams that ship fast: connect a repo and it tests the app the way a person would.

    Architecture

    1. AClients· 3Dashboard · GitHub · Claude
      • DashboardNext.js · live mapUI

        UI · Next.js · live map

        Projects, the system map, plans, runs with replays and failure analysis, and a chat panel.

        Talks to

        • → API routes (HTTPS)
        • ← Live stream (live)
      • GitHubOAuth · App · webhooksEXTERNAL

        EXTERNAL · OAuth · App · webhooks

        Sign-in, repo access through an installed App, webhooks on changes, and checks and comments back on pull requests.

        Talks to

        • → API routes (webhooks)
        • ← Reporter (PR check)
      • ClaudeMCP clientEXTERNAL

        EXTERNAL · MCP client

        Trigger runs, read the system map, plans and results, and search failures from Claude.

        Talks to

        • → MCP server (MCP)
    2. BAPI· 4API routes · Live stream · Orchestrator · MCP server
      • API routesNextAuth · RESTSERVICE

        SERVICE · NextAuth · REST

        Workspaces, projects, plans and runs, plus the webhook receivers for GitHub, Linear, Slack and billing.

        Talks to

        • ← Dashboard (HTTPS)
        • ← GitHub (webhooks)
        • → indexing (enqueue)
      • Live streamSSE · pub/subREALTIME

        REALTIME · SSE · pub/sub

        Streams indexing progress, run events and browser screenshots to the dashboard as they happen.

        Talks to

        • ← Executor (screenshots)
        • → Dashboard (live)
      • Orchestratorbudgets · contextSERVICE

        SERVICE · budgets · context

        Coordinates the agents through a run: token budgets per agent, and context picked by similarity rather than sent whole.

        Talks to

        • → execution (run)
        • ← scheduler (schedule)
        • ← MCP server (trigger)
      • MCP server7 toolsAI

        AI · 7 tools

        Run, map, plan, results, health, failure search and a code audit, over MCP.

        Talks to

        • ← Claude (MCP)
        • → Orchestrator (trigger)
    3. CQueues· 4indexing · execution · reporting · scheduler
      • indexingBullMQQUEUE

        QUEUE · BullMQ

        Jobs to clone and index a repo.

        Talks to

        • ← API routes (enqueue)
        • → Analyst (worker)
      • executionBullMQQUEUE

        QUEUE · BullMQ

        Jobs to run test cases in a browser.

        Talks to

        • ← Orchestrator (run)
        • → Executor (worker)
      • reportingBullMQQUEUE

        QUEUE · BullMQ

        Jobs to analyse results and send reports.

        Talks to

        • ← Executor (results)
        • → Reporter (worker)
      • schedulerBullMQQUEUE

        QUEUE · BullMQ

        Recurring runs on a schedule.

        Talks to

        • → Orchestrator (schedule)
    4. DAgents· 7Analyst · Planner · Executor · Reporter · Indexer · Prioritiser · Self-healer
      • Analystsystem mapAI

        AI · system map

        Turns a repo into a system map: framework, routes, components and their links.

        Talks to

        • ← indexing (worker)
        • → Indexer
        • → Planner (system map)
      • Plannerjourneys · casesAI

        AI · journeys · cases

        Rebuilds user journeys from the map, finds coverage gaps and writes test cases. Plans are cached.

        Talks to

        • ← Analyst (system map)
        • → Prioritiser
        • → Claude · GPT (plan)
      • Executorruns · evidenceAI

        AI · runs · evidence

        Drives a real browser step by step, classifies each failure, and captures screenshots, video and DOM snapshots.

        Talks to

        • ← execution (worker)
        • → Playwright · Stagehand (CDP)
        • → Self-healer
        • → Object storage (evidence)
        • → Live stream (screenshots)
        • → reporting (results)
      • Reporterplain EnglishAI

        AI · plain English

        Explains failures, spots patterns across runs, and files them where the team works.

        Talks to

        • ← reporting (worker)
        • → GitHub (PR check)
        • → Linear · Slack
      • Indexertree-sitter · regex fallbackSERVICE

        SERVICE · tree-sitter · regex fallback

        Parses source with tree-sitter, falls back to patterns when it can’t, detects the framework, and indexes incrementally.

        Talks to

        • ← Analyst
        • → PostgreSQL (map · embeddings)
      • Prioritiser40 · 35 · 25SERVICE

        SERVICE · 40 · 35 · 25

        Scores each case on criticality (40%), risk (35%) and coverage gap (25%), and boosts journeys like sign-in and checkout.

        Talks to

        • ← Planner
      • Self-healerselector memorySERVICE

        SERVICE · selector memory

        Finds a moved element by stored fix, text, label or role before asking a model, and saves what worked.

        Talks to

        • ← Executor
        • → PostgreSQL (saved fixes)
    5. EData· 3PostgreSQL · Redis · Object storage
      • PostgreSQLpgvectorSTORE

        STORE · pgvector

        Projects, maps, plans, runs and healed selectors, with embeddings for retrieval.

        Talks to

        • ← Indexer (map · embeddings)
        • ← Self-healer (saved fixes)
      • Redisqueues · pub/subSTORE

        STORE · queues · pub/sub

        Backs the job queues, rate limits and live events.

      • Object storageS3 / R2STORE

        STORE · S3 / R2

        Screenshots, videos and DOM snapshots from every run.

        Talks to

        • ← Executor (evidence)
    6. FOutside· 3Claude · GPT · Playwright · Stagehand · Linear · Slack
      • Claude · GPTrouted by taskEXTERNAL

        EXTERNAL · routed by task

        Different models for mapping, planning, running and reporting, chosen per task.

        Talks to

        • ← Planner (plan)
      • Playwright · Stagehandremote CDPEXTERNAL

        EXTERNAL · remote CDP

        A real headless browser over CDP, or a cloud browser when configured.

        Talks to

        • ← Executor (CDP)
      • Linear · Slackissues · alertsEXTERNAL

        EXTERNAL · issues · alerts

        Where failures become issues and alerts.

        Talks to

        • ← Reporter
    Connections · 24

    → request · ⇢ webhook, queue or schedule

    1. Dashboard → API routes · HTTPS
    2. GitHub ⇢ API routes · webhooks
    3. API routes ⇢ indexing · enqueue
    4. indexing ⇢ Analyst · worker
    5. Analyst → Indexer
    6. Indexer → PostgreSQL · map · embeddings
    7. Analyst → Planner · system map
    8. Planner → Prioritiser
    9. Planner → Claude · GPT · plan
    10. Orchestrator ⇢ execution · run
    11. scheduler ⇢ Orchestrator · schedule
    12. execution ⇢ Executor · worker
    13. Executor → Playwright · Stagehand · CDP
    14. Executor → Self-healer
    15. Self-healer → PostgreSQL · saved fixes
    16. Executor → Object storage · evidence
    17. Executor ⇢ Live stream · screenshots
    18. Live stream ⇢ Dashboard · live
    19. Executor ⇢ reporting · results
    20. reporting ⇢ Reporter · worker
    21. Reporter → GitHub · PR check
    22. Reporter → Linear · Slack
    23. Claude → MCP server · MCP
    24. MCP server → Orchestrator · trigger

    Inside: the executor and self-healing

    Real apps change under their tests. The executor checks it’s allowed to run, orders tests by what they depend on, and when a button has moved it climbs a ladder of cheap fixes before it ever asks a model, then remembers the answer.

    1. ABefore· 4Environment check · Dependency order · Auth reuse · API tests
      • Environment checknever productionSERVICE

        SERVICE · never production

        Refuses production environments outright, checks the target is reachable, and decrypts the test credentials.

        Talks to

        • → Dependency order
      • Dependency orderparallel groupsSERVICE

        SERVICE · parallel groups

        Sorts tests by their prerequisites into groups that run in parallel, one group after another, breaking any cycles first.

        Talks to

        • ← Environment check
        • → Auth reuse
        • → API tests (contracts)
      • Auth reuseskip repeat loginsSERVICE

        SERVICE · skip repeat logins

        Once signed in, later tests skip their opening login steps. Tests of the login itself always start fresh.

        Talks to

        • ← Dependency order
        • → Step executor
      • API testsplain HTTPSERVICE

        SERVICE · plain HTTP

        Contract tests run without a browser or a model loop, falling back to the browser when they need the UI.

        Talks to

        • ← Dependency order (contracts)
    2. BRun· 3Step executor · Browser · Provider guard
      • Step executorone step at a timeAI

        AI · one step at a time

        Acts on the page step by step and classifies any failure: missing element, not clickable, timeout, wrong assertion, wrong page.

        Talks to

        • ← Auth reuse
        • ← Provider guard (abort)
        • → Browser (act)
        • → Stored fix (broken selector)
        • → Flaky registry (retries)
        • → Baselines (on pass)
        • → Evidence
      • BrowserPlaywright · StagehandEXTERNAL

        EXTERNAL · Playwright · Stagehand

        A real browser over CDP, with Stagehand’s element and prompt caching when it is used.

        Talks to

        • ← Step executor (act)
      • Provider guardstop, don’t pile upSERVICE

        SERVICE · stop, don’t pile up

        If the AI provider fails on billing, auth or quota, the run stops rather than recording a false failure for every remaining test.

        Talks to

        • → Step executor (abort)
    3. CHeal· 5Stored fix · Visible text · Label · Role · Model
      • Stored fixapproved firstSERVICE

        SERVICE · approved first

        A fix that worked before for this selector, approved ones first, then others above 0.85 confidence.

        Talks to

        • ← Step executor (broken selector)
        • → Visible text (miss)
      • Visible textheuristicSERVICE

        SERVICE · heuristic

        Finds the element by the words on it.

        Talks to

        • ← Stored fix (miss)
        • → Label (miss)
      • Labelaria-labelSERVICE

        SERVICE · aria-label

        Finds it by its accessible label.

        Talks to

        • ← Visible text (miss)
        • → Role (miss)
      • Rolerole-basedSERVICE

        SERVICE · role-based

        Finds it by what it is: a button, a link, a field.

        Talks to

        • ← Label (miss)
        • → Model (miss)
      • Modelselector sub-agentAI

        AI · selector sub-agent

        Last resort: a model reads the page’s interactive elements and the selectors that failed, and proposes a new one.

        Talks to

        • ← Role (miss)
        • → Selector memory (saved)
    4. DAfter· 4Selector memory · Flaky registry · Baselines · Evidence
      • Selector memorysaved fixesSTORE

        STORE · saved fixes

        Every heal is stored with its strategy and confidence, so the next run starts from it.

        Talks to

        • ← Model (saved)
      • Flaky registryquarantineSERVICE

        SERVICE · quarantine

        A test that fails then passes with no code change is flaky, not broken; after five such flips with under half its recent runs passing, it is quarantined.

        Talks to

        • ← Step executor (retries)
      • Baselinesscreens · API shapesSTORE

        STORE · screens · API shapes

        After a passing run, screenshots and API response shapes are kept to compare the next run against.

        Talks to

        • ← Step executor (on pass)
      • Evidencescreens · video · DOMSTORE

        STORE · screens · video · DOM

        Everything a person needs to see what happened, kept per step.

        Talks to

        • ← Step executor
    Connections · 15

    → request · ⇢ webhook, queue or schedule

    1. Environment check → Dependency order
    2. Dependency order → Auth reuse
    3. Dependency order → API tests · contracts
    4. Auth reuse → Step executor
    5. Provider guard → Step executor · abort
    6. Step executor → Browser · act
    7. Step executor → Stored fix · broken selector
    8. Stored fix → Visible text · miss
    9. Visible text → Label · miss
    10. Label → Role · miss
    11. Role → Model · miss
    12. Model → Selector memory · saved
    13. Step executor → Flaky registry · retries
    14. Step executor → Baselines · on pass
    15. Step executor → Evidence

    Two flows

    Testing your app

    Walk through it and each step lights the parts it runs through in the drawings above.

    By count

    agents: analyst, planner, executor, reporter
    4
    actions Claude can take in it
    7

    Notes

    1. N.1When a button moves, Orbit tries the cheap ways to find it first: its text, its label, its role. It only asks a model as a last resort, and it remembers the answer.
    2. N.2It can break things on purpose, like a dropped request or a slow server, to see how the app copes.
    Orbit website
  5. 01.5

    Thronos

    Agent operations platform. A team of AI agents that works on a schedule. They read a company’s systems, draft the work and bring every decision to a person to approve.

    Live · private

    Full page →
    Fig.A team of AI agents that does a company’s routine work on a schedule, remembers what it learns, and brings every decision to a person.

    Architecture

    1. AWeb· 5Stage · Decisions · Library · Live socket · Slack
      • StageThree.js roomUI

        UI · Three.js room

        The home screen: each agent a node with live presence, lines where one hands work to another, an artifact shelf and a chat dock.

        Talks to

        • ← Live socket (live)
      • Decisionsj · k · a · rUI

        UI · j · k · a · r

        One queue for every pending approval, gate and proposal, triaged from the keyboard, with a log of what was settled today.

        Talks to

        • → Engine API (approve · reject)
      • LibraryartifactsUI

        UI · artifacts

        Every typed artifact an agent has produced, addressable by key.

      • Live socketsocket.ioREALTIME

        REALTIME · socket.io

        One shared connection per app; the Stage, chat and live thought streams all listen on it.

        Talks to

        • ← Redis (pub/sub)
        • → Stage (live)
      • Slackfast-path chatEXTERNAL

        EXTERNAL · fast-path chat

        Talk to the agents from Slack, answered by the cheaper runtime.

        Talks to

        • → Kernel (chat)
    2. BEngine· 16Engine API · Signals · Heartbeat · Orchestrator · 14 sub-agents · Kernel · Team templates · Governance · Agent runner · Task loop · Event mesh · MCP registry · Autoresearch · Self-healing · Costs · Integration hub
      • Engine APInode:httpSERVICE

        SERVICE · node:http

        The engine’s HTTP API, on Node’s own http module rather than a framework.

        Talks to

        • ← Decisions (approve · reject)
        • → Governance
      • SignalsGitHub · Linear · healthJOB

        JOB · GitHub · Linear · health

        Gatherers that collect what changed (code, tickets, business numbers, tool health, memory) before each tick.

        Talks to

        • → Heartbeat (what changed)
      • HeartbeatBullMQ · 12 lanesJOB

        JOB · BullMQ · 12 lanes

        Health hourly, the inbox every two hours, reviews each morning, weekly analysis, nightly research. Lanes that share resources never overlap, and a circuit breaker pauses an agent that keeps failing.

        Talks to

        • ← Team templates (seeds)
        • ← Signals (what changed)
        • → Orchestrator (tick)
        • → Kernel (cheap lanes)
        • → Autoresearch (nightly)
      • OrchestratorOpus · Agent SDKAI

        AI · Opus · Agent SDK

        The top-level agent. It reads the signals, opens and claims a task, and delegates to the specialists.

        Talks to

        • ← Heartbeat (tick)
        • → 14 sub-agents (delegates)
        • → Task loop (claims)
      • 14 sub-agentsHaiku · Sonnet · OpusAI

        AI · Haiku · Sonnet · Opus

        Sentinel, Analyst, Scribe, Custodian, Oracle, Architect, Strategist and the rest, each with its own model, tools, budget and yes-or-no checks.

        Talks to

        • ← Orchestrator (delegates)
        • → Agent runner
        • → Governance (proposals)
        • ← Autoresearch (prompts)
        • ← Self-healing (revisions)
        • → Anthropic · OpenRouter
      • KernelOpenRouter · cappedAI

        AI · OpenRouter · capped

        A second, cheaper runtime for the frequent lanes, with a hard budget per tick, a turn limit, and only the MCP servers that lane needs.

        Talks to

        • ← Heartbeat (cheap lanes)
        • → MCP registry (subset)
        • ← Slack (chat)
      • Team templatesfiveSERVICE

        SERVICE · five

        Seeds a team, its schedule and its autonomy defaults in one action.

        Talks to

        • → Heartbeat (seeds)
      • Governanceapprovals · autonomySERVICE

        SERVICE · approvals · autonomy

        Approval records and the autonomy mode (supervised, assisted or full) that decides what is approved automatically. New agents are capped at 20 per workspace and three a day.

        Talks to

        • ← Engine API
        • ← 14 sub-agents (proposals)
      • Agent runnerone run, start to endSERVICE

        SERVICE · one run, start to end

        Checks the budget, loads the agent’s past experience, filters its tools, runs it with a live thought stream, retries on failure, then writes the run to memory.

        Talks to

        • ← 14 sub-agents
        • → MCP registry (tools)
        • → Event mesh (output)
        • → Mnemos (write · recall)
        • → Costs (checks)
      • Task loopclaim · settleSERVICE

        SERVICE · claim · settle

        The work record. The engine claims a task before delegating and settles whatever is still open when a run ends, so the record is right even if an agent forgets.

        Talks to

        • ← Orchestrator (claims)
      • Event meshagent → agentREALTIME

        REALTIME · agent → agent

        Each run’s output is classified and published, so a Sentinel alert lands in the Orchestrator’s triage and an Architect deploy sets off a Sentinel check.

        Talks to

        • ← Agent runner (output)
        • → Redis (publish)
      • MCP registry~60 built-in toolsAI

        AI · ~60 built-in tools

        Assembles each agent’s tools from the healthy servers, minus the tools that agent is blocked from.

        Talks to

        • ← Agent runner (tools)
        • ← Kernel (subset)
        • → Dev tools (MCP)
        • → Company systems (MCP)
        • ← Integration hub (compiled)
      • Autoresearch03:00 nightlyJOB

        JOB · 03:00 nightly

        Simulates five outputs, grades them on yes-or-no checks, mutates the prompt, simulates five more, and promotes only at five percent better. Every experiment is logged.

        Talks to

        • ← Heartbeat (nightly)
        • → 14 sub-agents (prompts)
      • Self-healingbinary evalsJOB

        JOB · binary evals

        Scores every run and drafts a prompt revision when quality drops. A revision may change at most a fifth of the prompt, and after three failed revisions in a row a person is asked.

        Talks to

        • → 14 sub-agents (revisions)
      • Coststick · day · monthSERVICE

        SERVICE · tick · day · month

        Token budgets per agent per tick, per day and per month, under a global cap.

        Talks to

        • ← Agent runner (checks)
      • Integration hubspec → MCPSERVICE

        SERVICE · spec → MCP

        Compiles a REST or GraphQL connector from its spec into an in-process MCP server at install time.

        Talks to

        • → MCP registry (compiled)
        • ← Any API (spec)
    3. CMemory· 1Mnemos
      • Mnemosmemory serviceSERVICE

        SERVICE · memory service

        The memory, as its own service: written after every run, consolidated on a schedule, searched before the next. Drawn in full below.

        Talks to

        • ← Agent runner (write · recall)
        • → Neo4j
        • → PostgreSQL (vectors)
    4. DData· 3PostgreSQL · Neo4j · Redis
      • PostgreSQLPrisma · pgvectorSTORE

        STORE · Prisma · pgvector

        Agents, runs, tasks, approvals, budgets and experiments, plus the memory’s embeddings.

        Talks to

        • ← Mnemos (vectors)
      • Neo4jknowledge graphSTORE

        STORE · knowledge graph

        The graph of what the agents have learned.

        Talks to

        • ← Mnemos
      • RedisBullMQ · pub/subSTORE

        STORE · BullMQ · pub/sub

        The heartbeat’s queues and the event channels.

        Talks to

        • ← Event mesh (publish)
        • → Live socket (pub/sub)
    5. EReach· 4Anthropic · OpenRouter · Dev tools · Company systems · Any API
      • Anthropic · OpenRoutermodelsEXTERNAL

        EXTERNAL · models

        Claude through the Agent SDK; other models through OpenRouter.

        Talks to

        • ← 14 sub-agents
      • Dev toolsin-process MCPEXTERNAL

        EXTERNAL · in-process MCP

        GitHub, Linear and Railway: code, tickets and deploys.

        Talks to

        • ← MCP registry (MCP)
      • Company systemsHTTP MCPEXTERNAL

        EXTERNAL · HTTP MCP

        C0, ContentSphere and OutreachSphere, read through their own MCP servers.

        Talks to

        • ← MCP registry (MCP)
      • Any APIREST · GraphQLEXTERNAL

        EXTERNAL · REST · GraphQL

        Any API added through the hub.

        Talks to

        • → Integration hub (spec)
    Connections · 29

    → request · ⇢ webhook, queue or schedule

    1. Decisions → Engine API · approve · reject
    2. Engine API → Governance
    3. Team templates → Heartbeat · seeds
    4. Signals → Heartbeat · what changed
    5. Heartbeat ⇢ Orchestrator · tick
    6. Heartbeat ⇢ Kernel · cheap lanes
    7. Heartbeat ⇢ Autoresearch · nightly
    8. Orchestrator → 14 sub-agents · delegates
    9. Orchestrator → Task loop · claims
    10. 14 sub-agents → Agent runner
    11. Agent runner → MCP registry · tools
    12. Agent runner ⇢ Event mesh · output
    13. Agent runner → Mnemos · write · recall
    14. Agent runner → Costs · checks
    15. Kernel → MCP registry · subset
    16. Slack → Kernel · chat
    17. 14 sub-agents → Governance · proposals
    18. Autoresearch ⇢ 14 sub-agents · prompts
    19. Self-healing ⇢ 14 sub-agents · revisions
    20. MCP registry → Dev tools · MCP
    21. MCP registry → Company systems · MCP
    22. Integration hub → MCP registry · compiled
    23. Any API → Integration hub · spec
    24. Mnemos → Neo4j
    25. Mnemos → PostgreSQL · vectors
    26. Event mesh ⇢ Redis · publish
    27. Redis ⇢ Live socket · pub/sub
    28. Live socket ⇢ Stage · live
    29. 14 sub-agents → Anthropic · OpenRouter

    Inside: the memory

    Memory isn’t a log. Everything an agent produces is read for what it’s about, merged with what is already known, consolidated every six hours, faded when unused, and searched by meaning, keyword and connection when it’s needed again.

    1. AIn· 5Run output · Experience · Documents · From tools · Scenarios
      • Run outputsuccessful runsSERVICE

        SERVICE · successful runs

        What an agent produced, sent to memory after the run.

        Talks to

        • → Extract
      • Experienceevery runSERVICE

        SERVICE · every run

        A record of each run, failures included, so an agent can learn from what it has done.

        Talks to

        • → Knowledge graph (Experience node)
      • Documentsfiles · URLs · YouTubeSERVICE

        SERVICE · files · URLs · YouTube

        Outside material ingested on request.

        Talks to

        • → Extract
      • From toolsMCP ingestAI

        AI · MCP ingest

        Anything an agent chooses to remember through its memory tools.

        Talks to

        • → Extract
      • Scenariosworld modelsSERVICE

        SERVICE · world models

        A seed document becomes a model: actors with interests, tensions between them, dynamics and assumptions.

        Talks to

        • → Knowledge graph (world model)
    2. BWrite· 6Extract · Deduplicate · Score · Store · Embed · Connect
      • Extractontology-awareAI

        AI · ontology-aware

        Pulls out entities and relationships using the known types and their properties. Runs on a local model when one is available, Haiku otherwise.

        Talks to

        • ← Run output
        • ← Documents
        • ← From tools
        • → Deduplicate
      • Deduplicatespelling · meaningSERVICE

        SERVICE · spelling · meaning

        Matches each entity to one already known: by fuzzy name (bigram similarity of 0.75 or more), then by meaning.

        Talks to

        • ← Extract
        • → Score
      • Scoreconfidence · half-lifeSERVICE

        SERVICE · confidence · half-life

        Confidence comes from the source; lifespan from the type: 7 days for a signal, 90 for a client, 365 for a principle. Use keeps a memory fresh.

        Talks to

        • ← Deduplicate
        • → Store
      • Storemerge · never dropSERVICE

        SERVICE · merge · never drop

        Writes nodes idempotently with bounded concurrency. If extraction fails, the raw text is kept as an observation rather than lost.

        Talks to

        • ← Score
        • → Embed
        • → Knowledge graph (MERGE)
      • Embed1536 dimensionsAI

        AI · 1536 dimensions

        Embeds each node for search. In production a failed embedding is an error, never a placeholder that would quietly poison recall.

        Talks to

        • ← Store
        • → Connect
        • → Embeddings
      • Connectauto-linkSERVICE

        SERVICE · auto-link

        Links new nodes to related ones already in the graph.

        Talks to

        • ← Embed
        • → Knowledge graph (edges)
    3. CStores· 2Knowledge graph · Embeddings
      • Knowledge graphL0 raw · L1 distilledSTORE

        STORE · L0 raw · L1 distilled

        Nineteen core kinds of memory in Neo4j (new kinds can appear), from signals and bugs to decisions and principles, each fact able to say when it became true and when it stopped.

        Talks to

        • ← Experience (Experience node)
        • ← Scenarios (world model)
        • ← Store (MERGE)
        • ← Connect (edges)
        • ← Compression (L0 → L1)
        • ← Reflection (insights)
        • ← Summaries
        • ← Past experience (experiences)
      • EmbeddingspgvectorSTORE

        STORE · pgvector

        The vectors behind semantic search, cleaned up when a node is archived so it can’t haunt results.

        Talks to

        • ← Embed
        • ← Decay (archive)
        • ← Hybrid search (dense)
    4. DKeep· 4Compression · Reflection · Summaries · Decay
      • Compressionevery 6 hJOB

        JOB · every 6 h

        Clusters similar memories, checks the cluster really is similar (cosine 0.65 or more), and replaces it with one distilled L1 memory. High-value memories are never compressed.

        Talks to

        • → Knowledge graph (L0 → L1)
      • Reflectionafter compressionJOB

        JOB · after compression

        Reads 12 to 60 recent observations, decisions and experiences together and writes up to eight new insights or patterns.

        Talks to

        • → Knowledge graph (insights)
      • SummariesrollingJOB

        JOB · rolling

        Keeps a short summary on each node from its properties and its recent connections.

        Talks to

        • → Knowledge graph
      • DecaydailyJOB

        JOB · daily

        Recomputes each memory’s freshness from its half-life and last use; below 0.05 it is archived. A node with no timestamp is left alone, never archived on a guess.

        Talks to

        • → Embeddings (archive)
    5. ERecall· 6Past experience · HyDE · Hybrid search · Graph walk · Filters · Rerank
      • Past experiencebefore each runSERVICE

        SERVICE · before each run

        The agent’s own past runs, ranked by overlap with the task at hand, added to its prompt so it builds a view from what it has actually done.

        Talks to

        • → Knowledge graph (experiences)
      • HyDEhypothetical answerAI

        AI · hypothetical answer

        For abstract questions, drafts a likely answer and searches with that instead. Direct lookups skip it.

        Talks to

        • → Hybrid search
      • Hybrid searchdense + keyword · RRFSERVICE

        SERVICE · dense + keyword · RRF

        Runs semantic and keyword search and fuses the two rankings.

        Talks to

        • ← HyDE
        • → Embeddings (dense)
        • → Graph walk
      • Graph walk2 hopsSERVICE

        SERVICE · 2 hops

        Expands each hit two steps through the graph, so related context comes along.

        Talks to

        • ← Hybrid search
        • → Filters
      • Filterstime · type · truthSERVICE

        SERVICE · time · type · truth

        Drops archived and invalidated facts, and can answer as of a past date.

        Talks to

        • ← Graph walk
        • → Rerank
      • Rerankagainst the questionAI

        AI · against the question

        A model reorders the shortlist against the original question, not the expanded one.

        Talks to

        • ← Filters
    Connections · 23

    → request · ⇢ webhook, queue or schedule

    1. Run output → Extract
    2. Documents → Extract
    3. From tools → Extract
    4. Experience → Knowledge graph · Experience node
    5. Scenarios → Knowledge graph · world model
    6. Extract → Deduplicate
    7. Deduplicate → Score
    8. Score → Store
    9. Store → Embed
    10. Embed → Connect
    11. Store → Knowledge graph · MERGE
    12. Embed → Embeddings
    13. Connect → Knowledge graph · edges
    14. Compression ⇢ Knowledge graph · L0 → L1
    15. Reflection ⇢ Knowledge graph · insights
    16. Summaries ⇢ Knowledge graph
    17. Decay ⇢ Embeddings · archive
    18. Past experience → Knowledge graph · experiences
    19. HyDE → Hybrid search
    20. Hybrid search → Embeddings · dense
    21. Hybrid search → Graph walk
    22. Graph walk → Filters
    23. Filters → Rerank

    Two flows

    How an agent remembers

    Walk through it and each step lights the parts it runs through in the drawings above.

    By count

    agent roles
    15
    heartbeat lanes
    12
    built-in tools
    ~60
    kinds of memory, each with its own lifespan
    19
    team templates
    5
    autonomy modes
    3

    Notes

    1. N.1Every kind of memory has its own lifespan. A signal fades in a week, a client in three months, a principle in a year, and anything that keeps getting used stays fresh.
    2. N.2Memory can answer “what did we believe in March?” Facts carry when they became true and when they stopped, and recall can ask about a past date.
    3. N.3If a model can’t make sense of something, it is still kept as a raw note. Nothing an agent learns is silently dropped.
    4. N.4The agents react to each other. A Sentinel alert lands in the Orchestrator’s triage, and an Architect deploy sets off a Sentinel check.
    Thronos website
  6. 01.6

    Contractor Toolkit

    Open-source Claude Code plugins. Free Claude Code plugins for contractors. Tell Claude about your company once, and it drafts estimates, bid packages, RFIs and daily logs in your brand.

    Live · open source

    Full page →
    Fig.Free Claude Code plugins for contractors: tell Claude about your company once, and it writes the paperwork in your brand.

    Architecture

    1. AInstall· 3Your fork · Claude Code · claude.ai · Cowork
      • Your forkgit repoEXTERNAL

        EXTERNAL · git repo

        Fork the repo, configure it once, and push it to a private repo. Teammates clone it and get the company’s skills with no setup.

        Talks to

        • → Claude Code (marketplace add)
      • Claude Codeplugin marketplaceEXTERNAL

        EXTERNAL · plugin marketplace

        The marketplace file registers six plugins; each installs on its own.

        Talks to

        • ← Your fork (marketplace add)
        • → /initialize (installs)
      • claude.ai · Coworkskill zipsEXTERNAL

        EXTERNAL · skill zips

        The same skills as standalone packages, for the web app.

        Talks to

        • ← Skill packages (upload)
    2. BSetup· 3/initialize · Company config · contractor-brand
      • /initializeten sectionsUI

        UI · ten sections

        A conversational interview, one section at a time. Each answer is written into the template tokens of every skill that uses it; re-run one section and only its tokens change.

        Talks to

        • ← Claude Code (installs)
        • → Company config (writes)
      • Company configlocal MarkdownSTORE

        STORE · local Markdown

        The company’s answers, kept in local config. Capabilities are read at run time rather than substituted.

        Talks to

        • ← /initialize (writes)
        • → contractor-brand (tokens)
        • → contractor-estimating (defaults)
      • contractor-brandcolors · fonts · voiceSERVICE

        SERVICE · colors · fonts · voice

        Keeps every document on-brand: colors, type, logos and how the company sounds.

        Talks to

        • ← Company config (tokens)
        • → contractor-docs (brand)
    3. CSkills· 8contractor-estimating · contractor-extras · contractor-subs · contractor-docs · estimate-reviewer · scope-writer · sub-packager · Token guard
      • contractor-estimating13 skillsSERVICE

        SERVICE · 13 skills

        The preconstruction pipeline: ROM, plan takeoff, conceptual budget, scope check, sub bid packages, bid leveling, formal bid, contract and subcontract.

        Talks to

        • ← Company config (defaults)
        • → estimate-reviewer (review)
        • → scope-writer (scope)
        • → sub-packager (packages)
        • → contractor-docs (render)
      • contractor-extras13 skillsSERVICE

        SERVICE · 13 skills

        Everyday paperwork: proposals, RFIs and RFI logs, submittals, daily logs, look-aheads, change orders, punch lists, incident reports.

        Talks to

        • → contractor-docs
      • contractor-subs4 skillsSERVICE

        SERVICE · 4 skills

        For subcontractors: quotes, change order requests, T&M tickets and pay applications.

      • contractor-docsdocument engineSERVICE

        SERVICE · document engine

        Renders everything as HTML or DOCX in the company’s brand.

        Talks to

        • ← contractor-brand (brand)
        • ← contractor-estimating (render)
        • ← contractor-extras
        • → Documents (Write)
      • estimate-revieweragentAI

        AI · agent

        Checks an estimate before documents are generated.

        Talks to

        • ← contractor-estimating (review)
      • scope-writeragentAI

        AI · agent

        Writes project-specific scope by CSI division.

        Talks to

        • ← contractor-estimating (scope)
      • sub-packageragentAI

        AI · agent

        Builds one self-contained bid invitation per trade.

        Talks to

        • ← contractor-estimating (packages)
      • Token guardPostToolUse hookJOB

        JOB · PostToolUse hook

        Runs after every file Claude writes. A finished HTML document that still has an unfilled {{TOKEN}} is blocked.

        Talks to

        • → Documents (guards)
    4. DOutput· 3Documents · Release validation · Skill packages
      • DocumentsHTML · DOCXEXTERNAL

        EXTERNAL · HTML · DOCX

        Estimates, bids, contracts, logs and the rest, ready to send.

        Talks to

        • ← contractor-docs (Write)
        • ← Token guard (guards)
      • Release validationPython checksJOB

        JOB · Python checks

        Checks manifests, inventory, resource paths and template tokens. Unconfigured templates fail; there is no switch to skip it.

        Talks to

        • → Skill packages (gate)
      • Skill packagesdist buildJOB

        JOB · dist build

        Builds the standalone zips, after validation passes and a person reviews them.

        Talks to

        • ← Release validation (gate)
        • → claude.ai · Cowork (upload)
    Connections · 15

    → request · ⇢ webhook, queue or schedule

    1. Your fork → Claude Code · marketplace add
    2. Claude Code → /initialize · installs
    3. /initialize → Company config · writes
    4. Company config → contractor-brand · tokens
    5. Company config → contractor-estimating · defaults
    6. contractor-estimating → estimate-reviewer · review
    7. contractor-estimating → scope-writer · scope
    8. contractor-estimating → sub-packager · packages
    9. contractor-brand → contractor-docs · brand
    10. contractor-estimating → contractor-docs · render
    11. contractor-extras → contractor-docs
    12. contractor-docs → Documents · Write
    13. Token guard ⇢ Documents · guards
    14. Release validation → Skill packages · gate
    15. Skill packages → claude.ai · Cowork · upload

    Inside: the setup wizard and its safety gate

    Setup rewrites a company’s own files, so it is run like a change to production: planned, shown as an exact diff, approved, backed up, applied, and checked byte for byte, with nothing ever reported as done that wasn’t.

    1. AInterview· 2Ten sections · Section re-run
      • Ten sectionsone at a timeUI

        UI · one at a time

        Company, services, brand colors, type, logos, voice, contact, ideal client, capabilities and estimating defaults, each with a default you can accept.

        Talks to

        • → Staged answers
      • Section re-runonly its tokensUI

        UI · only its tokens

        Re-run one section and only that section’s values change.

        Talks to

        • → Staged answers
    2. BPlan· 3Staged answers · Change plan · Diff + approval
      • Staged answersoutside live filesSERVICE

        SERVICE · outside live files

        Answers and full proposed files are staged away from the real ones and validated first.

        Talks to

        • ← Ten sections
        • ← Section re-run
        • → Change plan
      • Change planbefore hashes · contextsSTORE

        STORE · before hashes · contexts

        Every file, its hash before, the exact text and context of each replacement, and the fields that change. No global find-and-replace.

        Talks to

        • ← Staged answers
        • → Diff + approval
      • Diff + approvalbound to the planUI

        UI · bound to the plan

        The exact diff is shown, and approval is tied to that plan; change the plan and it needs approving again.

        Talks to

        • ← Change plan
        • → Snapshot (approved)
    3. CApply· 4Snapshot · Recheck · Exact edits · Readback
      • Snapshotbackups firstJOB

        JOB · backups first

        Backs up every target and verifies the backups before anything is touched.

        Talks to

        • ← Diff + approval (approved)
        • → Recheck
      • Recheckstale hash voids itSERVICE

        SERVICE · stale hash voids it

        Checks each file still matches its hash from the plan. If it changed since approval, the approval no longer counts.

        Talks to

        • ← Snapshot
        • → Exact edits
      • Exact editsper file, per contextSERVICE

        SERVICE · per file, per context

        Applies only the approved edits.

        Talks to

        • ← Recheck
        • → Readback
      • Readbackafter hashes · fieldsSERVICE

        SERVICE · after hashes · fields

        Reopens every changed file and compares it to the approved result, byte for byte and field by field.

        Talks to

        • ← Exact edits
        • → Receipt (pass)
        • → Needs a person (fail)
    4. DOutcome· 3Needs a person · Resume · Receipt
      • Needs a personnever a false successSERVICE

        SERVICE · never a false success

        Any failure, interruption or missing backup stops here, with the backups kept.

        Talks to

        • ← Readback (fail)
        • → Resume
      • Resumebefore · after · conflictSERVICE

        SERVICE · before · after · conflict

        On restart each file is classed from its actual bytes; finished edits are never repeated, and nothing is rolled back over someone else’s changes.

        Talks to

        • ← Needs a person
      • Receiptmeasured, not claimedSTORE

        STORE · measured, not claimed

        Reports only what was measured: sections, changed files, checkpoint and any tokens still unfilled.

        Talks to

        • ← Readback (pass)
    Connections · 11

    → request · ⇢ webhook, queue or schedule

    1. Ten sections → Staged answers
    2. Section re-run → Staged answers
    3. Staged answers → Change plan
    4. Change plan → Diff + approval
    5. Diff + approval → Snapshot · approved
    6. Snapshot → Recheck
    7. Recheck → Exact edits
    8. Exact edits → Readback
    9. Readback → Receipt · pass
    10. Readback → Needs a person · fail
    11. Needs a person → Resume

    Two flows

    An idea becomes a formal bid

    Walk through it and each step lights the parts it runs through in the drawings above.

    By count

    plugins
    6
    skills
    38
    agents
    3
    setup sections
    10

    Notes

    1. N.1Setup is a ten-minute interview: name, colors, logos, how you talk, who your clients are. Every document after that uses it.
    2. N.2Every skill is plain Markdown. You can open one and change how it works.
    3. N.3Push your configured copy to a private repo and your whole team gets your company’s skills with no setup.
    4. N.4A finished document can’t be saved with a blank {{TOKEN}} left in it.
    Contractor Toolkit website
  7. 01.7

    ContentSphere

    Content system. Each client’s newsletters, LinkedIn posts and web copy, planned from their brand and drafted from prompts written for them. The client approves every piece.

    Live · internal

    Full page →
    Fig.A content studio for Formwork’s clients: newsletters, LinkedIn posts and web copy, planned from each brand and approved by the client.

    Architecture

    1. APeople· 3Writers · admins · Client portal · Claude
      • Writers · adminsNext.js 15UI

        UI · Next.js 15

        Formwork’s content team: brand, plans, pieces, approvals and the calendar, one client at a time.

        Talks to

        • → Content pieces (edit)
      • Client portalper clientUI

        UI · per client

        Clients read their pieces, comment and approve.

        Talks to

        • → Review (approve)
      • ClaudeMCP clientEXTERNAL

        EXTERNAL · MCP client

        Claude, connected with a scoped key, working the same content through MCP.

        Talks to

        • → MCP server (MCP · key)
    2. BApp· 10Brand strategy · Personas · Transcripts · Content plans · MCP server · Prompt matrix · Generation · Content pieces · Review · Calendar
      • Brand strategyversionedSERVICE

        SERVICE · versioned

        Each client’s positioning, pillars and voice, with every version kept.

        Talks to

        • → Personas
        • → Content plans (informs)
      • Personasaudiences · frameworksSERVICE

        SERVICE · audiences · frameworks

        Who the client is talking to, and the messaging frameworks for each audience.

        Talks to

        • ← Brand strategy
      • Transcriptsclient callsSERVICE

        SERVICE · client calls

        Calls with the client, kept as source material for topics.

        Talks to

        • → Content plans (topics)
      • Content plansmonthlySERVICE

        SERVICE · monthly

        The month’s topics per channel, drawn from the strategy and the calls.

        Talks to

        • ← Brand strategy (informs)
        • ← Transcripts (topics)
        • → Content pieces (pieces)
        • → C0 (deliverables)
      • MCP server112 tools · scoped keysAI

        AI · 112 tools · scoped keys

        A fresh server per request, with only the tool groups the key’s scopes allow. Keys are stored hashed.

        Talks to

        • ← Claude (MCP · key)
        • ← Six specialists (own tools)
      • Prompt matrixclient × content typeSERVICE

        SERVICE · client × content type

        The instructions for every pairing of client and kind of content.

        Talks to

        • → Generation (instructions)
      • Generationdraft · rewriteAI

        AI · draft · rewrite

        Drafts and rewrites pieces from the matrix, with the client’s context.

        Talks to

        • ← Prompt matrix (instructions)
        • → Content pieces (drafts)
        • → Claude · OpenAI (generate)
      • Content piecesdrafts · versionsSERVICE

        SERVICE · drafts · versions

        One piece per channel, with versioned drafts, comments and a status.

        Talks to

        • ← Content plans (pieces)
        • ← Generation (drafts)
        • ← Writers · admins (edit)
        • → Review
        • → PostgreSQL (SQL)
      • Reviewteam → clientSERVICE

        SERVICE · team → client

        Internal review, then the client’s. A piece can’t enter review without real draft copy.

        Talks to

        • ← Content pieces
        • ← Client portal (approve)
        • → Calendar (approved)
        • → Slack (notify)
      • CalendarscheduledSERVICE

        SERVICE · scheduled

        Approved pieces, on the dates they go out.

        Talks to

        • ← Review (approved)
    3. CAgents· 2Orchestrator · Six specialists
      • OrchestratorClaude Agent SDKAI

        AI · Claude Agent SDK

        The in-app agent. It hands work to the right specialist.

        Talks to

        • → Six specialists (delegates)
        • → Claude · OpenAI
      • Six specialistsstrategy → campaignsAI

        AI · strategy → campaigns

        Specialists from strategy and writing to prompts and campaigns, each limited to the tools its job needs, plus one tool to hand work to another.

        Talks to

        • ← Orchestrator (delegates)
        • → MCP server (own tools)
    4. DData· 1PostgreSQL
      • PostgreSQLPrismaSTORE

        STORE · Prisma

        Clients, strategy, plans, pieces, versions and comments.

        Talks to

        • ← Content pieces (SQL)
    5. EOutside· 3Claude · OpenAI · C0 · Slack
      • Claude · OpenAImodelsEXTERNAL

        EXTERNAL · models

        The models behind drafting and the agents.

        Talks to

        • ← Generation (generate)
        • ← Orchestrator
      • C0deliverables APIEXTERNAL

        EXTERNAL · deliverables API

        Formwork’s operations system, where each piece is also a tracked deliverable.

        Talks to

        • ← Content plans (deliverables)
      • SlacknotificationsEXTERNAL

        EXTERNAL · notifications

        Tells the team when work needs them.

        Talks to

        • ← Review (notify)
    Connections · 18

    → request · ⇢ webhook, queue or schedule

    1. Brand strategy → Personas
    2. Brand strategy → Content plans · informs
    3. Transcripts → Content plans · topics
    4. Content plans → Content pieces · pieces
    5. Prompt matrix → Generation · instructions
    6. Generation → Content pieces · drafts
    7. Generation → Claude · OpenAI · generate
    8. Writers · admins → Content pieces · edit
    9. Content pieces → Review
    10. Client portal → Review · approve
    11. Review → Calendar · approved
    12. Review ⇢ Slack · notify
    13. Content plans → C0 · deliverables
    14. Claude → MCP server · MCP · key
    15. Orchestrator → Six specialists · delegates
    16. Six specialists → MCP server · own tools
    17. Orchestrator → Claude · OpenAI
    18. Content pieces → PostgreSQL · SQL

    Inside: specialist agents and the prompt matrix

    The in-app agent isn’t one model with every tool. An orchestrator hands work to specialists that each see only their own tools, and every draft starts from instructions written for that client, that kind of content and that reader.

    1. AAsk· 2Agent chat · Claude
      • Agent chatin the appUI

        UI · in the app

        Where the team asks for plans, drafts and campaigns in plain words.

        Talks to

        • → Orchestrator
      • ClaudeMCP clientEXTERNAL

        EXTERNAL · MCP client

        Claude outside the app, using the same tools through a scoped key.

        Talks to

        • → Tool subsets (MCP)
    2. BLead· 2Orchestrator · Agent prompts
      • Orchestratorstreams · tool roundsAI

        AI · streams · tool rounds

        Streams its answer, runs tool calls in rounds up to a limit, and delegates to one of six specialists.

        Talks to

        • ← Agent chat
        • ← Agent prompts (instructions)
        • → Strategist (delegates)
        • → Creator
        • → Campaign manager
        • → Prompt engineer
      • Agent promptseditableSTORE

        STORE · editable

        Each agent’s instructions live in the database, so they can be tuned without a deploy, with built-in defaults if the database is unavailable.

        Talks to

        • → Orchestrator (instructions)
    3. CSpecialists· 5Strategist · Creator · Campaign manager · Prompt engineer · Tool subsets
      • Strategistbrand · audiencesAI

        AI · brand · audiences

        Brand strategy, audiences, messaging frameworks, pillars and client context.

        Talks to

        • ← Orchestrator (delegates)
      • Creatorpieces · draftsAI

        AI · pieces · drafts

        Writes and manages pieces: LinkedIn posts, newsletters, case studies, articles.

        Talks to

        • ← Orchestrator
        • → Client prompts (reads)
      • Campaign managerplans · calendar · shootsAI

        AI · plans · calendar · shoots

        Content plans, the editorial calendar, photo and video shoots, assets, and updates from construction projects.

        Talks to

        • ← Orchestrator
      • Prompt engineerprompts · personasAI

        AI · prompts · personas

        Designs the prompt matrix and personas, and tunes generation quality.

        Talks to

        • ← Orchestrator
        • → Tool subsets
      • Tool subsetsper specialistSERVICE

        SERVICE · per specialist

        Each specialist gets its own list of tools plus one to hand work to another; nothing else is offered to it.

        Talks to

        • ← Claude (MCP)
        • ← Prompt engineer
    4. DMatrix· 3Client prompts · Default matrix · Draft
      • Client promptsclient · type · personaSTORE

        STORE · client · type · persona

        Instructions written for one client and one kind of content, optionally for one persona. These win when they exist.

        Talks to

        • ← Creator (reads)
        • → Draft (first choice)
      • Default matrixfallbackSTORE

        STORE · fallback

        The house prompts, used when a client has none of its own.

        Talks to

        • → Draft (fallback)
      • Drafttraced to its promptAI

        AI · traced to its prompt

        The generated draft records which prompt produced it, so a bad draft can be traced to its instructions.

        Talks to

        • ← Client prompts (first choice)
        • ← Default matrix (fallback)
    Connections · 11

    → request · ⇢ webhook, queue or schedule

    1. Agent chat → Orchestrator
    2. Agent prompts → Orchestrator · instructions
    3. Orchestrator → Strategist · delegates
    4. Orchestrator → Creator
    5. Orchestrator → Campaign manager
    6. Orchestrator → Prompt engineer
    7. Claude → Tool subsets · MCP
    8. Prompt engineer → Tool subsets
    9. Creator → Client prompts · reads
    10. Client prompts → Draft · first choice
    11. Default matrix → Draft · fallback

    Two flows

    A topic becomes a published piece

    Walk through it and each step lights the parts it runs through in the drawings above.

    By count

    specialist agents
    6
    rounds of review: team, then client
    2
    actions Claude can take in it
    112

    Notes

    1. N.1Prompts are a matrix of client by kind of content. A newsletter for one contractor and a LinkedIn post for another start from different instructions.
    2. N.2Six specialist agents, from strategy to campaigns. Each gets only the tools its job needs, plus one to hand work to another.
    ContentSphere website
  8. 01.8

    C0

    Internal operations system. Runs Formwork day to day: clients, projects, tasks and invoices in one place, synced with the books. After each meeting, Claude drafts the follow-up tasks.

    Live · runs Formwork

    Full page →
    Fig.How Formwork runs: sales, clients, work, money and meetings in one place, with a portal for each kind of person.

    Architecture

    1. APortals· 5Executive · Manager · member · Client · Prospect · Claude
      • ExecutiveportalUI

        UI · portal

        The whole firm: money, clients, people and objectives.

        Talks to

        • → Middleware (cookie)
      • Manager · memberportalsUI

        UI · portals

        Managers see their team; members see their own tasks and time.

      • ClientportalUI

        UI · portal

        Clients see their services, billing, content, outreach and tasks.

        Talks to

        • → Middleware
      • ProspectportalUI

        UI · portal

        A prospect’s own view of what Formwork offers them.

      • ClaudeMCP clientEXTERNAL

        EXTERNAL · MCP client

        Claude over MCP, with tools scoped to the person’s role.

        Talks to

        • → MCP server (MCP)
    2. BApp· 11Middleware · Prospects · Clients · Projects · tasks · Invoices · expenses · MCP server · Meetings · Task drafting · Knowledge base · Bank matching · Chat agent
      • MiddlewareJWT · role routesSERVICE

        SERVICE · JWT · role routes

        Checks the session cookie, routes each role to its portal, and catches a role that changed since sign-in.

        Talks to

        • ← Executive (cookie)
        • ← Client
        • → Clients (by role)
      • ProspectsproposalsSERVICE

        SERVICE · proposals

        Prospects and proposals, until one converts to a client.

        Talks to

        • → Clients (converts)
      • Clientsservices · healthSERVICE

        SERVICE · services · health

        Each client and the services they buy, with one health score from 0 to 100.

        Talks to

        • ← Middleware (by role)
        • ← Prospects (converts)
        • → Projects · tasks
        • → Invoices · expenses (bills)
        • → Sales & content (outreach · content)
      • Projects · taskstime logsSERVICE

        SERVICE · time logs

        The work for each service, with dependencies and time logged.

        Talks to

        • ← Clients
        • ← Task drafting (drafts)
        • → PostgreSQL (SQL)
        • → Airtable (dual write)
      • Invoices · expensespaymentsSERVICE

        SERVICE · payments

        Invoices, payments and expenses, allocated to clients and services.

        Talks to

        • ← Clients (bills)
        • ← Plaid (bank feeds)
        • ← Bank matching (matches)
      • MCP server250+ tools by roleAI

        AI · 250+ tools by role

        Tools composed by role: a client sees about ten, an executive over two hundred.

        Talks to

        • ← Claude (MCP)
        • ← Chat agent (catalogue)
        • → Knowledge base (kb tools)
      • MeetingstranscriptsSERVICE

        SERVICE · transcripts

        Each meeting and its transcript, with a badge until its drafted tasks are approved.

        Talks to

        • → Task drafting (transcript)
        • → Knowledge base (mined)
      • Task draftingClaudeAI

        AI · Claude

        Drafts follow-up tasks from a transcript, with the context around the meeting.

        Talks to

        • ← Meetings (transcript)
        • → Projects · tasks (drafts)
        • → Claude · OpenRouter
      • Knowledge basefacts · reviewAI

        AI · facts · review

        Claims mined from meetings, embedded and merged into facts. New ones are candidates until a second model verifies them.

        Talks to

        • ← Meetings (mined)
        • ← MCP server (kb tools)
      • Bank matchingconfidence tiersSERVICE

        SERVICE · confidence tiers

        Matches each cash line from the books to an invoice, a subscription or a person, with a confidence score. Only the surest can be approved in bulk.

        Talks to

        • ← QuickBooks (webhooks)
        • → Invoices · expenses (matches)
      • Chat agentsearch · describe · runAI

        AI · search · describe · run

        Above a threshold it gets a category index and three meta-tools instead of every schema, and loads only the tools it means to call.

        Talks to

        • → MCP server (catalogue)
    3. CJobs· 2Due-date checks · Scheduled email
      • Due-date checksscheduledJOB

        JOB · scheduled

        Flags tasks coming due and invoices gone overdue.

        Talks to

        • → Slack (alerts)
      • Scheduled emailscheduledJOB

        JOB · scheduled

        Sends reports and scheduled emails.

    4. DData· 2PostgreSQL · Airtable
      • PostgreSQLprimary · PrismaSTORE

        STORE · primary · Prisma

        Where every read comes from.

        Talks to

        • ← Projects · tasks (SQL)
      • Airtabledual writeSTORE

        STORE · dual write

        Writes for tasks, time and money also land here, so the rollups people already use stay right.

        Talks to

        • ← Projects · tasks (dual write)
    5. EOutside· 5QuickBooks · Plaid · Sales & content · Slack · Claude · OpenRouter
      • QuickBooksOAuth · webhooksEXTERNAL

        EXTERNAL · OAuth · webhooks

        The books. Its webhooks bring each change across.

        Talks to

        • → Bank matching (webhooks)
      • Plaidbank feeds · webhooksEXTERNAL

        EXTERNAL · bank feeds · webhooks

        Live bank balances and transactions.

        Talks to

        • → Invoices · expenses (bank feeds)
      • Sales & contentFormwork’s own appsEXTERNAL

        EXTERNAL · Formwork’s own apps

        OutreachSphere and ContentSphere, read for each client’s outreach and content.

        Talks to

        • ← Clients (outreach · content)
      • SlackalertsEXTERNAL

        EXTERNAL · alerts

        Where the due-date and overdue alerts land.

        Talks to

        • ← Due-date checks (alerts)
      • Claude · OpenRoutermodelsEXTERNAL

        EXTERNAL · models

        The models behind drafting, the knowledge base and the agent.

        Talks to

        • ← Task drafting
    Connections · 20

    → request · ⇢ webhook, queue or schedule

    1. Executive → Middleware · cookie
    2. Client → Middleware
    3. Middleware → Clients · by role
    4. Prospects → Clients · converts
    5. Clients → Projects · tasks
    6. Clients → Invoices · expenses · bills
    7. Meetings → Task drafting · transcript
    8. Task drafting → Projects · tasks · drafts
    9. Meetings → Knowledge base · mined
    10. Task drafting → Claude · OpenRouter
    11. QuickBooks ⇢ Bank matching · webhooks
    12. Plaid ⇢ Invoices · expenses · bank feeds
    13. Bank matching → Invoices · expenses · matches
    14. Claude → MCP server · MCP
    15. Chat agent → MCP server · catalogue
    16. MCP server → Knowledge base · kb tools
    17. Projects · tasks → PostgreSQL · SQL
    18. Projects · tasks ⇢ Airtable · dual write
    19. Due-date checks ⇢ Slack · alerts
    20. Clients → Sales & content · outreach · content

    Inside: meetings, tasks and what Formwork knows

    A meeting does two jobs. It becomes tasks people approve, and it teaches the firm something: claims are pulled out, matched to the people and companies they’re about, deduplicated, checked by a second model, and fed back into the next meeting about that client.

    1. AIn· 3Transcript · Meeting context · Account memory
      • Transcriptper meetingUI

        UI · per meeting

        The meeting’s transcript, internal or with a client.

        Talks to

        • → Meeting context
      • Meeting contextpeople · services · goalsSERVICE

        SERVICE · people · services · goals

        Who was there, the client and their active services, and the firm’s current objectives and projects, so tasks land in the right place.

        Talks to

        • ← Transcript
        • → Tasks + summary
      • Account memorywhat we already knowAI

        AI · what we already know

        What the firm already knows about this client, injected before analysis. A knowledge-base failure never blocks the meeting.

        Talks to

        • → Tasks + summary (injected)
        • → Search (account spine)
    2. BAnalysis· 3Tasks + summary · Approval · Slack
      • Tasks + summaryClaude · in parallelAI

        AI · Claude · in parallel

        Writes the meeting summary and the follow-up tasks at the same time, each with an assignee, a service, a project and a due date.

        Talks to

        • ← Meeting context
        • ← Account memory (injected)
        • → Approval (drafts)
        • → Slack
        • → Claim extraction (transcript)
      • Approvalbadge until approvedUI

        UI · badge until approved

        Drafted tasks wait for a person. Until they are approved the meeting shows a badge.

        Talks to

        • ← Tasks + summary (drafts)
      • Slacksummary · tasksEXTERNAL

        EXTERNAL · summary · tasks

        The summary and the drafted tasks are posted to Slack.

        Talks to

        • ← Tasks + summary
    3. CLearn· 5Claim extraction · Entity resolution · Dedup · Auto-review · Latest wins
      • Claim extractionHaiku · Sonnet if unsureAI

        AI · Haiku · Sonnet if unsure

        Picks out claims worth keeping about the industry, the client or the business, tagged from a fixed vocabulary of 22 topics. Internal meetings need more confidence to count.

        Talks to

        • ← Tasks + summary (transcript)
        • → Entity resolution (mentions)
        • → Dedup (claims)
      • Entity resolutionnames · aliasesSERVICE

        SERVICE · names · aliases

        Maps “Logan”, “Logan Smith” and “chief estimator” to the same person, following merges; a new name starts as a candidate for review.

        Talks to

        • ← Claim extraction (mentions)
        • → Entity graph
      • Deduphash · cosine 0.92SERVICE

        SERVICE · hash · cosine 0.92

        An exact restatement or a near-duplicate becomes a new citation on the existing fact instead of a new row.

        Talks to

        • ← Claim extraction (claims)
        • → Facts
      • Auto-reviewsecond modelAI

        AI · second model

        Verifies or rejects new facts. Nothing is verified on the way in; borderline ones stay for a person to spot-check.

        Talks to

        • → Facts (verify)
      • Latest winssupersededSERVICE

        SERVICE · superseded

        When a newer claim replaces an old one, the old one is marked superseded rather than deleted.

        Talks to

        • → Facts
    4. DRecall· 4Facts · Entity graph · Search · kb tools
      • Factspgvector · 1024-dSTORE

        STORE · pgvector · 1024-d

        Canonical facts with their citations, embedded with one locked model whose name is stored beside each vector for future migrations.

        Talks to

        • ← Dedup
        • ← Auto-review (verify)
        • ← Latest wins
        • ← Search
      • Entity graphtyped edgesSTORE

        STORE · typed edges

        People, companies and projects, linked to the account they belong to.

        Talks to

        • ← Entity resolution
      • Searchverified-onlySERVICE

        SERVICE · verified-only

        Semantic search with metadata filters, verified facts only by default so agents don’t retrieve noise, plus a keyed account spine, newest first.

        Talks to

        • → Facts
        • ← kb tools
        • ← Account memory (account spine)
      • kb toolsMCPAI

        AI · MCP

        Search, expand an entity, add or verify a fact, and the review queue, for any agent.

        Talks to

        • → Search
    Connections · 15

    → request · ⇢ webhook, queue or schedule

    1. Transcript → Meeting context
    2. Meeting context → Tasks + summary
    3. Account memory → Tasks + summary · injected
    4. Tasks + summary → Approval · drafts
    5. Tasks + summary ⇢ Slack
    6. Tasks + summary → Claim extraction · transcript
    7. Claim extraction → Entity resolution · mentions
    8. Claim extraction → Dedup · claims
    9. Entity resolution → Entity graph
    10. Dedup → Facts
    11. Auto-review ⇢ Facts · verify
    12. Latest wins → Facts
    13. Search → Facts
    14. kb tools → Search
    15. Account memory → Search · account spine

    Two flows

    A meeting becomes work

    Walk through it and each step lights the parts it runs through in the drawings above.

    By count

    portals: executive, manager, member, client, prospect
    5
    actions Claude can take in it
    250+

    Notes

    1. N.1Client health is one number from 0 to 100, computed in one place, so the members list, the invoice header and the exec dashboard never disagree.
    2. N.2Clients get their own portal with their services, billing, content, outreach and tasks.
    3. N.3Bank lines are matched to invoices and people with a confidence score. Only the surest matches can be approved in bulk.
  9. 01.9

    Delta Portal

    MATTER, deployed for Delta. Delta’s deployment of MATTER: RFIs, bids, contracts and chat. It replaced Procore, a $48K-a-year bill; about 400 past projects moved off it in about two hours.

    Live · Delta Construction

    Full page →
    Fig.Delta Construction’s deployment of MATTER, for its own team and for the architects and subs it works with.

    Architecture

    1. APeople· 2Delta’s team · Architects & subs
      • Delta’s teamweb · phones · iPadsUI

        UI · web · phones · iPads

        Delta’s project managers, engineers and field staff, in the app.

        Talks to

        • → Public API (HTTPS)
        • → Live sockets (live)
      • Architects & subsemailed linksUI

        UI · emailed links

        People outside Delta. They answer RFIs and submit bids from a link, without an account.

        Talks to

        • → Public API (emailed link)
    2. BGateway· 2Public API · Live sockets
      • Public APISpring Boot · JWTSERVICE

        SERVICE · Spring Boot · JWT

        Checks who is asking and forwards each request with their identity. Link tokens are checked here too.

        Talks to

        • ← Delta’s team (HTTPS)
        • ← Architects & subs (emailed link)
        • → Project (REST)
        • → Bid packages (REST)
      • Live socketsWebSocketsREALTIME

        REALTIME · WebSockets

        Pushes chat and notifications to open apps as they happen.

        Talks to

        • ← Delta’s team (live)
        • ← Redis (pub/sub)
    3. CProject· 9Project · RFIs · Submittals · Drawings · Chat · Bid packages · Bids · Contracts · Notifications
      • Projectteam · directorySERVICE

        SERVICE · team · directory

        Everything hangs off a project and the companies and people on it.

        Talks to

        • ← Public API (REST)
        • → Bid packages (packages)
        • → PostgreSQL (SQL)
        • ← Procore (import)
      • RFIsball in courtSERVICE

        SERVICE · ball in court

        Questions to the design team, with the ball moving between companies as the RFI is answered.

      • Submittalsrevise & resubmitSERVICE

        SERVICE · revise & resubmit

        Submittals go round in revisions until approved.

      • Drawingssheets · revisionsSERVICE

        SERVICE · sheets · revisions

        Plan sets split into sheets, with revisions side by side.

        Talks to

        • → Object storage (files)
        • → Autodesk APS (linked files)
      • Chatreal timeSERVICE

        SERVICE · real time

        Project conversations, live.

        Talks to

        • → Redis (publish)
      • Bid packagesinvites · levelingSERVICE

        SERVICE · invites · leveling

        A trade’s scope packaged for bidding, with the subs invited to it.

        Talks to

        • ← Public API (REST)
        • ← Project (packages)
        • → Bids (collects)
      • BidsSOV · alternatesSERVICE

        SERVICE · SOV · alternates

        Each sub’s bid, with a schedule of values and any alternates, levelled against the others.

        Talks to

        • ← Bid packages (collects)
        • → Contracts (awarded)
      • ContractsSOV from the awardSERVICE

        SERVICE · SOV from the award

        The awarded bid’s schedule of values is carried onto a payable contract on the same project.

        Talks to

        • ← Bids (awarded)
      • Notificationsin-app · emailSERVICE

        SERVICE · in-app · email

        Tells people when something they own moves.

        Talks to

        • → Redis (publish)
    4. DData· 3PostgreSQL · Object storage · Redis
      • PostgreSQLSTORE

        STORE

        The record of every project, RFI, bid and contract.

        Talks to

        • ← Project (SQL)
      • Object storageS3-compatibleSTORE

        STORE · S3-compatible

        Drawings, attachments and photos.

        Talks to

        • ← Drawings (files)
      • Redispub/subSTORE

        STORE · pub/sub

        Carries chat and notification events to the sockets.

        Talks to

        • ← Chat (publish)
        • ← Notifications (publish)
        • → Live sockets (pub/sub)
    5. ELinks· 2Procore · Autodesk APS
      • Procoreone-time importEXTERNAL

        EXTERNAL · one-time import

        Projects came across from Procore once. Nothing writes back.

        Talks to

        • → Project (import)
      • Autodesk APSfolders · filesEXTERNAL

        EXTERNAL · folders · files

        Delta’s Autodesk folders and files, linked to the project.

        Talks to

        • ← Drawings (linked files)
    Connections · 15

    → request · ⇢ webhook, queue or schedule

    1. Delta’s team → Public API · HTTPS
    2. Architects & subs → Public API · emailed link
    3. Delta’s team → Live sockets · live
    4. Public API → Project · REST
    5. Public API → Bid packages · REST
    6. Project → Bid packages · packages
    7. Bid packages → Bids · collects
    8. Bids → Contracts · awarded
    9. Chat ⇢ Redis · publish
    10. Notifications ⇢ Redis · publish
    11. Redis ⇢ Live sockets · pub/sub
    12. Project → PostgreSQL · SQL
    13. Drawings → Object storage · files
    14. Drawings → Autodesk APS · linked files
    15. Procore ⇢ Project · import

    One flow

    A bid package becomes a subcontract

    Walk through it and each step lights the parts it runs through in the drawings above.

    By count

    past projects moved off Procore, in about two hours
    ~400
    a year of Procore licensing, replaced
    $48K

    Notes

    1. N.1It replaced Procore, whose bill grew as Delta did. Projects were brought over from Procore once; nothing writes back to it.
    2. N.2About 180 active projects and $14M in contracts run through it, with hundreds of RFIs a week.
    3. N.3People outside Delta answer RFIs and submit bids from an emailed link, so the people who owe a reply don’t need a login.
    4. N.4Chat is live, and you aren’t notified about a conversation you’re already reading.
  10. 01.10

    Delta Estimating Portal

    Bid pipeline & CRM. Shows Delta’s estimators what they’re bidding and when: each bid gets a slot with a name, dates and hours, beside the client account.

    Live · Delta Construction

    Full page →
    Fig.Delta’s bid pipeline: what the estimators are working on, for whom, and when.

    Architecture

    1. APeople· 2Delta’s team · Estimators
      • Delta’s teamweb appUI

        UI · web app

        The people who log leads and look after client accounts.

        Talks to

        • → Leads (logs)
      • Estimatorstheir scheduleUI

        UI · their schedule

        Each estimator sees what they’re bidding, and when.

        Talks to

        • → Estimating slots (their week)
    2. BPipeline· 8Leads · Follow-ups · Estimating slots · Estimator profiles · Client accounts · Contacts · Interactions · Project
      • Leadsstatuses you setSERVICE

        SERVICE · statuses you set

        Every bid opportunity, moving through statuses the team defines.

        Talks to

        • ← Delta’s team (logs)
        • → Client accounts (for)
        • → Follow-ups
        • → Estimating slots (scheduled)
        • → Project (won)
      • Follow-upscalls · emailsSERVICE

        SERVICE · calls · emails

        Calls and emails due on a lead, logged when done.

        Talks to

        • ← Leads
        • → Interactions (logged as)
      • Estimating slotswho · dates · hoursSERVICE

        SERVICE · who · dates · hours

        A bid on the estimating schedule: which estimator, which dates, hours planned and hours actually spent.

        Talks to

        • ← Estimators (their week)
        • ← Leads (scheduled)
        • → Estimator profiles (assigned)
      • Estimator profilesspecialtiesSERVICE

        SERVICE · specialties

        Each estimator and their specialties.

        Talks to

        • ← Estimating slots (assigned)
      • Client accountsSERVICE

        SERVICE

        The companies Delta bids for, with their own statuses.

        Talks to

        • ← Leads (for)
        • → Contacts
      • ContactsSERVICE

        SERVICE

        The people at each account.

        Talks to

        • ← Client accounts
      • InteractionstimelineSERVICE

        SERVICE · timeline

        Every call, email and meeting with an account, on one timeline.

        Talks to

        • ← Follow-ups (logged as)
        • → PostgreSQL (SQL)
      • Projectwhen it’s wonSERVICE

        SERVICE · when it’s won

        A won lead becomes a project.

        Talks to

        • ← Leads (won)
    3. CData· 1PostgreSQL
      • PostgreSQLSTORE

        STORE

        The record of leads, accounts and the schedule.

        Talks to

        • ← Interactions (SQL)
    Connections · 10

    → request · ⇢ webhook, queue or schedule

    1. Delta’s team → Leads · logs
    2. Estimators → Estimating slots · their week
    3. Leads → Client accounts · for
    4. Client accounts → Contacts
    5. Leads → Follow-ups
    6. Follow-ups → Interactions · logged as
    7. Leads → Estimating slots · scheduled
    8. Estimating slots → Estimator profiles · assigned
    9. Leads → Project · won
    10. Interactions → PostgreSQL · SQL

    One flow

    A lead gets an estimator

    Walk through it and each step lights the parts it runs through in the drawings above.

    Notes

    1. N.1An estimating slot keeps the hours planned next to the hours actually spent, per estimator.
    2. N.2The team sets its own lead statuses, so the pipeline uses their words.

All systems on one page ↗

Résumé

Virginia, USA

I’m a systems architect in Virginia. In 2024 I co-founded Formwork, and I build the software it and its clients run on.

Since 2022 I’ve also been at CGI Federal, building AI for Medicare and Medicaid. On my own time I build a synth and AI tools that test software and run agents. I studied computer information systems at James Madison.

  1. Nov 2024 to now

    Formwork

    Technical Co-Founder & CTO

    Formwork does sales, marketing and software for commercial construction contractors. I built all of its technology, and I decide how it fits together across the three units. It started as Sunrise Systems.

  2. Jun 2022 to now

    CGI Federal

    Senior Consultant1

    I work in the Health and Social Services unit. I built the AI prototypes that led to a contract award from the Centers for Medicare & Medicaid Services. I also built the tracking systems and the dashboards leadership uses to see the team’s work.

    1“He has been integral in the development of tracking systems and dashboards, automating and displaying team function at an executive level.”
    William HallDirector of Emerging IP, CGI Federal
  3. Class of 2023

    James Madison University

    B.B.A. Computer Information Systems2

    2“You have shown a speed and ability to solve problems that I have not seen in my students before.”
    Dr. Dmytro BabikProfessor of Information Systems, James Madison University

After hours

Off the clock

When I’m not at work I’m usually still building: SIGIL, Orbit and Thronos all started as side projects.

I read, I look after my two dogs, Pixel and Melon, and I follow racing, which is why this site is a race.

Writing

Guides for Formwork, letters on HEY World

Work with me

I take on a few product builds outside Formwork. I design the system and write the code.

Tell me what you’re making. I read every message myself and reply within a couple of days.

2 product slots open for Q4

Form

This is about
Budgetoptional
Timelineoptional