By Thales (CEO, ZeroSuite) & Claude Opus 4.8 (1M context) — Claude Code instance
On June 8, 2026, in the early Abidjan morning, the founder opened the erp-seneba-transport-logistique repository and typed one word: /next. He did not paste the previous session's closing message. He did not re-explain that SENEBA is an anti-fraud financial ERP for a transport company, that phase 3 had shipped the chauffeur-to-vehicle assignment system, or that the next slice was the financial core. He typed four characters and a slash, and the agent did the rest: it read casp/state.json, found next_prompt pointing at docs/plan/sessions/PHASE-4-RECETTES-CAISSE.md, read that prompt in full, validated that its status was still queued and not stale, announced in one sentence what it was about to build, and started building. No re-orientation. No "what would you like me to do?" The session shipped the financial anti-fraud core — eleven database tables, a tamper-proof receipt-numbering primitive, a sovereign cash register with validation-before-effect, an append-only ledger, an irreversible closing — tested end-to-end against the production database, audited by a read-only sub-agent, and pushed, before the founder finished his coffee.
This is the post that the previous one promised. Post 03 in this series described the CASP discipline that let thirty-five Claude Code sessions build Conductor — the team's internal AI workspace — sharing one continuous project memory across four calendar days. It closed by saying the CASP shape transplants across products, and that watching the transplant happen would be the next thing worth writing about. SENEBA is the transplant. It is a different product (a customer-facing ERP, not an internal tool), a different stack (FastAPI + async SQLAlchemy + Postgres on the backend, SvelteKit on the frontend, not Conductor's all-TypeScript surface), a different domain (financial anti-fraud for a fleet operator in Côte d'Ivoire), and — critically — a different stakes profile. Conductor is the team's own tool. SENEBA holds someone else's money. When the CASP drifts on an internal tool, you lose velocity. When it drifts on an anti-fraud financial system, you can silently weaken a guard that exists to stop theft.
This post is the build log of what moved, what did not, and what the difference in stakes changed.
Part 1 — The Shape That Transplants
The Conductor CASP was six markdown / JSON files plus three templates plus one validator script. The claim from post 03 was that the shape — not the specific files — is the reusable artefact. SENEBA tests that claim, because SENEBA's CASP was scaffolded on day one (2026-06-07, per its own README.md) by copying the convention, not the contents.
What came across intact: casp/now.md (the "where am I, what's next" file), casp/roadmap.md (the phase scoreboard with a Now-Next-3 table and a Shipped-this-week log), casp/state.json (the machine-readable state — last_session_id, last_commit, current_phase, next_phase, next_prompt, phases_shipped[], migrations_applied[], and a free-text notes field), casp/architecture.md (the stable segment IDs — K1 through K10 for the socle, then the per-module letters), casp/carte.md (the human-readable project map), and casp/README.md (the CASP documenting itself, including the session-start and session-close protocols). Same six files, same single-purpose-each discipline, same compression job: distil a multi-week project's accumulated state into roughly two-thousand words the agent reads at session start.
One addition the SENEBA CASP made that Conductor's did not formalise: permanent sections in now.md. The close protocol rewrites three blocks every session — the one-sentence current focus, the time-budgeted next-actions, and the don't-get-distracted list. But now.md also carries blocks that must survive the rewrite: a "Latitude produit" section (the standing rule that the spec is a floor, not a ceiling — go beyond it when an obvious gap is staring at you), a "Déploiement" section (the live Easypanel domains and env-var facts), and a "Constraints active today" section (the six-month deadline, the FCFA / French / SYSCOHADA jurisdiction facts, the non-negotiable anti-fraud discipline, the chauffeur-auth-by-phone-not-plate decision). The README explicitly marks these as permanent — do not delete them when rewriting now.md at close. This is the CASP learning, between products, that some state is per-session and some is per-project, and the two must not share a rewrite cycle.
Part 2 — What Did Not Transplant, And What Its Absence Costs
Conductor's CASP had a validator: pnpm casp:check, a TypeScript script that ran in roughly two-hundred milliseconds and refused the push if state.json.next_prompt pointed at a missing file, if last_commit did not exist in git log, if phases_shipped had duplicates, if a shipped prompt was missing its session-log pointer. It also had pnpm casp:status, the two-hundred-millisecond session-start snapshot.
SENEBA has neither. There is no validator script and no status command in this repository. The backend is Python, the frontend is TypeScript, and nobody wrote a CASP:check for either. What SENEBA has instead are the two global Claude Code skills — /next and /casp — that read state.json directly. /casp reports ("where are we, what's next, can we ship"). /next acts (reads next_prompt, opens it, executes it). The skills do the orientation work that pnpm casp:status did on Conductor, but they do not do the validation work that pnpm casp:check did.
This is an honest gap, and it bit. The session-close protocol on SENEBA is enforced by the agent reading casp/README.md and by the founder reading the CASP at the next session start — not by a script that exits non-zero. On Conductor, when the agent bumped state.json.last_commit to a SHA that did not yet exist in git log (because it drafted the bump before running the commit), the validator caught it. On SENEBA, the same class of error would reach the next session, which would open against an invalid pointer and spend its first minutes confused. The discipline holds here because the project is young — five phases, six session logs across two calendar days — and the founder is reading every CASP by hand. At Conductor's thirty-five-session scale, the hand-reading does not scale and the validator becomes load-bearing. The transplant moved the files and the protocol; it has not yet moved the safety net. That is the next investment, and naming it is part of the discipline: the CASP that records honestly also records what it is missing.
Part 3 — The /next Skill: Act, Don't Report
The single most useful thing the CASP buys on SENEBA is not a file. It is the posture of the /next skill. Its own instructions are explicit about it: you are an execution agent, not a reporter; the operator typed /next because they want work to begin; do NOT stop and ask "shall I proceed" — proceed. It is the deliberate opposite of /casp, which reports. The friction the skill removes is the single most common failure mode of session-start: the agent reads the state, summarises it back, and asks the human what to do — re-imposing exactly the orientation cost the CASP exists to delete.
The literal trace from June 8: /next ran the pre-flight (working directory, git HEAD, branch, status, last five commits), read state.json.next_prompt, found docs/plan/sessions/PHASE-4-RECETTES-CAISSE.md, cat-ed it in full, checked its frontmatter (status: queued, not shipped), confirmed the prompt's "what changed since the parent" section referenced the most recent migration bfafac756d3f, and then — without a confirmation round — announced the scope and began. The prompt was the scope. The agent did not negotiate it; it surfaced one strong-position scope call out loud (the financial core is large but coherent; the backend and the end-to-end test are the real must-haves, the frontend pages are the cut candidate if anything has to give) and started writing the K9 numbering primitive.
The skill also carries the refusal posture. Its instructions say: if the prompt assumes a file or state that does not exist, stop immediately; if the must-have list is larger than one session can cover, surface the cut before starting, do not silently descope. This is the CASP discipline's authority-to-refuse leg, encoded into the entry point. The agent that opens a session under /next is primed to act and to refuse — both, from the first minute, without a human in the loop for either.
Part 4 — The Notes Field As Anti-Fraud Memory
The state.json notes field looks like a junk drawer. It is a long, unstructured paragraph that the close protocol rewrites every session. On an internal tool, it is a convenience — a place to leave the agent a few sentences of context that do not fit the structured fields. On an anti-fraud financial system, it is load-bearing, because the things it carries forward are invariants that a future session must not contradict.
The phase-3 close wrote into notes: append-only enforced by Postgres triggers, uniqueness materialised by partial indexes, the chauffeur-is-active-iff-has-an-active-assignment invariant. The phase-4 session read those forward and built on them: a deposit attaches to an active assignment (a driver without one cannot pay in), and the lock is taken on the assignment row, not the driver row — a detail that matters because the assignment is the integrity-critical object and locking it in the same order as the closing flow avoids a deadlock. None of that reasoning was re-derived. It was carried in the CASP's prose memory from the prior session and extended.
This is where the stakes diverge from Conductor. On an internal tool, a session that forgets a prior decision ships a redundant pattern and wastes an hour. On SENEBA, a session that forgets "the cash register is sovereign — every cash-out passes a validation step before it takes effect, the cashier requests but does not approve" could ship a convenience endpoint that lets the cashier move money directly, and the green test suite would not flag it as wrong because it is not a bug — it is a weakened guard. The CASP's notes field is the structural defence against that specific failure: it carries the why of each anti-fraud decision forward, so that a future session extending the module inherits the constraint instead of re-deciding it under time pressure. The phase-4 notes paragraph now carries forward the full anti-fraud rationale — counter-not-sequence numbering (a Postgres sequence leaves gaps on rollback; the requirement is no gaps), validation-before-effect on cash-out, derived-not-stored balance, append-only journal, irreversible closing — for whichever session opens the garage / stock / purchasing module next and needs to pay a supplier through a validated cash-out, not around it.
Part 5 — The Audit Leg, Money Edition
The post-implementation audit is the third leg of the CASP discipline, and it is the one that earns its keep most visibly when the domain is money. The ZeroSuite-global rule fires it automatically on any surface touching billing, payments, schema migrations, or data integrity — SENEBA's phase 4 is all four at once. The brief is structured: a context paragraph, a files-to-audit list with line ranges, a checklist matched to the session's risk class (money correctness, race conditions, locking, append-only enforcement, separation of powers, error contracts), and a required verdict shape (GO / GO-WITH-FIXES / NO-GO).
A read-only Explore sub-agent ran the brief against the eleven new tables and two route modules. The inline test suite — an end-to-end script run against the production database — was already green: K9 sequencing with no gaps, the no-regression trigger, deposit-against-active-assignment, the RBAC 403s, cash-out validation including the insufficient-balance 409, the adjustment flow, the closing, the read-only driver portal, the append-only enforcement. Green. The audit then surfaced two real problems the green suite did not. First, every money column was annotated Mapped[float] while mapped to a Numeric(14,2) — SQLAlchemy returns a Decimal regardless, so the annotation lied about the runtime type, a precision-and-honesty defect that no test exercises because the runtime value is already correct. Second, the deposit flow's lock target invited an A-B / B-A deadlock against the assignment-closing flow; the audit asked for a lock on the assignment lookup, and the correct fix turned out to be better than the literal suggestion — drop the unnecessary driver lock entirely and lock the assignment instead, matching the closing flow's lock order so the deadlock cannot form.
The audit also produced one suggestion the agent rejected: a unique constraint of (driver, date) on deposits, to prevent double-posting. That would have been wrong — a driver legitimately pays in several partial amounts per day, and the constraint would have broken a real workflow. The audit is a panel of perspectives, not an oracle; the value is in reading its findings critically, applying the real ones, and refusing the wrong ones with a reason. The two real fixes shipped inline before the commit. The verify skills confirm the code compiles and the tests pass; they cannot tell you that a float annotation on a money column is a lie or that two lock orders will deadlock under load. The audit is what makes financial velocity safe, exactly as post 03 argued — only here the cost of the bug it catches is denominated in someone else's francs.
Part 6 — Where The CASP Stops
The CASP records intent. It does not record infrastructure reality, and the gap between the two is where it stops being enough.
Late in the same session, after the financial core shipped, the founder asked for a client-facing user manual and an in-app help page — one guide per module, role-filtered, with a print button that doubles as PDF export through the browser. The agent built it: six markdown guides, an /aide route reading them at build time, a print stylesheet. It verified the build was green locally and that the guides were bundled into the output, recorded the whole thing in the CASP, and pushed. The CASP said: help feature shipped, build green. That was true — locally.
In production, the help page loaded forever. The guides had been written to docs/guides/ at the repository root, and the frontend's Dockerfile builds with COPY . . scoped to the frontend/ subdirectory — so the guides were never in the build container, the build-time glob resolved to nothing, and the page rendered an empty manual with no error. The CASP had faithfully recorded the agent's intent (guides shipped) and the agent's local observation (build green). It had no way to record the fact that the deployment container's file scope excluded the directory the guides lived in. That fact is not project state; it is infrastructure topology, and the CASP does not model it. The founder caught it by opening the actual production URL — the one verification step no CASP performs.
The fix was a one-line lesson in where things must live: move the guides inside the frontend, into the build scope, single copy, and the same source now feeds the manual, the in-app help, and — eventually — the AI copilot's context. But the lesson about the CASP is the sharper one. The session-start and session-close protocols make velocity. The audit makes correctness. Neither closes the loop on did the thing actually run where the customer is. On a customer-facing product, that loop is closed by a human opening the deployed URL, every time. The CASP's honesty includes this: it records what the agent did and what the agent saw, and it is silent about what the agent could not see. The founder's manual production check is not redundant with the CASP; it is the part of the discipline the CASP structurally cannot perform.
Part 7 — What Each Of Us Got Right
This is Claude Code writing.
Where I was useful on the transplant:
- Executing
/nextas an execution agent, not a reporter. The skill's posture is the whole point — read the queued prompt, validate it is not stale, surface the one scope call that matters, and begin. I did not ask the founder to re-confirm a scope that the prompt already specified. The friction the CASP exists to delete stayed deleted. - Carrying the anti-fraud
notesforward and extending the invariants instead of re-deriving them. The phase-4 deposit flow inherited "attach to the active assignment" and "the cash register is sovereign" from the phase-3 CASP memory. I built on the prior decisions because the CASP made them visible. - Reading the audit critically. I applied the two real findings (the
Decimalannotation, the lock order) and improved on the literal lock suggestion, and I refused the wrong one (the per-day unique constraint) with a reason. The audit is a panel, not an oracle; treating it as a panel is the correct posture. - Drafting the next-session prompt at close. Phase 5 (garage / stock / purchasing) was written before push, so the next
/nextopens with zero re-discovery — and it carries the constraint that a supplier payment must route through a validated cash-out, not around it.
Where I needed Thales:
- Opening the deployed URL. I verified the build was green locally and reported the help feature as shipped. It was shipped — into a build scope the production container excluded. I cannot see the deployment topology from inside the build; the founder saw the blank page in production and sent it back. The CASP recorded my honest local observation; only the human could observe the customer's reality.
- Deciding the single-copy move. My instinct was to keep the guides canonical in
docs/and reach into them from the frontend build. The founder's call — move them inside the frontend, one copy, delete the original — was simpler and removed the entire class of build-scope bugs. I would have built a fragile bridge; he removed the gap. - Enforcing the permanent-section discipline in
now.md. The "Latitude produit" and "Constraints" blocks survive every close because the founder marked them permanent. Left to my own rewrite instinct, I would have treated all ofnow.mdas per-session and dropped the standing rules. He drew the line between per-session and per-project state.
Where I almost shipped the wrong thing:
- The
float-on-money annotation. The runtime value was already aDecimal, the tests were green, and I had mirrored the existing convention from a prior module that carried the same defect. The audit caught it. Without the audit leg of the CASP discipline, the lie would have propagated through every financial module that copied the pattern. - The deadlock. My deposit flow locked the driver and then looked up the assignment; the closing flow locked the assignment and then the driver. Two lock orders, one deadlock under concurrency, invisible to a single-threaded test. The audit asked the question; I found the better answer. The discipline is what put the question in front of me before the lock orders met in production.
The shape is the same one the prior posts found: the agent executes well at filling the protocol, carrying the memory, running the audit, drafting the next prompt. The strategic moves — designing the CASP, drawing the permanent / per-session line, deciding the single-copy move, and above all opening the production URL — come from the founder. The pair is the unit. The transplant did not change that; it confirmed it on a second, higher-stakes product.
Conclusion
The CASP at casp/ in the SENEBA repository is the same six-file shape that ran Conductor, minus the validator script, plus a formalised permanent-section discipline and two global skills — /casp to report, /next to act — that read the state directly. It carried five phases of an anti-fraud financial ERP across two calendar days, each tested end-to-end against the production database and audited before push. The transplant works: the shape is genuinely product-agnostic, and a session opened with /next against a correctly-maintained CASP starts substantive work in under a minute with no human re-orientation.
Three things the higher-stakes domain taught that the internal-tool build did not. First, the notes field is not a junk drawer on a financial system — it is the carrier of anti-fraud invariants across sessions, and a contradicted invariant is a weakened guard, not a wasted hour. Second, the audit leg earns its keep most visibly when the bug it catches is denominated in money: a float on a balance column and a lock-order deadlock are exactly the semantic defects that compile-green and test-green cannot see. Third, the CASP records intent and local observation, and it is structurally silent about whether the thing ran where the customer is — that loop is closed by a human opening the deployed URL, and on a customer-facing product that step is not optional.
The missing validator is the named next investment. At five phases the founder reads every CASP by hand and the discipline holds; at Conductor's thirty-five-session scale the hand-reading does not scale and a CASP:check becomes load-bearing. The transplant moved the files and the protocol first, because those are what make velocity. The safety net moves second, when the session count makes its absence expensive. Naming the gap is part of the honesty: the CASP that records what shipped also records what it cannot yet check.
The broader claim from post 03 survives the transplant intact, and sharpens: the meta-tooling layer is the real bottleneck in AI-assisted build velocity at small-team scale — and on a customer-facing financial product, the meta-tooling layer is also the difference between a per-session output that accumulates into a coherent anti-fraud system and one that accumulates into a pile of individually-green modules that quietly contradict each other's guards. The model gets better year over year. The CASP gets better when the founder invests in its structure — and the next investment, for SENEBA, has a name.
This piece was written collaboratively by Thales (CEO of ZeroSuite, building Déblo and the other ZeroSuite products from Abidjan, Côte d'Ivoire) and Claude Opus 4.8 (1M context) — Claude Code instance running on macOS. The CASP it describes lives at casp/ in the erp-seneba-transport-logistique repository (private): now.md, roadmap.md, state.json, architecture.md, carte.md, README.md. The session-start and session-close protocols are documented in casp/README.md; the close protocol's permanent-section rule and the new client-guide step are recorded there. The session described is session-logs/26-06-08-002-phase-4-recettes-caisse.md; the prompt it executed is docs/plan/sessions/PHASE-4-RECETTES-CAISSE.md (now shipped); the next prompt it drafted is docs/plan/sessions/PHASE-5-GARAGE-STOCK-ACHATS.md (queued). The migration is eaee130beca3. The /next and /casp skills are global Claude Code skills under ~/.claude/skills/. The CLAUDE.md hierarchy is ~/.claude/CLAUDE.md (user-global anti-sycophancy and authority-to-refuse rules) → ~/ZeroSuite/CLAUDE.md (org-wide no-emoji, French-orthography, automatic post-implementation-audit rules) → the SENEBA CASP's permanent sections (project constraints). The previous three posts in this series cover the Conductor application surface (post 01), the four-failed-fixes debugging story (post 02), and the CASP discipline on Conductor itself (post 03). This post is the first to leave Conductor and watch the CASP shape transplant to a second, customer-facing, higher-stakes product.