Spec · v2 · ★ resolved · census inside

SF writes, graduated

Your ruling, made mechanical: no shadow, no taps — writes execute on the proven rail the moment their class’s validation is green, receipted in-thread and in #neo-receipts. The write universe is now a census with a gate, not a guess. One check left: is the class table the whole universe?

★ resolved per your ruling · class table v2 awaits your completeness check · builds when the bay clears

The story: the write that finishes the job

Alie’s Cement Creek question ends, today, at a human doing the fix: someone must put the Stripe link on the Salesforce account. Neo can find the gap (the sibling reach spec); he cannot close it.

The graduated version, as your ruling shaped it: Neo makes the write — “add this Stripe link to the Cement Creek account” — it executes on the proven rail the moment its class’s validation is green, a receipt lands in the thread and in #neo-receipts, and where the class allows it, an undo rides the receipt. No tap, no waiting on your hands. The loop closes without anyone opening Salesforce.

What exists today (three half-built things, one of them real)

HAVE ITA proven write rail. One chokepoint module owns every Salesforce write: validates, checks for conflicts before updating, executes, verifies after writing, writes a receipt. Deletes are structurally impossible. A kill switch exists. Live today — but the last step, the “drain” that actually executes approved writes, is a script Robert runs by hand.
↘ go deeper
sf-write-rail.ts: chokepoint invariant enforced by structural test (test/sf-write-rail-chokepoint.test.ts, planted rogue fixture MUST flag). Gates G1 single-path, G4 conflict-check, G5 verify-failure ⇒ executed-unverified never a second write, G6 kill switch, G7 dedupe, G8 DELETE structurally absent, G11 marker + paired activity log, G12 hold-for-cancel. LANE-1 = queue-only outbox (:235); LANE-2 = the drain, the ONLY path producing execution-state transitions (:709,:739,:919). Manual runner: scripts/sf-write-drain.ts. Flags ON in prod (verified this session): SF_WRITE_ENABLED, COMMAND_CHANNEL_ENABLED.
DEADA proposal capability that is dead code. The autonomous “Neo notices and proposes a write” module (c8) shipped dark and was never wired in — the runtime never registers it. It cannot run. It never could. Retired by this spec.
↘ go deeper
eve-runtime.ts:794-843 — the capabilityWiring literal sets no c8 key (re-read at HEAD). c8-sf-write-proposals.ts header: “Ships DARK… It NEVER executes. It carries NO executor reference.” Registration absent ⇒ unreachable. Retirement: delete both c8 files; [M] Plato orphan check; chokepoint structural test stays green.
AMNESIAA shadow ledger that forgets. The record of proposed and pending writes resets on restart; the durable version was specced 2026-06-26 and never shipped. Ships with this graduation — a precondition, not an option.
↘ go deeper
eve-jobs-durable-update-map-2026-06-26.md, never shipped. Folded to current store doctrine: bounded, byte budget + loud overflow (the diary-bound lesson), exactly-once via the durable-cursor pattern already in production elsewhere. [M] Restart fixture: stage → simulated DO reset → state intact, no double-execution (G7 asserted across the reset).

What I decided (updated to carry your ruling)

One rail, not two. Everything graduates ONTO the proven rail. c8 is retired, not revived — its “notice and propose” job returns later as a thin producer feeding the SAME rail. Dead code goes away.
The durable ledger ships with graduation. A write system that can’t remember what it wrote across a restart is not trustworthy. The 2026-06-26 durable spec stops being optional — it’s a precondition for “complete.”
No routine confirm taps. Your 2026-07-17 ruling supersedes Call 1’s per-write taps — they were the bottleneck (“writes just aren’t being done”). Every class executes autonomously once its validation is green. I removed the taps everywhere, including money-adjacent writes — mark this chip if you want a tap kept anywhere.
Receipts: the thread + #neo-receipts. Every write, both places, one glanceable line: object · field · old → new · undo. With no taps, the receipt IS your window. No silent writes, ever.

★ THE STARRED CALL — RESOLVED (your ruling, 2026-07-17)

Your words, verbatim: “Honestly, I need it working now. Your job is the validation. So figure out exactly what needs to be validated, make sure it’s trustworthy, and then it goes straight to production. We can’t have the luxury of the shadow because right now writes just aren’t being done because I just don’t have time to do them.”

What that ruling makes true:

The tier is validated-autonomous. Writes fire in production without per-write human approval. The trust is carried by the validation harness — not by your tap.

The shadow era is dead. No proposal-purgatory, no manual drain as the default path. The hand-run drain script survives only as break-glass.

“Straight to production” does not mean “skip validation” — it means validation is the gate, and it’s mine. Each write class ships only when its harness is green: the write courts, the conflict-and-verify gates, the live undo drill, the kill-switch drill. That is the “figure out exactly what needs to be validated” half of your ruling, taken literally.

The safety rail is not weakened — it’s extended. Salesforce writes stay classified irreversible; the new rung’s precondition is a green per-class validation record instead of a recorded human tap. No path reaches the executor without one — and we prove that by deliberately revoking a record and watching the drain refuse.

↘ go deeper — how the new rung lands without weakening the rail
reversibility-ladder.ts:59-71 — IRREVERSIBLE_ACTION_KINDS keeps sf_write; G2’s “never auto-fire via fireReversibleAction” stays literally true. New rung validated_autonomous lands in contract/action.ts + the ladder as a separate, court-gated path whose precondition is a green per-class validation record (durable, versioned artifact). [M] mutation fixture: revoke the class’s record → drain refuses; no path reaches the executor without one. The validation harness per class: (i) write-court [J] with contradicted fixtures (wrong-account write MUST fail; vague receipt MUST fail); (ii) conflict/verify gates [M] with induced conflicts; (iii) live undo drill [M]; (iv) budget + kill-switch fixtures [M]; (v) census-gate coverage [M]. Any leg missing ⇒ class not validated ⇒ cannot fire.

The universe — census, not guesswork (your second note, answered)

You asked: “is this the entire universe of stuff that I would need to do… every single thing… proper investigation and proper schema.” I ran the census against Salesforce itself — your user, last 180 days, field-change history plus record queries. What you actually write:

Accounts (create; status, primary contact, name — plus untracked fields like the Stripe link) · Opportunities (create; stage incl. Closed-Won, products, point of contact, the three pipeline dates) · Contacts (create; email fixes; re-parenting) · Cases (create; ownership routing) · Tasks — the biggest surface: the Closed-Won activation batches (domain, accounting, Call IQ, the Targeted-Ads pre/post-launch sets, blog verification), kickoff and designer-assignment tasks, and the [A-…] agent-staged tasks already flowing through the existing drain today · Leads (create, status, convert — which cascades into account+contact+opportunity) · Projects (onboarding / Spotlight / ads records).

The completeness guarantee is a gate, not this list. Salesforce’s change history only records tracked fields, so any hand census undercounts — the Stripe-link field is exactly the kind it misses. So the build ships a census gate: a programmatic sweep enumerating EVERY object with a Robert-authored write in the trailing 365 days, diffed against the class table — anything uncovered fails the build loudly. The universe stays whole by machine, not by memory.
↘ go deeper — the census receipts
Run 2026-07-17 via DE Brain query_salesforce, Robert = 0052E00000IKOgfQAH, LAST_N_DAYS:180: AccountHistory 99 rows (created, Client_Status__c, Primary_Contact__c, TextName, accountUpdatedByLead) · OpportunityFieldHistory 200/cap (created, StageName, Products__c, Point_of_Contact__c, Appointment_Set/Done_Date__c, POC_Reached_Date__c) · CaseHistory 35 (created, Owner) · ContactHistory 46 (created, Email, Account) · LeadHistory 5 (created, Status, Email, leadConverted) · Task 200/cap (activation batches, kickoffs, [A-…] agent tasks, email auto-logs) · Event 50 (calendar-sync dominant — excluded from Neo’s write scope v1) · Project__c 8.

The class table v2 (rebuilt from the census; ships as typed code the gates read)

Write classCensus evidence (you, 180d)BehaviorUndo
task-opsactivation batches, kickoffs, [A-…] agent tasks (volume cap hit)autonomous + receiptstatus-cancel (delete stays blocked)
record-createaccounts, contacts, opportunities, cases, leads, projects createdautonomous + receiptmark-inactive/close per object
record-fieldaccount status/contact/name + untracked (Stripe link); contact email + re-parent; case routing; project fieldsautonomous + receiptwrite back old value
pipeline-fieldopportunity stage (incl. Closed-Won), products, POC, pipeline datesautonomous + receiptwrite back old value
lead-convertone conversion (cascades acct+contact+opp)autonomous + receipt; v1 may stage-with-offernone — flagged class
neverDELETE (structurally absent), owner transfer off-team, financial/billing amount fields: refused by construction

Every class autonomous per your ruling — no tap column anymore. The census gate diffs this table against the live 365-day universe on every build.

↘ go deeper — receipts wiring, the drain’s graduation
Receipts: new secret EVE_RECEIPTS_CHANNEL; receipt = object, field, old→new, actor, undo token/window or “no undo (class)”. Undo rides the receipt as a typed in-thread reply (“undo <id>”) on the command-channel pattern — no new ingress; the /slack/interactive endpoint leaves the critical path (deferred). An UNDONE write or census-gate failure posts to #neo-receipts at alert level. Drain: worker-side consumer executing rail-admitted actions whose class validation record is GREEN; manual script break-glass only; per-cycle write budget [M]; kill switch honored at consumer entry (fixture: switch ON ⇒ zero transitions). Verdicts: bay-pair (codex+opus) on the rung change, drain consumer, validation-record store, census gate.

What could go wrong

A wrong write — no human in front of it

The risk your ruling consciously accepts, answered in layers: conflict check before every update, verify-after-write, per-class write courts, undo on the receipt, kill switch one command away — and the worst case visible in #neo-receipts in seconds, never silent.

A write flood

Kill switch (exists), dedupe via the execution log (exists), plus a per-cycle write budget this spec adds.

Amnesia

The current real gap. The durable ledger is the fix AND a gate: no graduation while the ledger forgets.

Receipt blindness

With no taps, receipts are the human window. Mitigation: glanceable one-liners, a dedicated #neo-receipts channel, and any UNDONE write auto-surfaces to you rather than burying itself.

A misclassified write kind

The class table is now a safety artifact. The census gate plus the never-list keep a new kind from silently inheriting autonomy.

How we’ll know it works: the Cement-Creek write fixture goes green live — staged from a thread, executed autonomously on the rail, receipted in-thread + #neo-receipts, and undone once as a drill. The restart-amnesia fixture passes. The kill switch is pulled once, live, and everything stops. The census gate runs green against the trailing-365-day universe. Only then does each class’s record stay green. Rollback: SF_WRITE_ENABLED to “0” kills the rail; per-class revocation stops one class instantly, no deploy.

Reference strip — the rail + gates · the resolved rung · census + gate · class table + drain · failure modes. Full build sequence (architectural: safety-rail change); load-bearing verdicts run as the codex+opus pair. Builds start only after the engine bay is cleared. Canonical source: docs/ai/design/sf-write-graduation-2026-07-17.md.