🩹 PATCH

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.

PATCH never starts on its own, and never writes without approval. A human nominates a change, and a human approves every repair. Without those two gates this is an agent that rewrites your CRM because someone fixed a typo.

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.

SurfaceGenerated whenWhat 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
Two of the five refuse to apply the change. That refusal is the product, not a limitation β€” blindly replacing every occurrence would falsify an installation record and silently rewrite history.

How it works

Announcement β†’ verification β†’ impact β†’ decision β†’ action β†’ audit.

1
A truth change is nominated
Someone mentions @patch with the correction in Slack, or edits a document directly in the workspace and PATCH notices.
2
PATCH asks before it acts
A card shows the subject, previous value, new value and confidence, with Confirm, Edit interpretation and Not a factual change. Nothing has been searched yet.
3
Evidence is retrieved, not assumed
External sources are checked and labelled live, cached or unverified. A contradicting source is shown, never hidden. No relevant source means β€œinternally confirmed only”.
4
The spread is traced
Documents, sheets, wiki pages, tasks, CRM records and mail are searched β€” including a direct scan of CRM custom fields, which full-text search does not index.
5
Each artefact is classified and given an interface
Both axes, independently. Then a repair surface is generated per artefact, with the mapping from disposition enforced rather than suggested.
6
A human approves; PATCH executes
Safe repairs can be approved as a batch; risky ones are handled one at a time. Writes land in the real workspace and an audit record returns to the thread where it started.

Six agents

Each one a typed function with its own prompt, model and output schema.

interpreter
Reads the nominated message and extracts a truth change, or declines when it is not a durable fact change.
evidence
Retrieves external sources and judges each as supporting or contradicting. Strict about relevance β€” an unrelated source with the same number is worse than none.
tracer
Mechanical retrieval, no model. Literal search, a subject pass for dependencies, and a direct CRM field scan.
classifier
The agent that carries the product. Emits both axes per artefact, and decides what must not be edited.
planner
Chooses the repair surface and its props. The disposition mapping is enforced in code, not left to the model.
executor
Applies the approved plan. Refuses in-place edits to historical and irreversible artefacts even if asked.

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
An edit with no number, unit, standard or reference is prose, not a fact change, and never reaches the interpreter. The watcher stays quiet rather than chatty.

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.

Actionvieweroperatoradmin
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
The repair interface renders from a committed fixture by default, so it works with no API keys and no network. That is deliberate: it is also the fallback if the live pipeline is unavailable.

Configuration

FileControls
patch.config.jsonRoles and per-action permissions
src/lib/models.tsDefault model per agent
.patch-models.jsonRuntime model overrides, written from chat
scripts/seed/company.tsWorkspace content and scenarios
src/contract/schema.tsThe shapes agents emit and the interface renders