Applied AI
Part 6 — Put Intelligence Into the Process
One paragraph, one process
A disposable file holds one line:
draft: models are stochastic, so review is hard [S1].
The frozen criteria for the task are narrow on purpose: the [S1] marker must be gone, and the sentence Models supply cognition. must be present. The “reviewer” is a fake model adapter that returns one canned revision. That is deliberate. This chapter is not testing whether a model can review a paragraph. Chapters 23 through 28 spent their evidence on what models and model policies do. This one tests whether everything around the model holds together when the pieces are joined.
By the end of the run, one authorized edit has happened exactly once, a check has examined the exact bytes the edit produced, a person-labeled acceptor has accepted them, and a repeated request has been answered from the record without touching the file. Six other branches stop: an edit under the wrong grant, a check aimed at a stale state, a key reused for a different instruction, a verifier that crashes, an effect whose outcome is unknown, and a proposal that fails its check. An independent reader, given only the ledger file and the preserved bytes, reconstructs all of it.
That is the book’s thesis in operational form. The model is not the process. It is one selectively invoked component inside an inspectable process — one that records why it acted, what it was allowed to do, what actually happened, what was checked, and what remains uncertain.
Can one task move from directive through authorized effect, observation, bound verification, and acceptance while leaving enough durable evidence for an independent reader to reconstruct what happened — and which joints between the mechanisms does the runtime actually enforce?
Why composition is its own test
Every mechanism in this book was tested in isolation, against a fixture built for that chapter. Isolation proves a component honors its own contract. Whether one component’s output matches the input the next one assumes remains untested.
Integration failures live exactly there. The action records a state hash; the check must bind to that hash, not to a fresh reading of a different file. The acceptance must name the check events that actually ran against the accepted bytes. A replay after acceptance must still honor both operation identity and current authority. A refused branch must leave a record that later projections read as refusal rather than silence. Each mechanism can be individually correct and the chain still break, because the bug is in the handoff.
So the chapter’s distinction is component correct ≠ composition holds ≠ deployment ready. Chapters 14 through 28 earned the first. This chapter tests the second, for one exercised path, leaving the third explicitly out of scope with the gap named.
The composition run had a protocol frozen before execution, a pass condition stated in advance — the independent verifier must reconstruct every named link from records plus bytes and catch every seeded corruption — and one explicit tolerance: a gap the run retains visibly does not fail composition; a gap it hides does. 1
The spine, with actual identities
Here is the happy path as the preserved ledger records it. One line is not a ledger record, and it is marked: the scheduler is a pure function, and nothing persisted its answer. 1
directive.opened d-comp READ + WRITE + ACCEPT
directive.opened d-comp-edit READ + WRITE, max_tokens 1000
causation_id = d-comp's event (narrowing validated)
task.created t-comp criteria: remove [S1]; contain "Models supply cognition."
context.compiled selected from task.created
call.* call-comp one fake call; interpretation v1, generation complete
claim.recorded claim-comp-1 legacy claim path, attributed to call-comp
(unledgered) scheduler decide_next_step(has_required_verification) → CHECK
check.* check-comp-1 PASS on the proposal artifact
action.* act-denied DENIED under READ; observed 72bfd9f4… (pre-edit bytes)
action.* act-comp-1 SUCCEEDED under WRITE, requested_by human-approver
observed 77e25726… (post-edit bytes)
check.* check-comp-2 target_state_hash 77e25726… → PASS, observed 77e25726…
task.accepted acc-comp-1 human-reviewer under ACCEPT; names both check events
task.completed causation_id = task.accepted; artifact 77e25726…
action.* act-comp-2 same key, same fingerprint, WRITE → replay of act-comp-1
adapter invocations still 1
The success criterion was never whether the final paragraph reads well, but whether a reader holding only records can answer why the process acted, whether it was allowed to, what changed, which exact state was checked, why it was accepted, and whether repetition caused a second effect. The rest of the chapter shows how each answer is carried — and where an answer rests on convention rather than enforcement.
The whole run as one chain, in the visual vocabulary the book has built — stadium proposes, diamonds gate, cylinders endure:
flowchart TD
O["objective + grant<br/><i>directive: READ + WRITE + ACCEPT</i>"] --> T["task<br/><i>frozen criteria</i>"]
T --> CX["context<br/><i>compiled + recorded</i>"]
CX --> M(["model call<br/><i>the only cognition</i>"])
M --> CL["claim<br/><i>attributed, unresolved</i>"]
CL --> C1["check 1 · PASS<br/><i>independent command</i>"]
C1 --> G{"authority gate?"}
G -->|"READ: deny"| DN["DENIED recorded<br/><i>file unchanged</i>"]
G -->|"WRITE: permit"| A["action<br/><i>effect + observed hash</i>"]
A --> C2["check 2 · PASS<br/><i>bound to the post-edit hash</i>"]
C2 --> H(("human reviewer<br/><i>ACCEPT grant</i>"))
H --> AT["acceptance<br/><i>names call + checks</i>"]
AT --> CO[("completion<br/><i>caused by acceptance</i>")]
CO --> R["replay<br/><i>same key, no second effect</i>"]
G -.->|"cannot proceed"| ESC["stop branches<br/><i>recorded, not retried blind</i>"]
C2 -.->|"FAIL or ERROR"| ESC
Three joints, in the real API
The producer script is ordinary Python against CodeAI’s public runtime. Reduced from the executed producer, with the joint comments added for this chapter: 2
rt = Runtime(ledger, artifact_store=store,
state_resolver=lambda: sha_file(paragraph)) # the runtime's only eyes
done = rt.execute_action(
ActionRequest(action_id="act-comp-1", task_id="t-comp",
directive_id="d-comp-edit", capability="write",
instruction="apply proposal", precondition_hash=None,
idempotency_key="comp:edit:1",
requested_by="human-approver", adapter="fixture-editor"),
authority=WRITE, adapter=editor) # grant passed in by the caller
after_hash = sha_file(paragraph)
assert done.observed_state_hash == after_hash # joint 1
check2 = rt.run_check(
py_check(file_code, cwd=str(ws), check_id="check-comp-2", task_id="t-comp",
target=artifact_target(sha), target_state_hash=after_hash),
verifier=verifier)
assert check2.observed_target_state_hash == after_hash # joint 2
completion = rt.accept_task(
AcceptanceRequest(acceptance_id="acc-comp-1", task_id="t-comp",
actor_id="human-reviewer",
criteria_sha256=criteria_sha256(CRITERIA),
artifact_sha256=sha, source_call_id="call-comp",
source_attempt_id=attempt.attempt_id,
source_interpretation_id=interp.interpretation_id,
check_ids=("check-comp-1", "check-comp-2")),
authority=ACCEPT) # joint 3
Joint 1: effect → observation. execute_action appends action.requested first, looks for a prior completion under the key, checks the capability, compares any precondition, calls the adapter, and then reads the state resolver itself before appending action.completed. The adapter reported succeeded; the runtime separately recorded 77e25726…, the hash of the bytes now on disk. On the denied path, nothing reaches the adapter and the runtime still records its reading — the pre-edit hash — so “denied” and “file unchanged” stand as two recorded facts rather than one inferred from the other. That is Chapter 19’s reported ≠ observed ≠ expected, held in three different places: the adapter’s status, the runtime’s observation, and the task’s frozen criteria. 3
Joint 2: observation → verification. When a check names target_state_hash, run_check reads the resolver once, compares, and only on a match invokes the verifier. On a mismatch it records ERROR without running anything. Whatever happens, the runtime then overwrites observed_target_state_hash with its own reading, so a verifier cannot supply the observation that authorized it. The requested target, the runtime’s observation, and the preserved after-bytes all agree at 77e25726…. 4 1
Joint 3: verification → acceptance. accept_task refuses unless the authority grants ACCEPT, the criteria hash matches the task, the source call succeeded with a complete generation on its final attempt, the named interpretation was that call’s decision basis, the artifact equals the preserved call output, every named check exists for this task, targets these bytes, and passed, and the acceptor is not the actor that produced the artifact. Only then does it append task.accepted and a task.completed whose causation_id points back at it. A completion without that causal pair completes nothing. 5
Read joint 3 closely and one link is missing: the acceptance names the call and the checks, but not the action. Nothing in AcceptanceRequest refers to act-comp-1. The effect joins the acceptance only because check-comp-2 was bound to the post-edit hash, and that hash equals the artifact hash — which holds here because the editor wrote the proposal verbatim. An edit that transformed the proposal on the way to disk would break that equality, and nothing in the acceptance path would say which action produced the accepted state. The capstone reconstructs this link; the runtime does not enforce it. 6
The adequacy of the checks is equally specific. Check-comp-1 tested only that the proposal contained the required sentence; check-comp-2 tested the file for both the sentence and the marker’s absence. Together they cover the frozen criteria exactly, and nothing beyond them — not whether the paragraph is good, which no criterion asked. Independence is similarly modest: the checks are commands that read bytes and share no code with the fake proposer, not a second judgment about meaning. That is Chapter 21’s adequacy in its narrow, honest form. 1
Where cognition was, and was not
Exactly one model call ran, and it was a fake. Everything else in the ledger is deterministic bookkeeping or a labeled human gate: one context compilation, five check completions, six action completions and one replay refusal, one acceptance. 1
The scheduler’s contribution needs stating precisely, because it is easy to overstate. The producer asked decide_next_step a question — verification required — and got CHECK rather than another CALL. Separately, it asked with the model budget exhausted and verification pending, and still got CHECK: spent cognition does not stop a process that has a check to run. Both are real answers from the committed policy. But the flags were set by the producer, not projected from ledger state, and neither answer was persisted. The capstone shows the policy saying the right thing; it does not show the runtime deriving the question or recording the decision. 1 7
The branches that stop
A capstone with only the happy path would hide every boundary the book built. Six branches stop, each in its own durable vocabulary: 1
| Branch | What the ledger holds | What it teaches |
|---|---|---|
| Edit under READ | denied, error capability denied: write, observed pre-edit hash; adapter not called |
Capability ≠ authority; the grant is checked before any effect |
| Stale target | Check ERROR target state mismatch; verifier invocations +0 |
The check never ran, so there is no verdict to misread |
| Same key, new instruction | action.replay_refused naming instruction; editor calls still 1 |
A key is not an operation identity |
| Raising verifier | Check ERROR verifier raised RuntimeError: …; nothing promoted, nothing accepted |
The checker failed ≠ the thing checked failed |
| Effect then crash | Two failed completions, the second replaying the first; marker present in preserved bytes |
Failed ≠ ineffectual; the outcome is unknown |
| Bad proposal | Check FAIL; task projects INCOMPLETE; no acceptance | A failed check ends the line |
The crash branch is the composition’s honest unknown, so it gets a closer reading. The adapter appended a marker to crash.txt before raising, which the runtime recorded as FAILED. A retry under the same key returned that recorded FAILED without calling the adapter again. That is Chapter 22’s decision to cache failure rather than silently re-execute, and here it prevented a second marker.
But look at what the runtime observed for that action: 77e25726…, the hash of paragraph.txt. The resolver was wired to one file, so the recorded observation never saw the effect on the other. The only evidence that the crash changed anything is the preserved crash_final.txt, which the independent verifier reads directly. This is the warning Chapters 19 and 21 both recorded — the resolver is trusted configuration, and the runtime does not validate its coverage — turning up inside a composition that looked fully instrumented. 1
The run records the branch as UNRESOLVED and stops. Nothing in the ledger can say whether retrying is safe, and nothing in the runtime offers an action-level path to find out. Reliability, at this boundary, means refusing to infer “no effect” from a failure status. It also means admitting that the refusal is the whole recovery plan.
What composition exposed
An integration test that finds nothing is either perfect or blind. This one found several joints the runtime does not enforce. None was repaired for the capstone; no runtime mechanism was added. Each is a named edge, and most were already named by the chapter that built the component — composition shows them together, on one path, which is a different kind of evidence than finding them one at a time.
- Decision → action is conventional. No Stage 18
decision.recordedevent exists in this run; the claim went through the older claim path, and claim standing was never derived. The action carriestask_idanddirective_id, so a reader can reconstruct motive, but nothing refuses an action whose decision basis has moved. Chapter 20 proposed that seam; it remains future work. 1 - Directive grant → execution grant is conventional. Registration really does validate that
d-comp-editnarrowsd-comp, reconstructed from the recorded parent. Butexecute_actionchecks theAuthoritythe caller passes in, not the recorded directive’s grant. The happy path passed WRITE because the producer chose to. 8 - Effect → acceptance is conventional. As joint 3 showed, the acceptance names no action; the link runs through a hash equality that happened to hold. 6
- Observation is resolver-scoped. One resolver per runtime, pointed at one file, missed the crash effect entirely. 1
- No action reconcile workflow. Chapter 16’s reconciliation machinery is call-only; the crash branch ends at UNRESOLVED with operator judgment where a workflow would go. 1
One protocol step also did not happen as written. The frozen protocol ends the happy path with “reopen projects COMPLETED.” The producer’s result field is named completion_after_reopen, but it projects completion on the same live runtime handle; no fresh CodeAI handle was opened on the files. What this bundle does show across a process boundary is weaker and different: the independent verifier, in a separate process with no CodeAI import, reads the checkpointed ledger copy and finds a completion caused by a valid acceptance. A true restart — new handles on the same files recovering completion and history — was demonstrated by the earlier 2026-09-13 capstone bundle, not by this one. The label stays as found, and the claim shrinks to fit. 2 9
Checking it without trusting it
The independent verifier is stdlib only. It never imports CodeAI and never reads the producer’s summary for its predicates; it opens the preserved SQLite ledger and the fixture bytes and recomputes. Its predicates fall into four groups:
| Group | Recomputed from records and bytes |
|---|---|
| Grant | Both directives present; child’s causation_id is the parent’s event; child capabilities ⊆ parent’s |
| Effect | Replay fingerprint rebuilt from both request payloads (capability, instruction, canonical-JSON payload hash, precondition, adapter); exactly one original and one replay under the edit key; original’s observation = SHA-256 of the after-bytes; denial carries the pre-edit hash; both crash completions FAILED with the marker in the preserved bytes; one refusal naming instruction |
| Verification | Bound check requested and carried the after-hash; stale and raising checks are ERROR, the latter with its error preserved |
| Acceptance | One acceptance for t-comp referencing both check events; completion caused by it, carrying the after-bytes’ hash; no acceptance on the crash or bad-proposal tasks; call receipt present |
Nine seeded corruptions are applied to temporary copies: a forged completion cause, an altered bound observation, a deleted child directive, a changed instruction on the replay request, a deleted refusal, a replay rewritten as a second physical effect, the raising verifier’s ERROR rewritten as PASS, an acceptance forged for the crash task, and a deleted call receipt. All nine are caught. Re-run on a copy of the bundle during editing, the verifier printed the same result, and printing each corrupted copy’s problem list shows every corruption trips exactly one predicate — the one it targets. 10
This is a stronger verifier than Chapter 21’s demo, which checked a producer summary; this one reads records. Its limits are still worth stating. It is written for this fixture’s identifiers and would need rewriting for another task. It confirms that the twelve-question report has twelve answers, but those answers are the producer’s prose, not the verifier’s derivations. It checks that required event kinds are present, not their counts; the counts cited in this chapter come from reading the ledger. And it checks that a call receipt exists, not that no second call does. 1
The rest of the book, in its place
The capstone does not reprint Stage 29B or the P-series; it spends them where they belong.
Stage 29B is why the capstone holds its single call without apology — and why that restraint is not a verdict for cheap-first execution. On forty synthetic extraction items, the ladder accepted 33 outcomes (32 correct, 1 wrong) against top-first’s 31 (31 correct, 0 wrong). It was cheaper per accepted outcome under the preregistered person-cost scenario, and it still failed its frozen adoption rule because it added an accepted-but-wrong outcome, A05. Top-first avoided A05 through a token-exhausted, unusable output rather than demonstrated better judgment. The capstone inherits the discipline, not a winner. 11
A05 also explains why the capstone’s checks are so narrow. The grounding checker there passed an answer that was grounded and wrong; checks that test only exact byte criteria can be adequate to those criteria because they claim nothing else. The P-series travels as method — matched arms, frozen rules, no promotion without earning it. The capstone promotes nothing, selects nothing by oracle, and prices nothing, and it invokes no independent proposals, so nothing Chapters 23–27 measured about variety is retested here. The model-router challenger stays where Chapter 28 left it: specified with its falsifier, unrun. Nothing in this chapter depends on its outcome, and nothing here shows the deterministic policy would win it. 12 13
Two outside papers earn brief places, and only as interaction design. Chaining model steps so people can inspect, alter, and test intermediate work is the deployment form of this chapter’s trace: transparency through preserved intermediates rather than explanation (Wu et al., 2022). Guidelines for human–AI interaction ask systems to make clear what they can do, support efficient correction, and scope services when uncertain; the stop branches are one concrete way to meet that, since each ERROR, DENIED, and UNRESOLVED hands the person a named state instead of an automated guess (Amershi et al., 2019). Both mappings are the book’s; neither paper validates CodeAI.
What it does not establish
- Neither autonomy nor model behavior. One disposable task, one artifact, canned cognition, and legacy claims leave real model variance and Stage 18 claim standing unexercised. 1
- Not correctness. PASS means the frozen byte criteria held; the criteria are the ceiling of what was checked.
- Not enforcement of every link. Decision → action, directive grant → execution grant, and effect → acceptance are carried by shared identifiers and one hash equality, not refused on violation. 3 6
- Not recovery. There is no action reconcile path, and observation coverage is whatever the resolver was pointed at. The crash branch preserves disagreement; recovery is a person. 1
- Neither exactly-once nor restart. Sequential replay suppressed a known duplicate, while concurrency and crash windows remain outside what was shown. Reopen was not exercised in this bundle. 1
- Not a routing result. The deterministic policy answered two caller-posed, unledgered questions; the router challenger is unrun. 7
- Not identity or tamper-evidence.
human-approveris a string, the ledger is unsigned and single-writer, and the ledger is the trust boundary. Unknown-provenance policy, sandboxing, and the pricing gaps of Chapters 23 and 28 ride along untouched. 14
Do this now
One hour. Run one task end to end, then find the joints you did not enforce.
- Pick a disposable file task with byte-checkable criteria. Freeze the criteria, the authority labels, and the acceptance rule before running.
- Walk it through grant, one model call, an authorized effect, the runtime’s own observation, a check bound to that observation, acceptance, and one exact-duplicate replay. Count model calls, verifier invocations, and physical effects separately.
- Break it four ways: remove the grant, stale the check’s target, reuse the key with a changed instruction, crash between effect and completion. Confirm each stops in its own durable record.
- For every pair of adjacent records — decision and action, grant and execution, effect and acceptance — ask whether the runtime refuses a mismatch or merely lets you reconstruct one. Write the second kind down. That list is your architecture’s real perimeter.
- Hand the ledger and the bytes to someone who has not seen your summary. What they cannot reconstruct is your next gap.
If you are building with an assistant:
Compose one task from directive to acceptance with every transition durable.
Invoke the model only where proposing earns it; decide, check, and gate with
deterministic code and labeled human authority. Record the runtime's own
observation of every effect, and state what the resolver covers. Bind each
check to one observed state. Replay only on matching fingerprint plus current
authority. Stop in durable vocabulary: denied, stale, conflict, error,
unresolved. Then list each joint between records as enforced or conventional,
and verify the chain with a reader that imports none of your code and must
catch seeded corruptions.
Failure modes
- Trusting a joint because the records line up. Matching identifiers let you reconstruct a link; they do not prove anything enforced it.
- Instrumenting one file and calling it observation. The resolver sees what it was pointed at, and a real effect elsewhere leaves no trace in the record.
- Resolving the crash gap in prose. UNRESOLVED is a state of the process, not a sentence awaiting polish.
- Letting a field name carry a claim.
completion_after_reopendid not reopen anything. Read the code that produced a result, not only its label. - Letting the verifier’s scope drift. A reader that checks twelve answers exist has not checked what they say.
What this chapter established
- Composition holds for the exercised path, with six stop branches in six durable records, reconstructed from ledger and bytes by a stdlib reader that catches 9/9 targeted corruptions. 1
- Composition also showed, on one path, what isolation could not: three conventional joints, observation that missed a real effect, no action reconciliation, and a protocol step the producer did not perform. 1
Coda: what Applied AI means now
The book opened with a model in a chat box and an operator doing the engineering in their head. It closes with that engineering moved into software, and with a precise account of how far the move went.
Useful applied AI is ordinary software with intelligent boundaries placed selectively. Deterministic code where the rule is known. A model where proposing, interpreting, or exploring is actually useful — and, as Stage 29B showed, only after the operation has been chosen and the evidence rules for adopting a policy are fixed. Evidence around both. Authority around effects. Verification before acceptance, with independence, adequacy, and binding judged separately. People where intent, authority, or frontier judgment genuinely belong.
None of that makes the model less important. It makes the model replaceable, which is what lets the rest of the system keep its promises when the model changes underneath it.
The capstone shows those pieces joining on one path, and it shows the places where joining is still a convention rather than a guarantee. That is not an anticlimax. A process that can say denied, stale, conflict, error, and unresolved — and can tell you which of its own links it does not yet enforce — is one you can extend without guessing. The slider stays in the human hand: per operation, per risk, per evidence. The runtime’s job is to hold the process steady underneath it and to be honest about where its grip ends.
There is one more consequence, and it is not an engineering result. The architecture that makes the model replaceable is ordinary software, and ordinary software is becoming cheaper to build. The frame, the records, the checks and the policies do not have to be built for everyone. They can be built around you.
Next
The capstone answered the book’s question for one process. The last chapter asks the reader’s question: when software can be built around one person, what should that person build, and how does it keep improving without losing the discipline this book built?
Continue with Your Applied AI.
References
- Tongshuang Wu, Michael Terry, and Carrie J. Cai. AI Chains: Transparent and Controllable Human-AI Interaction by Chaining Large Language Model Prompts. CHI, 2022. arXiv:2110.01691.
- Saleema Amershi et al. Guidelines for Human-AI Interaction. CHI, 2019. Microsoft Research.
Implementation sources: the composition run used CodeAI base 7a0d43b plus an uncommitted working tree whose dirty-file list is recorded in the bundle manifest; that file list matches the later commit a1b562a, though content identity was not hashed at run time. Source inspection for this chapter used a1b562a. src/codeai/runtime.py: Runtime.open_directive, Runtime.execute_action, Runtime.run_check, Runtime._replay_action_result, Runtime._check_action_replay_fingerprint; src/codeai/acceptance.py: accept_task, AcceptanceRequest, project_task_completion; src/codeai/scheduler.py: decide_next_step. No runtime mechanism was added for the capstone. The code excerpt is reduced from the executed producer with comments added. Evidence: experiments/applied-ai/evidence/capstone-composition/ (PROTOCOL.md frozen before the run, producer, results, twelve-question report, preserved ledger, artifacts and fixture bytes, manifest, stdlib verifier with nine seeded corruptions; the verifier was re-run on a copy during editing, and the bundle is unchanged) and experiments/applied-ai/evidence/capstone/ (2026-09-13 demo with fresh-handle restart, preserved untouched). Footnotes mark provenance: measurement notes refer to the frozen-protocol bundle, demo notes to preserved unpinned execution, source notes to inspected code, report notes to frozen designs. Open future work is stated in prose, not footnotes.
-
Measured run:
experiments/applied-ai/evidence/capstone-composition. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ -
Measured run:
experiments/applied-ai/evidence/capstone-composition/run_composition.py. ↩︎ ↩︎ -
Source inspection:
src/codeai/runtime.py(Runtime.execute_action). ↩︎ ↩︎ -
Source inspection:
src/codeai/runtime.py(Runtime.run_check). ↩︎ -
Source inspection:
src/codeai/acceptance.py(accept_task). ↩︎ -
Source inspection:
src/codeai/acceptance.py(AcceptanceRequest). ↩︎ ↩︎ ↩︎ -
Source inspection:
src/codeai/scheduler.py(decide_next_step). ↩︎ ↩︎ -
Source inspection:
src/codeai/runtime.py(Runtime.open_directive, Runtime.execute_action). ↩︎ -
Unpinned demonstration:
experiments/applied-ai/evidence/capstone. ↩︎ -
Measured run:
experiments/applied-ai/evidence/capstone-composition/verify_composition.py. ↩︎ ↩︎ -
Measured run:
experiments/applied-ai/evidence/execution-ladder/2026-09-14-7a0d43b. ↩︎ -
Measured run:
experiments/applied-ai/evidence/p-series-analysis. ↩︎ -
Report:
docs/applied-ai/ch28-router-experiment-design.md. ↩︎ -
Source inspection:
src/codeai/acceptance.py. ↩︎