When truth changes,
patch everywhere it spread.
Every organisation has one source of truth and hundreds of copies of yesterday's truth. The dangerous part isn't that a fact changed β it's that the old fact is still alive in a draft proposal, a CRM record, an open task, and an email you already sent.
What PATCH does
Detect the change, find the spread, generate the right repair for each artefact.
A supplier revises a motor specification from 22 kW to 18.5 kW.
Someone announces it in Slack. That fact already exists in nine other places, and nothing
systematically finds and repairs them.
PATCH takes the announcement, verifies it against external evidence, searches the workspace, and classifies every affected artefact. Then it generates a different repair interface for each one β because repairing a draft and repairing a sent email are not the same problem.
The two axes
The idea the whole product rests on.
It is tempting to classify an artefact once: infected, exposed, historical, irreversible. That is wrong. A sent customer email is infected and irreversible. A 2024 as-built document is infected and historical. They are two independent questions.
Infection status
Does this artefact carry the stale fact?
infected β contains the stale value literally
exposed β depends on it without naming it
immune β checked, clean
Repair disposition
What are we permitted to do about it?
editable β safe to modify in place
historical β preserve, annotate only
irreversible β already delivered
Status decides whether a node lights up on the map. Disposition decides which repair interface is generated. That is what makes βthe interface is generated around the remediationβ mechanical rather than hand-waved.
Five repair surfaces
Generated from artefact kind Γ disposition. Not one modal with different text.
| Surface | Generated when | What it offers |
|---|---|---|
| Document diff | Editable prose containing the stale value | Before/after diff Β· accept Β· rewrite Β· mark exception |
| Field change | A structured record field (CRM) | Current β verified value Β· source Β· connected deals |
| Dependency decision | Exposed artefact whose downstream work may break | Impact statement Β· create review Β· assign Β· set urgency |
| Corrective message | Already delivered to someone outside the edit boundary | Refuses to edit. Drafts a correction instead |
| Preservation notice | Accurate when written; a record of what happened | Refuses to edit. Appends an annotation |
How it works
Announcement β verification β impact β decision β action β audit.
@patch with the correction in Slack, or edits a document directly in the workspace and PATCH notices.live, cached or unverified. A contradicting source is shown, never hidden. No relevant source means βinternally confirmed onlyβ.Six agents
Each one a typed function with its own prompt, model and output schema.
Every model call is routed through a single gateway with per-agent model selection, so cheap fast models handle extraction and stronger models handle judgement. The model that actually ran is recorded in the trace and shown in the interface.
Two ways a change arrives
Truth changes where work happens, so PATCH listens in both places.
From chat
// in your project channel
@patch Supplier update: lead time is now 22 weeks, not 14 weeks
Naming both values matters β the previous one is what the search looks for.
From the workspace
Edit a document, sheet or wiki page directly and PATCH notices the change, interprets it, and announces it where the work happened. It offers the change for nomination; it does not act on it.
@patch changes // pending workspace detections
Roles and permissions
Everyone sees. Only the people you name act.
Being in a channel should not be enough to start a workspace-wide search or cause a write. Viewing is deliberately open β the audit trail is only useful if the team can read it.
| Action | viewer | operator | admin |
|---|---|---|---|
| See every card and result | β | β | β |
| Nominate a truth change | β | β | β |
| Confirm and run the pipeline | β | β | β |
| Approve repairs | β | β | β |
| Change model routing | β | β | β |
// patch.config.json
{
"roles": {
"admin": { "members": ["U0123ABCD", "lead@company.com"] },
"operator": { "members": ["U0456EFGH"] }
}
}
Members match on user id, email or display name. A missing or unreadable config
fails closed β nobody can act. Run @patch whoami to see your role
and the id to add.
Get started
Clone, install, seed, run.
git clone https://github.com/thanmai670/PATCH.git
cd PATCH
npm install
cp .env.example .env.local # fill in your keys
Run it
npm run seed # populate the workspace
npm run dev # the repair interface, on :3000
npm run listener # the chat agent
Verify it
npm run typecheck # types
npm run test:repair # every scenario repairs without damaging a document
npm run seed:reset # restore a clean workspace
Configuration
| File | Controls |
|---|---|
patch.config.json | Roles and per-action permissions |
src/lib/models.ts | Default model per agent |
.patch-models.json | Runtime model overrides, written from chat |
scripts/seed/company.ts | Workspace content and scenarios |
src/contract/schema.ts | The shapes agents emit and the interface renders |