Selective recovery · Deterministic authority

The model understands. The deterministic protocol authorizes.

When a missed delivery breaks promises already made, PromisePatch changes only what it is allowed to change: a swap the customer already agreed to, or one they approve now. The rest goes to the owner, and every order the failure does not reach is left untouched.

In the live app, press Look around a real case: read-only, no account.

6 promises → 1 auto-recovered · 1 customer-approved · 2 owner-escalated · 2 untouched.

02 · The problem

A made-to-order bakery accepts promises against supply it expects to receive. Then, one morning, the raspberries do not arrive.

Replanning the inventory is the easy part. Changing promises people already relied on is the hard part.

A frontline worker has to answer four questions in the middle of a shift. A language model can help understand what they said, but it must never be the thing that decides.

  1. AUTOWhich may change under a substitution the customer already agreed to?
  2. ASKWhich need the customer to say yes?
  3. BLOCKEDWhich must go to the owner, because no permitted recovery exists?
  4. UNAFFECTEDWhich must not be touched at all?

03 · Six promises, four lanes

One missing delivery. Six accepted orders. Each gets exactly one answer.

Step through the canonical case as it ran on the deployment. The worker clarifies “just raspberries — the strawberries came.” Select an order to see why it landed where it did and who was allowed to decide.

7 SettledRESOLVED · the order system’s own store holds both amendments.

  • Order Aacceptedhas raspberry● AUTO✓ amended v1→v2✓ recovered✓ recovered✓ RECOVERED
  • Order Bacceptedhas raspberry◆ ASK◆ 1 message sent◆ YES◆ 10/10 PROCEED✓ RECOVERED
  • Order Cacceptedhas raspberry■ BLOCKED■ owner · held■ owner · held■ owner · held■ ESCALATED
  • Order Dacceptedhas raspberry■ BLOCKED■ owner · held■ owner · held■ owner · held■ ESCALATED
  • Order Eacceptedno raspberry○ UNAFFECTED○ 0 effects○ 0 effects○ 0 effects○ UNTOUCHED
  • Order Facceptedno raspberry○ UNAFFECTED○ 0 effects○ 0 effects○ 0 effects○ UNTOUCHED
● AUTO◆ ASK■ BLOCKED○ UNAFFECTED✓ settled in the order system

04 · Authority, not autonomy

Reading a sentence and being allowed to act on it are different jobs.

Every rule below is enforced in code and tests, not by convention. Import-linter contracts forbid the model boundary, the MCP server and the conversational client from reaching the domain or the database.

UNDERSTANDING

The model

Proposes interpretations only: a reading of a sentence that must ground in the bakery’s own vocabulary. A fact it helps read is recorded as the reporting worker’s, never the model’s.

CANNOT

  • ✕ write a row
  • ✕ record consent
  • ✕ approve a plan
  • ✕ choose a recovery

The canonical raspberry report costs zero model calls, and a test asserts it.

AUTHORITY

Deterministic engine

Decides what a failure reaches, which lane each promise is in, and whether an approved change is still true. No I/O, no environment, no clock.

Worker

Attests the physical fact, and approves the plan that was read out, in a signed-in browser session or on the operator console. The approval is bound to that plan’s identity.

Customer

Authorizes an ASK change with a literal YES or NO, trimmed and case-insensitive. Any other reply decides nothing.

Order system

Stays the system of record. Changes arrive as governed amendments, only after revalidation.

  • A service credential is not a person.MCP intake is a trusted reporting channel: its reports are recorded under the server’s configured worker. An MCP confirm can only spend an approval a person already wrote.
  • Two approvals, never interchangeable.A customer’s yes never spends a worker approval, and the reverse is also true.
  • Nothing is invented at runtime.Recovery only selects pre-authored recipe versions.
  • Uncertainty fails closed.Unknown or conflicting state goes to BLOCKED, never to UNAFFECTED.

05 · The revalidation moment

A yes is perishable.

Approval is not a permanent permission token. When a customer’s YES arrives, PromisePatch takes a fresh snapshot and runs ten checks before the change may be committed. A change that is no longer true is refused as STALE, nothing is sent, and that track is re-planned; an expired answer goes to the owner and an unauthorized one is refused. The ten checks guard the commit. After it, only the production start is judged again, at the amendment’s first dispatch. On the current release, one live run showed it: a customer’s yes about one cake at order v1 was refused as STALE at check 2 once a deliberate edit in the simulated order system made it two cakes at v2, and no amendment reached that order. Live revalidation proof

  1. 20:27:10One Telegram message delivered
  2. 20:27:23Worker stopped on purpose
  3. 20:28:31The owner, as the demo customer, presses APPROVE. Stored; nothing acts on it.
  4. 20:30:58Worker starts again, 3 min 35 s after it stopped
  5. 20:31:01Stored answer taken up, 2 min 29 s after the press. Fresh snapshot. Ten checks.
  6. 20:31:03EXT-B amended once. Case resolved.

Deployed rehearsal R3

AUDIT 503–512 · SNAPSHOT 20:31:01.207Z
  1. Waiting. The track and case are waiting. Passed.WAITING
  2. Order. Order state and version unchanged. Passed.ACCEPTED @ v1
  3. Pinned version. Pinned recipe version unchanged. Passed.rv-raspberry-rose-2
  4. Constraints. Constraint snapshot unchanged. Passed.ee9962aa… = ee9962aa…
  5. Substitute. The substitute is still available. Passed.3.200 ≥ 2.200
  6. Production task. Not started; its start is ahead. Passed.SCHEDULED
  7. Deadline. Approval deadline not passed, judged at processing time. Passed.24 Sep 20:31:01Z ≤ 25 Sep 01:26:54Z
  8. Sender. The sender is the order’s approval channel. Passed.masked
  9. Parser. The decision came from the literal parser. Passed.LITERAL
  10. Decision. One unspent decision, bound to this plan. Passed.1 decision

OUTCOME

PROCEED

EXT-B amended once, v1 → v2, under HUMAN_APPROVAL. Case RESOLVED at 20:31:03Z.

Values as pp case-status printed them in rehearsal R3 of the G8 freeze, on the earlier deployment 4529a802e34e (historical). R3 passed again on the current release, 740a062838e0.

Read the R3 record →

06 · Measured evidence

6 promises → 1 auto-recovered · 1 customer-approved · 2 owner-escalated · 2 untouched

0/2

untouched orders received an incident-caused effect, in each of five deployed restart rehearsals, while the four threatened orders were recovered or escalated.

Per rehearsal: 2 amendments · 1 customer message · 2 task holds · 3 outbox rows, all delivered on attempt 1.

Caveat. One fixture measured five times. It shows the demo repeats, not a reliability rate. Demo funnel

5/5 REHEARSALS ON 740a062838e0
runworker restarteduntouchedverdict
R1waiting for consent0/2✓ PASS
R2across the plan confirmation0/2✓ PASS
R3across the customer’s answer0/2✓ PASS
R4after the case resolved0/2✓ PASS
R5waiting for consent, again0/2✓ PASS

EFFECT SETS · TWO DOCUMENTS, TWO RESULTS

11/16PERMANENT HEADLINE

The first scored run of sixteen frozen scenarios against the v1 manifest, hand-labelled before the runner existed. Five failed. The result is never replaced.

First scored run →
16/16SEPARATE RELEASE CONDITION

Run once against v2, a separately versioned label correction in which one label moved: S12’s hold, because started kitchen work is never held. Taken once on the current release, 740a062.

v2 release condition →

The original benchmark did not become 16/16. The other four v1 failures were implementation defects, fixed under published SHAs. Both manifests are developer-authored, finite and public, not an independent benchmark. The effect-set CI workflow stays red on purpose, because it judges v1.

VOICE

9/10

voice turns in which a truthful spoken response began within four seconds of speech ending. It met the predeclared threshold of K ≥ 9 exactly.

Caveat. This is a second run. Run 1 (1/10) was voided after its intervals had been computed, which the protocol forbids; a strict reader may treat run 2 as a best-of-two. Local stack, browser speech APIs, no public-internet round trip. Not a latency SLA.

Voice measurement, both runs →

RELEASE CI

13/13

jobs green on the exact release SHA 740a062, the whole-stack browser job among them.

pr run 36925136266 →

07 · Architecture

The model proposes a reading. It does not own authority.

authority lives here understanding only outside the boundary

Customer consent

One outbound Telegram message. The customer answers YES or NO on a signed web link. That answer is revalidated by the engine against a fresh snapshot before the amendment is committed.

session: one of two plan-approval channelsbearerservice tokenthe wordscandidate reading, never authorityreach · partition· revalidateamendmentsigned events1 messageYES / NOanswer → revalidateBakery workervoice or textAlexa+-style agentany MCP clientMCP serverStreamable HTTP2025-11-25 · no DBIntent APIactor + clock areserver-derivedSemantic boundaryAmazon Bedrockproposes a readingDurable workflowstate machine + ledgerPostgreSQLpromise_graphdeterministic engineno I/O · no clockOrder systemsystem of recordTelegramoutbound onlyCustomerSigned web linkliteral YES or NO
  1. Worker / agent clientOUTSIDE
    ↓ MCP bearer token, or a signed-in session
  2. MCP serverOUTSIDE
    ↓ Streamable HTTP · 2025-11-25 · no DB access
  3. Intent APIAUTHORITY
    ↓ actor and clock are server-derived
  4. Semantic boundaryUNDERSTANDING
    ↓ proposes a reading, never authority
  5. promise_graph engineAUTHORITY
    ↓ reach · partition · revalidate
  6. Durable workflow · PostgreSQLAUTHORITY
    ↓ governed amendment, after revalidation
  7. External order systemOUTSIDE
    ↓ system of record · signed events back
  8. Telegram, outboundOUTSIDE
    ↓ one message
  9. Signed approval linkOUTSIDE
    ↓ literal YES or NO
  10. Fresh revalidationAUTHORITY
    ↓ ten checks against a fresh snapshot
  11. Governed effectAUTHORITY

PromisePatch exposes five intent tools (report, clarify, confirm, withdraw, status) over MCP protocol revision 2025-11-25. This is not a native Alexa+ integration. The Alexa+-style experience is simulated: a panel in the app drives a case-scoped MCP client on the server, which calls the real, authenticated endpoint. Live on 740a062838e0, a typed “Yes, go ahead.” became a Bedrock CONFIRM and a real MCP confirm that spent the worker’s earlier browser approval and created none. Live MCP confirm proof · MCP transport proof

08 · Running on AWS

Not a mockup. A frozen deployment you can open.

It serves the case workspace, the API, the event stream and the MCP endpoint. Telegram outbound is live: one message was delivered per rehearsal, and customers answer through the signed web link.

COMPUTE
One EC2 t4g.small in us-east-1, behind Caddy with a Let’s Encrypt certificate. IMDSv2 required.
DATABASE
Private, encrypted RDS PostgreSQL.
MODEL
Amazon Bedrock, Nova 2 Lite, called by the instance role. No AWS key is held anywhere.
FREEZE
Declared 2026-10-02. Any later change to a product path voids it.

DEPLOYED PRODUCT / IMAGE SHA

740a062838e0 Reported by GET /healthz

REPOSITORY RELEASE SHA

740a062838e0ea2620499abed27d653c42fc05f7

The image tag is the release commit’s first twelve characters; repository HEAD may carry documentation-only commits on top. Earlier releases are historical: 283f63f2845f, and the G8 freeze 56c3023 / 4529a802e34e. Bridge release · G8 closeout · Customer channel

09 · Proof

Don’t trust the pitch. Inspect the proof.

Every claim links to its committed record. Failed runs, voided runs and the repository’s own overclaims are published beside the passes. Claims audit

What the numbers do not say

  • One bakery, fixture data, a simulated order system. The Telegram message and the web approval are the real parts.
  • The Alexa+ experience is simulated by an MCP client on the server; no native Alexa+ skill exists. The live MCP confirm proof is one run of the success path.
  • One refusal kind has been exercised live, once. STALE, through check 2, on 740a062838e0. The other checks refusing, EXPIRED, UNAUTHORIZED, NOOP and the commit-time freshness gate are proved by tests only.
  • Telegram inbound is deliberately not built. The signed link proves possession of the message, not identity.
  • Telegram’s Bot API has no idempotency key, so a retry after an uncertain send can deliver a duplicate message. Order amendments carry a stable idempotency key, so a duplicate is a second message, never a second amendment.
  • MCP intake is a trusted reporting channel. A report over MCP is attested as the server’s configured worker, not by a person the server authenticated.
  • The effect sets are developer-authored, and both evaluation holdouts remain sealed.
  • The voice result is not a production latency SLA.
  • Operations debt is recorded, not fixed. See Honest limitations.

When reality changes, permission must be checked again.