James Madison University, class of 2023. Computer information systems, in the business school.
James Madison University
B.B.A. Computer Information Systems, 2023
“
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
NARAMLAP 1/5
Lap 2Spa-Francorchamps, Belgium
CGIFederal.
My day job since 2022: AI software for Medicare and Medicaid programs.
CGI Federal
Jun 2022 to now
Senior Consultant
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.
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
Lap 3Sakhir, Bahrain
Formwork.
Co-founded in 2024. Commercial contractors hire it for sales, marketing and software. I build the software.
Formwork
Nov 2024 to now
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.
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
DeltaPortal
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
DeltaEstimatingPortal
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.
Delta, a $9M general contractor, ran its projects on Procore: about $48K a year and climbing as Delta grew. A rough estimate took a senior estimator weeks.
Delta Portal, a deployment of MATTER: RFIs, bidding, contracts and chat in one system. About 400 past projects came off Procore in about two hours.
About 180 active projects and $14M in contracts run on it. Rough estimates take minutes.
Case 02EFI
After an ownership change, EFI lost access to 25 years of records: an old Access database on a laptop, holding about $54M of past projects and 4,500 client contacts.
We got into the laptop, pulled the data out, designed a new schema and moved it to a cloud database.
25 years of records are back, running as EFI’s cloud ERP.
Case 03CGI Federal
An AI idea had to prove itself before a federal agency would commit.
I built the working prototypes.
CMS awarded the contract.
Case 04Open source
Senior project managers spend their time on estimates, proposals and paperwork.
Contractor Toolkit: AI plugins that write estimates, proposals, RFIs, submittals and daily logs in the company’s own brand.
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.
02
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.
03
Built a 234-tool MCP server so Claude can work inside a live construction platform with each person’s exact permissions.
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.
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
Hover a box to trace its connections; click it for what it does.
request
webhook, queue, schedule
the heart
outside service
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)
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)
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.
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.
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.
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.
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.
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)
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
Web app → Public API · HTTPS · JWT
Respond by link → Public API · token
Missive sidebar → Public API
Web app → Live sockets · live
Claude & MCP clients → MCP endpoint · MCP
Claude & MCP clients → OAuth server · OAuth
Public API → AI service · proxy
MCP endpoint → Tool registry · as the user
AI service → Tool registry · list · call
Agents → AI service
AI service → Claude · OpenRouter · stream
Catalogue ingestion → Catalogues
Tool registry → Projects · every domain
Public API → Projects · REST
Leads & CRM → Estimating schedule
Estimating schedule → Scope & estimate
Catalogues → Scope & estimate
Bidding → Scope & estimate · carry a bid
Scope & estimate → Client proposals · priced
Client proposals → Contracts & SOV · accepted
Bidding → Contracts & SOV · award
Change orders → Contracts & SOV
Contracts & SOV → Pay applications
AI service → Daily logs
RFIs → Notifications · ball moved
Chat ⇢ Redis 7 · publish
Notifications ⇢ Redis 7
Redis 7 ⇢ Live sockets · pub/sub
Notifications ⇢ Mail queue
Mail queue ⇢ Company mail · SMTP
Scheduled jobs ⇢ Notifications
Drawings → Object storage
Exhibit approvals → Drawings
Files & folders → Autodesk APS
Procore ⇢ Projects · import
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.
Hover a box to trace its connections; click it for what it does.
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
Leads → Follow-ups
Leads → Estimating slot · scheduled
Leads → Win/loss analysis · won · lost
Leads → Estimate stages · becomes a project
Estimate stages → Scope tree
Catalogues → Scope tree
Scope tree → Revisions · snapshot
Bid packages → Carry a bid
Carry a bid → Scope tree · prices lines
Scope tree → Pricing
Pricing → Client proposal · priced scope
Client proposal → Review & send
Review & send → Client’s decision
Client’s decision → Pricing · locks prices
Client’s decision → Prime contract · accepted
Bid packages → Subcontracts · award
Subcontracts → Pay applications
Prime contract → Pay applications
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
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.
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.
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.
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.
Fig.Swipe across to see all of it. MATTER’s core data model.
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.
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
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
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
Campaign managers → Lead lists · CSV
Lead lists → Enrichment · gaps
Enrichment drain ⇢ Enrichment · queued
Enrichment → Data providers · in turn
Lead lists → Sequences · filtered
Sequences → Smartlead · push
Sequences → Valley
Smartlead ⇢ Webhook intake · webhooks
Valley ⇢ Webhook intake · webhooks
Nylas ⇢ Webhook intake · webhooks
Webhook intake → Reply triage · replies
Reply triage → Claude · OpenAI · classify
Reply triage ⇢ Slack · alert
Reply triage → Reply approvals · real leads
Reply pre-drafts ⇢ Reply approvals · drafts
SDR desk → Reply approvals · approve
Reply approvals → Smartlead · reply
Reply approvals → CRM · promote
CRM → Opportunities · deal
Client portal → CRM · their pipeline
Claude → MCP server · MCP · token
Sender sync ⇢ Smartlead
Research & prep → Vector store
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.
Hover a box to trace its connections; click it for what it does.
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.
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.
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
Smartlead ⇢ Webhook event
Nylas ⇢ Webhook event
Webhook event → Field extraction
Field extraction → Rules
Rules → Classifier · undecided
Classifier → Confidence floor
Confidence floor → Hot channel · lead · unsure
Confidence floor → Vendor channel · vendor
Confidence floor ⇢ Firehose
Kill switch → Hot channel · override
Confidence floor → Review queue · real leads
Review queue → Draft + suggestions
Pre-drafts ⇢ Draft + suggestions
Draft + suggestions → Approve
Approve → Thread resolver
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
N.1Nobody counts as contacted until the email has actually gone out, so the numbers a client sees are real.
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.
N.3Clients get their own portal with their campaigns, leads and pipeline.
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.
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)
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
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.
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
Browser tab → React UI
MIDI · keyboard → React UI · notes
Presets → Hunt · seeds
Hunt → Names & glyphs · name · mark
Hunt → React UI · six takes
React UI → AudioWorklet · params · notes
AudioWorklet → DSP core · renders
DSP core → Six engines
Six engines → FX & character
React UI → Bounce · record
Bounce · record → Your DAW · drag WAV
React UI → JUCE plugin · bundled
JUCE plugin → C++ engine · process
JUCE plugin → Your DAW · VST3
DSP core → Parity check · goldens
C++ engine → Parity check · compared
Claude → MCP endpoint · MCP
MCP endpoint → Six engines · patches
Browser tab → Server routes · gate
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.
Hover a box to trace its connections; click it for what it does.
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)
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.
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.
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
Engine registry → Descriptors
Descriptors → Built interface · builds
Descriptors → Voice manager · params
Voice manager → Analog · voices
Smoothing → Voice manager
Voice manager → Granular
Physical → Effects chain · mix
Effects chain → Character chain
Seed → Mutate
Breed → Mutate
Taste → Breed · bias
Mutate → Lineage · what changed
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
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.
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.
N.3The plugin and the browser make the same sound, so a patch you find in a tab sounds identical in your DAW.
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.
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
Dashboard → API routes · HTTPS
GitHub ⇢ API routes · webhooks
API routes ⇢ indexing · enqueue
indexing ⇢ Analyst · worker
Analyst → Indexer
Indexer → PostgreSQL · map · embeddings
Analyst → Planner · system map
Planner → Prioritiser
Planner → Claude · GPT · plan
Orchestrator ⇢ execution · run
scheduler ⇢ Orchestrator · schedule
execution ⇢ Executor · worker
Executor → Playwright · Stagehand · CDP
Executor → Self-healer
Self-healer → PostgreSQL · saved fixes
Executor → Object storage · evidence
Executor ⇢ Live stream · screenshots
Live stream ⇢ Dashboard · live
Executor ⇢ reporting · results
reporting ⇢ Reporter · worker
Reporter → GitHub · PR check
Reporter → Linear · Slack
Claude → MCP server · MCP
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.
Hover a box to trace its connections; click it for what it does.
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)
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)
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.
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
Environment check → Dependency order
Dependency order → Auth reuse
Dependency order → API tests · contracts
Auth reuse → Step executor
Provider guard → Step executor · abort
Step executor → Browser · act
Step executor → Stored fix · broken selector
Stored fix → Visible text · miss
Visible text → Label · miss
Label → Role · miss
Role → Model · miss
Model → Selector memory · saved
Step executor → Flaky registry · retries
Step executor → Baselines · on pass
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
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.
N.2It can break things on purpose, like a dropped request or a slow server, to see how the app copes.
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.
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)
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)
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)
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
Decisions → Engine API · approve · reject
Engine API → Governance
Team templates → Heartbeat · seeds
Signals → Heartbeat · what changed
Heartbeat ⇢ Orchestrator · tick
Heartbeat ⇢ Kernel · cheap lanes
Heartbeat ⇢ Autoresearch · nightly
Orchestrator → 14 sub-agents · delegates
Orchestrator → Task loop · claims
14 sub-agents → Agent runner
Agent runner → MCP registry · tools
Agent runner ⇢ Event mesh · output
Agent runner → Mnemos · write · recall
Agent runner → Costs · checks
Kernel → MCP registry · subset
Slack → Kernel · chat
14 sub-agents → Governance · proposals
Autoresearch ⇢ 14 sub-agents · prompts
Self-healing ⇢ 14 sub-agents · revisions
MCP registry → Dev tools · MCP
MCP registry → Company systems · MCP
Integration hub → MCP registry · compiled
Any API → Integration hub · spec
Mnemos → Neo4j
Mnemos → PostgreSQL · vectors
Event mesh ⇢ Redis · publish
Redis ⇢ Live socket · pub/sub
Live socket ⇢ Stage · live
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.
Hover a box to trace its connections; click it for what it does.
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)
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.
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.
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
Run output → Extract
Documents → Extract
From tools → Extract
Experience → Knowledge graph · Experience node
Scenarios → Knowledge graph · world model
Extract → Deduplicate
Deduplicate → Score
Score → Store
Store → Embed
Embed → Connect
Store → Knowledge graph · MERGE
Embed → Embeddings
Connect → Knowledge graph · edges
Compression ⇢ Knowledge graph · L0 → L1
Reflection ⇢ Knowledge graph · insights
Summaries ⇢ Knowledge graph
Decay ⇢ Embeddings · archive
Past experience → Knowledge graph · experiences
HyDE → Hybrid search
Hybrid search → Embeddings · dense
Hybrid search → Graph walk
Graph walk → Filters
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
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.
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.
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.
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.
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.
Fig.Free Claude Code plugins for contractors: tell Claude about your company once, and it writes the paperwork in your brand.
Architecture
Hover a box to trace its connections; click it for what it does.
request
webhook, queue, schedule
the heart
outside service
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)
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.
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.
Hover a box to trace its connections; click it for what it does.
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
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.
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.
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)
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)
DData· 1PostgreSQL+
PostgreSQLPrismaSTORE+
STORE · Prisma
Clients, strategy, plans, pieces, versions and comments.
Talks to
← Content pieces (SQL)
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
Brand strategy → Personas
Brand strategy → Content plans · informs
Transcripts → Content plans · topics
Content plans → Content pieces · pieces
Prompt matrix → Generation · instructions
Generation → Content pieces · drafts
Generation → Claude · OpenAI · generate
Writers · admins → Content pieces · edit
Content pieces → Review
Client portal → Review · approve
Review → Calendar · approved
Review ⇢ Slack · notify
Content plans → C0 · deliverables
Claude → MCP server · MCP · key
Orchestrator → Six specialists · delegates
Six specialists → MCP server · own tools
Orchestrator → Claude · OpenAI
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.
Hover a box to trace its connections; click it for what it does.
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)
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.
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
Agent chat → Orchestrator
Agent prompts → Orchestrator · instructions
Orchestrator → Strategist · delegates
Orchestrator → Creator
Orchestrator → Campaign manager
Orchestrator → Prompt engineer
Claude → Tool subsets · MCP
Prompt engineer → Tool subsets
Creator → Client prompts · reads
Client prompts → Draft · first choice
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
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.
N.2Six specialist agents, from strategy to campaigns. Each gets only the tools its job needs, plus one to hand work to another.
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.
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
Executive → Middleware · cookie
Client → Middleware
Middleware → Clients · by role
Prospects → Clients · converts
Clients → Projects · tasks
Clients → Invoices · expenses · bills
Meetings → Task drafting · transcript
Task drafting → Projects · tasks · drafts
Meetings → Knowledge base · mined
Task drafting → Claude · OpenRouter
QuickBooks ⇢ Bank matching · webhooks
Plaid ⇢ Invoices · expenses · bank feeds
Bank matching → Invoices · expenses · matches
Claude → MCP server · MCP
Chat agent → MCP server · catalogue
MCP server → Knowledge base · kb tools
Projects · tasks → PostgreSQL · SQL
Projects · tasks ⇢ Airtable · dual write
Due-date checks ⇢ Slack · alerts
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.
Hover a box to trace its connections; click it for what it does.
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.
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.
N.2Clients get their own portal with their services, billing, content, outreach and tasks.
N.3Bank lines are matched to invoices and people with a confidence score. Only the surest matches can be approved in bulk.
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.
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)
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)
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
Delta’s team → Public API · HTTPS
Architects & subs → Public API · emailed link
Delta’s team → Live sockets · live
Public API → Project · REST
Public API → Bid packages · REST
Project → Bid packages · packages
Bid packages → Bids · collects
Bids → Contracts · awarded
Chat ⇢ Redis · publish
Notifications ⇢ Redis · publish
Redis ⇢ Live sockets · pub/sub
Project → PostgreSQL · SQL
Drawings → Object storage · files
Drawings → Autodesk APS · linked files
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
N.1It replaced Procore, whose bill grew as Delta did. Projects were brought over from Procore once; nothing writes back to it.
N.2About 180 active projects and $14M in contracts run through it, with hundreds of RFIs a week.
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.
N.4Chat is live, and you aren’t notified about a conversation you’re already reading.
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.
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.
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.
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.”