[{"data":1,"prerenderedAt":4378},["ShallowReactive",2],{"navigation":3,"page-\u002Fchapters\u002Fplans-verified-completion":102,"surround-\u002Fchapters\u002Fplans-verified-completion":4373},[4,8],{"title":5,"path":6,"stem":7},"Home","\u002F","index",{"title":9,"path":10,"stem":11,"children":12,"page":101},"Chapters","\u002Fchapters","2.chapters",[13,17,21,25,29,33,37,41,45,49,53,57,61,65,69,73,77,81,85,89,93,97],{"title":14,"path":15,"stem":16},"Chapter 1. What an Agent Actually Is","\u002Fchapters\u002Fwhat-an-agent-actually-is","2.chapters\u002F01.what-an-agent-actually-is",{"title":18,"path":19,"stem":20},"Chapter 2. The Minimum Viable Loop","\u002Fchapters\u002Fminimum-viable-loop","2.chapters\u002F02.minimum-viable-loop",{"title":22,"path":23,"stem":24},"Chapter 3. Messages, Turns, and the Transcript","\u002Fchapters\u002Fmessages-turns-transcript","2.chapters\u002F03.messages-turns-transcript",{"title":26,"path":27,"stem":28},"Chapter 4. The Tool Protocol","\u002Fchapters\u002Ftool-protocol","2.chapters\u002F04.tool-protocol",{"title":30,"path":31,"stem":32},"Chapter 5. Streaming, Interruption, and Error Handling","\u002Fchapters\u002Fstreaming-interruption-errors","2.chapters\u002F05.streaming-interruption-errors",{"title":34,"path":35,"stem":36},"Chapter 6. Safe Tool Execution","\u002Fchapters\u002Fsafe-tool-execution","2.chapters\u002F06.safe-tool-execution",{"title":38,"path":39,"stem":40},"Chapter 7. The Context Window Is a Resource","\u002Fchapters\u002Fcontext-window-as-resource","2.chapters\u002F07.context-window-as-resource",{"title":42,"path":43,"stem":44},"Chapter 8. Compaction","\u002Fchapters\u002Fcompaction","2.chapters\u002F08.compaction",{"title":46,"path":47,"stem":48},"Chapter 9. External State: The Scratchpad","\u002Fchapters\u002Fscratchpad","2.chapters\u002F09.scratchpad",{"title":50,"path":51,"stem":52},"Chapter 10. Retrieval","\u002Fchapters\u002Fretrieval","2.chapters\u002F10.retrieval",{"title":54,"path":55,"stem":56},"Chapter 11. Designing Tools Models Can Actually Use","\u002Fchapters\u002Fdesigning-tools","2.chapters\u002F11.designing-tools",{"title":58,"path":59,"stem":60},"Chapter 12. The Tool Cliff and Dynamic Loading","\u002Fchapters\u002Ftool-cliff","2.chapters\u002F12.tool-cliff",{"title":62,"path":63,"stem":64},"Chapter 13. MCP: Tools From the Outside World","\u002Fchapters\u002Fmcp","2.chapters\u002F13.mcp",{"title":66,"path":67,"stem":68},"Chapter 14. Sandboxing and Permissions","\u002Fchapters\u002Fsandboxing-permissions","2.chapters\u002F14.sandboxing-permissions",{"title":70,"path":71,"stem":72},"Chapter 15. Sub-agents","\u002Fchapters\u002Fsub-agents","2.chapters\u002F15.sub-agents",{"title":74,"path":75,"stem":76},"Chapter 16. Structured Plans and Verified Completion","\u002Fchapters\u002Fplans-verified-completion","2.chapters\u002F16.plans-verified-completion",{"title":78,"path":79,"stem":80},"Chapter 17. Parallelism and Shared State","\u002Fchapters\u002Fparallelism-shared-state","2.chapters\u002F17.parallelism-shared-state",{"title":82,"path":83,"stem":84},"Chapter 18. Observability","\u002Fchapters\u002Fobservability","2.chapters\u002F18.observability",{"title":86,"path":87,"stem":88},"Chapter 19. Evals","\u002Fchapters\u002Fevals","2.chapters\u002F19.evals",{"title":90,"path":91,"stem":92},"Chapter 20. Cost Control","\u002Fchapters\u002Fcost-control","2.chapters\u002F20.cost-control",{"title":94,"path":95,"stem":96},"Chapter 21. Resumability and Durable State","\u002Fchapters\u002Fresumability","2.chapters\u002F21.resumability",{"title":98,"path":99,"stem":100},"Chapter 22. What Transfers, Where to Go","\u002Fchapters\u002Fwhat-transfers","2.chapters\u002F22.what-transfers",false,{"id":103,"title":74,"body":104,"description":117,"extension":4368,"meta":4369,"navigation":4370,"path":75,"seo":4371,"stem":76,"__hash__":4372},"content\u002F2.chapters\u002F16.plans-verified-completion.md",{"type":105,"value":106,"toc":4359},"minimark",[107,111,118,121,128,134,146,272,275,280,1684,1687,1701,1711,1713,1717,1720,3253,3256,3272,3281,3290,3292,3296,3299,3701,3704,3707,3713,3715,3719,4213,4216,4222,4225,4227,4231,4234,4244,4250,4256,4258,4262,4310,4314,4340,4342,4355],[108,109,74],"h1",{"id":110},"chapter-16-structured-plans-and-verified-completion",[112,113,114],"p",{},[115,116,117],"em",{},"Previously: sub-agents with bounded delegation. A coordinator can now split work across sub-agents and synthesize. What it cannot yet do — and what single-agent runs also cannot — is verify that what it claims to have done, it actually did.",[112,119,120],{},"Two specific failure modes motivate this chapter.",[112,122,123,127],{},[124,125,126],"strong",{},"Premature finalization."," The agent says \"task complete\" after processing half the items. Galileo's production analysis named this as one of the top agent failure patterns — an agent asked to process all items in a list processes four of six and claims completion. The model's training rewards coherent-sounding completions; the agent cannot distinguish \"said X\" from \"did X.\"",[112,129,130,133],{},[124,131,132],{},"Plan-execution mismatch."," The MAST paper (Cemri et al., 2025) identified reasoning-action mismatch as a distinct failure mode across 1,642 multi-agent traces. The agent's plan says \"read A, then modify B.\" The action reads A and modifies C. The plan and the action are generated in separate forward passes; nothing connects them.",[112,135,136,137,140,141,145],{},"Both are addressable by making the plan a ",[124,138,139],{},"structured object"," the harness enforces rather than an unstructured string the agent produces and then may or may not follow. This is Kambhampati et al.'s 2024 ICML position paper \"LLMs Can't Plan, But Can Help Planning in LLM-Modulo Frameworks\" spelled out in concrete code: the paper's core argument is that language models produce plausible plans but cannot reliably self-verify completion, and the right architecture pairs the model with an external verifier that decides when the model's work is actually done. The harness is the external verifier. This chapter introduces ",[142,143,144],"code",{},"Plan",", a dataclass with steps, preconditions, and postconditions. A step has to be marked complete with evidence; a plan has to have all postconditions satisfied before the agent can declare final. The harness checks, not the model.",[147,148,152,265],"figure",{"className":149},[150,151],"not-prose","my-8",[153,154,160,235,239],"div",{"className":155},[156,157,158,159],"flex","flex-col","gap-4","items-center",[153,161,167,191,195,218,221],{"className":162},[156,163,159,164,165,166],"flex-row","gap-3","flex-wrap","justify-center",[153,168,178,185],{"className":169},[170,171,172,173,174,175,176,177],"rounded-lg","border","border-default","bg-elevated","px-4","py-3","text-center","text-sm",[153,179,184],{"className":180},[181,182,183],"font-mono","text-xs","text-muted","step.status",[153,186,190],{"className":187},[188,189],"font-semibold","text-default","pending",[153,192,194],{"className":193},[183],"→",[153,196,198,201,205,210],{"className":197},[170,171,172,173,174,175,176,177],[153,199,184],{"className":200},[181,182,183],[153,202,204],{"className":203},[188,189],"in_progress",[153,206,209],{"className":207},[182,183,208],"mt-1","↓ can side-branch",[153,211,217],{"className":212},[208,213,214,171,172,215,216,182,183],"inline-block","rounded","px-2","py-0.5","blocked",[153,219,194],{"className":220},[183],[153,222,224,227,231],{"className":223},[170,171,172,173,174,175,176,177],[153,225,184],{"className":226},[181,182,183],[153,228,230],{"className":229},[188,189],"done",[153,232,234],{"className":233},[182,183,208],"+ evidence",[153,236,238],{"className":237},[183,177],"↓",[153,240,246,252,261],{"className":241,"style":245},[170,242,243,173,244,175,176],"border-2","border-primary","px-5","max-width:480px;",[153,247,251],{"className":248},[182,181,249,250],"text-primary","tracking-wide","FINALIZATION GATE",[153,253,255,256,260],{"className":254},[177,189,208],"all steps ",[257,258,230],"span",{"className":259},[181],"? postconditions satisfied?",[153,262,264],{"className":263},[182,183,208],"agent cannot emit final answer unless gate passes",[266,267,271],"figcaption",{"className":268},[182,183,269,176,270],"mt-3","italic","The plan state machine. The harness checks the gate; the model cannot self-certify completion.",[273,274],"hr",{},[276,277,279],"h2",{"id":278},"_161-the-shape-of-a-plan","16.1 The Shape of a Plan",[281,282,287],"pre",{"className":283,"code":284,"language":285,"meta":286,"style":286},"language-python shiki shiki-themes material-theme-lighter github-light github-dark","# src\u002Fharness\u002Fplans\u002Fmodel.py\nfrom __future__ import annotations\n\nfrom dataclasses import dataclass, field\nfrom datetime import datetime, timezone\nfrom enum import Enum\nfrom typing import Literal\nfrom uuid import uuid4\n\n\nclass StepStatus(str, Enum):\n    pending = \"pending\"\n    in_progress = \"in_progress\"\n    done = \"done\"\n    blocked = \"blocked\"\n\n\n@dataclass\nclass Step:\n    id: str\n    description: str\n    status: StepStatus = StepStatus.pending\n    evidence: str | None = None   # what proved the step done\n    notes: str = \"\"\n\n    def is_terminal(self) -> bool:\n        return self.status in (StepStatus.done, StepStatus.blocked)\n\n\n@dataclass\nclass Postcondition:\n    description: str\n    satisfied: bool = False\n    evidence: str | None = None\n\n\n@dataclass\nclass Plan:\n    objective: str\n    steps: list[Step] = field(default_factory=list)\n    postconditions: list[Postcondition] = field(default_factory=list)\n    created_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))\n    id: str = field(default_factory=lambda: str(uuid4()))\n\n    def all_steps_terminal(self) -> bool:\n        return all(s.is_terminal() for s in self.steps)\n\n    def all_postconditions_satisfied(self) -> bool:\n        return all(pc.satisfied for pc in self.postconditions)\n\n    def is_ready_to_finalize(self) -> bool:\n        return self.all_steps_terminal() and self.all_postconditions_satisfied()\n\n    def to_render(self) -> str:\n        \"\"\"Render the plan as a string the model can read.\"\"\"\n        lines = [f\"# Plan: {self.objective}\\n\"]\n        lines.append(\"## Steps\")\n        for i, s in enumerate(self.steps, start=1):\n            mark = {\"pending\": \"[ ]\", \"in_progress\": \"[.]\",\n                    \"done\": \"[x]\", \"blocked\": \"[!]\"}[s.status.value]\n            lines.append(f\"{i}. {mark} {s.description}\")\n            if s.evidence:\n                lines.append(f\"     evidence: {s.evidence}\")\n            if s.notes:\n                lines.append(f\"     notes: {s.notes}\")\n        lines.append(\"\\n## Postconditions\")\n        for i, pc in enumerate(self.postconditions, start=1):\n            mark = \"[x]\" if pc.satisfied else \"[ ]\"\n            lines.append(f\"{i}. {mark} {pc.description}\")\n            if pc.evidence:\n                lines.append(f\"     evidence: {pc.evidence}\")\n        return \"\\n\".join(lines)\n","python","",[142,288,289,297,315,322,343,361,374,387,400,405,410,436,456,470,484,498,503,508,519,530,543,553,575,601,616,621,647,685,690,695,702,712,721,736,754,759,764,771,781,791,830,861,906,939,944,964,1003,1008,1028,1061,1066,1086,1113,1118,1138,1152,1192,1214,1252,1298,1350,1398,1414,1445,1459,1489,1511,1544,1576,1619,1632,1661],{"__ignoreMap":286},[257,290,293],{"class":291,"line":292},"line",1,[257,294,296],{"class":295},"sutJx","# src\u002Fharness\u002Fplans\u002Fmodel.py\n",[257,298,300,304,308,311],{"class":291,"line":299},2,[257,301,303],{"class":302},"sVHd0","from",[257,305,307],{"class":306},"s_hVV"," __future__",[257,309,310],{"class":302}," import",[257,312,314],{"class":313},"su5hD"," annotations\n",[257,316,318],{"class":291,"line":317},3,[257,319,321],{"emptyLinePlaceholder":320},true,"\n",[257,323,325,327,330,333,336,340],{"class":291,"line":324},4,[257,326,303],{"class":302},[257,328,329],{"class":313}," dataclasses ",[257,331,332],{"class":302},"import",[257,334,335],{"class":313}," dataclass",[257,337,339],{"class":338},"sP7_E",",",[257,341,342],{"class":313}," field\n",[257,344,346,348,351,353,356,358],{"class":291,"line":345},5,[257,347,303],{"class":302},[257,349,350],{"class":313}," datetime ",[257,352,332],{"class":302},[257,354,355],{"class":313}," datetime",[257,357,339],{"class":338},[257,359,360],{"class":313}," timezone\n",[257,362,364,366,369,371],{"class":291,"line":363},6,[257,365,303],{"class":302},[257,367,368],{"class":313}," enum ",[257,370,332],{"class":302},[257,372,373],{"class":313}," Enum\n",[257,375,377,379,382,384],{"class":291,"line":376},7,[257,378,303],{"class":302},[257,380,381],{"class":313}," typing ",[257,383,332],{"class":302},[257,385,386],{"class":313}," Literal\n",[257,388,390,392,395,397],{"class":291,"line":389},8,[257,391,303],{"class":302},[257,393,394],{"class":313}," uuid ",[257,396,332],{"class":302},[257,398,399],{"class":313}," uuid4\n",[257,401,403],{"class":291,"line":402},9,[257,404,321],{"emptyLinePlaceholder":320},[257,406,408],{"class":291,"line":407},10,[257,409,321],{"emptyLinePlaceholder":320},[257,411,413,417,421,424,428,430,433],{"class":291,"line":412},11,[257,414,416],{"class":415},"sbsja","class",[257,418,420],{"class":419},"sbgvK"," StepStatus",[257,422,423],{"class":338},"(",[257,425,427],{"class":426},"sZMiF","str",[257,429,339],{"class":338},[257,431,432],{"class":419}," Enum",[257,434,435],{"class":338},"):\n",[257,437,439,442,446,450,453],{"class":291,"line":438},12,[257,440,441],{"class":313},"    pending ",[257,443,445],{"class":444},"smGrS","=",[257,447,449],{"class":448},"sjJ54"," \"",[257,451,190],{"class":452},"s_sjI",[257,454,455],{"class":448},"\"\n",[257,457,459,462,464,466,468],{"class":291,"line":458},13,[257,460,461],{"class":313},"    in_progress ",[257,463,445],{"class":444},[257,465,449],{"class":448},[257,467,204],{"class":452},[257,469,455],{"class":448},[257,471,473,476,478,480,482],{"class":291,"line":472},14,[257,474,475],{"class":313},"    done ",[257,477,445],{"class":444},[257,479,449],{"class":448},[257,481,230],{"class":452},[257,483,455],{"class":448},[257,485,487,490,492,494,496],{"class":291,"line":486},15,[257,488,489],{"class":313},"    blocked ",[257,491,445],{"class":444},[257,493,449],{"class":448},[257,495,217],{"class":452},[257,497,455],{"class":448},[257,499,501],{"class":291,"line":500},16,[257,502,321],{"emptyLinePlaceholder":320},[257,504,506],{"class":291,"line":505},17,[257,507,321],{"emptyLinePlaceholder":320},[257,509,511,515],{"class":291,"line":510},18,[257,512,514],{"class":513},"stp6e","@",[257,516,518],{"class":517},"sGLFI","dataclass\n",[257,520,522,524,527],{"class":291,"line":521},19,[257,523,416],{"class":415},[257,525,526],{"class":419}," Step",[257,528,529],{"class":338},":\n",[257,531,533,537,540],{"class":291,"line":532},20,[257,534,536],{"class":535},"sptTA","    id",[257,538,539],{"class":338},":",[257,541,542],{"class":426}," str\n",[257,544,546,549,551],{"class":291,"line":545},21,[257,547,548],{"class":313},"    description",[257,550,539],{"class":338},[257,552,542],{"class":426},[257,554,556,559,561,564,566,568,571],{"class":291,"line":555},22,[257,557,558],{"class":313},"    status",[257,560,539],{"class":338},[257,562,563],{"class":313}," StepStatus ",[257,565,445],{"class":444},[257,567,420],{"class":313},[257,569,570],{"class":338},".",[257,572,574],{"class":573},"skxfh","pending\n",[257,576,578,581,583,586,589,593,596,598],{"class":291,"line":577},23,[257,579,580],{"class":313},"    evidence",[257,582,539],{"class":338},[257,584,585],{"class":426}," str",[257,587,588],{"class":444}," |",[257,590,592],{"class":591},"s39Yj"," None",[257,594,595],{"class":444}," =",[257,597,592],{"class":591},[257,599,600],{"class":295},"   # what proved the step done\n",[257,602,604,607,609,611,613],{"class":291,"line":603},24,[257,605,606],{"class":313},"    notes",[257,608,539],{"class":338},[257,610,585],{"class":426},[257,612,595],{"class":444},[257,614,615],{"class":448}," \"\"\n",[257,617,619],{"class":291,"line":618},25,[257,620,321],{"emptyLinePlaceholder":320},[257,622,624,627,630,632,636,639,642,645],{"class":291,"line":623},26,[257,625,626],{"class":415},"    def",[257,628,629],{"class":517}," is_terminal",[257,631,423],{"class":338},[257,633,635],{"class":634},"smCYv","self",[257,637,638],{"class":338},")",[257,640,641],{"class":338}," ->",[257,643,644],{"class":426}," bool",[257,646,529],{"class":338},[257,648,650,653,656,658,661,664,667,670,672,674,676,678,680,682],{"class":291,"line":649},27,[257,651,652],{"class":302},"        return",[257,654,655],{"class":306}," self",[257,657,570],{"class":338},[257,659,660],{"class":573},"status",[257,662,663],{"class":444}," in",[257,665,666],{"class":338}," (",[257,668,669],{"class":313},"StepStatus",[257,671,570],{"class":338},[257,673,230],{"class":573},[257,675,339],{"class":338},[257,677,420],{"class":313},[257,679,570],{"class":338},[257,681,217],{"class":573},[257,683,684],{"class":338},")\n",[257,686,688],{"class":291,"line":687},28,[257,689,321],{"emptyLinePlaceholder":320},[257,691,693],{"class":291,"line":692},29,[257,694,321],{"emptyLinePlaceholder":320},[257,696,698,700],{"class":291,"line":697},30,[257,699,514],{"class":513},[257,701,518],{"class":517},[257,703,705,707,710],{"class":291,"line":704},31,[257,706,416],{"class":415},[257,708,709],{"class":419}," Postcondition",[257,711,529],{"class":338},[257,713,715,717,719],{"class":291,"line":714},32,[257,716,548],{"class":313},[257,718,539],{"class":338},[257,720,542],{"class":426},[257,722,724,727,729,731,733],{"class":291,"line":723},33,[257,725,726],{"class":313},"    satisfied",[257,728,539],{"class":338},[257,730,644],{"class":426},[257,732,595],{"class":444},[257,734,735],{"class":591}," False\n",[257,737,739,741,743,745,747,749,751],{"class":291,"line":738},34,[257,740,580],{"class":313},[257,742,539],{"class":338},[257,744,585],{"class":426},[257,746,588],{"class":444},[257,748,592],{"class":591},[257,750,595],{"class":444},[257,752,753],{"class":591}," None\n",[257,755,757],{"class":291,"line":756},35,[257,758,321],{"emptyLinePlaceholder":320},[257,760,762],{"class":291,"line":761},36,[257,763,321],{"emptyLinePlaceholder":320},[257,765,767,769],{"class":291,"line":766},37,[257,768,514],{"class":513},[257,770,518],{"class":517},[257,772,774,776,779],{"class":291,"line":773},38,[257,775,416],{"class":415},[257,777,778],{"class":419}," Plan",[257,780,529],{"class":338},[257,782,784,787,789],{"class":291,"line":783},39,[257,785,786],{"class":313},"    objective",[257,788,539],{"class":338},[257,790,542],{"class":426},[257,792,794,797,799,802,805,808,811,813,817,819,823,825,828],{"class":291,"line":793},40,[257,795,796],{"class":313},"    steps",[257,798,539],{"class":338},[257,800,801],{"class":313}," list",[257,803,804],{"class":338},"[",[257,806,807],{"class":313},"Step",[257,809,810],{"class":338},"]",[257,812,595],{"class":444},[257,814,816],{"class":815},"slqww"," field",[257,818,423],{"class":338},[257,820,822],{"class":821},"s99_P","default_factory",[257,824,445],{"class":444},[257,826,827],{"class":426},"list",[257,829,684],{"class":338},[257,831,833,836,838,840,842,845,847,849,851,853,855,857,859],{"class":291,"line":832},41,[257,834,835],{"class":313},"    postconditions",[257,837,539],{"class":338},[257,839,801],{"class":313},[257,841,804],{"class":338},[257,843,844],{"class":313},"Postcondition",[257,846,810],{"class":338},[257,848,595],{"class":444},[257,850,816],{"class":815},[257,852,423],{"class":338},[257,854,822],{"class":821},[257,856,445],{"class":444},[257,858,827],{"class":426},[257,860,684],{"class":338},[257,862,864,867,869,871,873,875,877,879,881,884,886,888,890,893,895,898,900,903],{"class":291,"line":863},42,[257,865,866],{"class":313},"    created_at",[257,868,539],{"class":338},[257,870,350],{"class":313},[257,872,445],{"class":444},[257,874,816],{"class":815},[257,876,423],{"class":338},[257,878,822],{"class":821},[257,880,445],{"class":444},[257,882,883],{"class":415},"lambda",[257,885,539],{"class":338},[257,887,355],{"class":815},[257,889,570],{"class":338},[257,891,892],{"class":815},"now",[257,894,423],{"class":338},[257,896,897],{"class":815},"timezone",[257,899,570],{"class":338},[257,901,902],{"class":573},"utc",[257,904,905],{"class":338},"))\n",[257,907,909,911,913,915,917,919,921,923,925,927,929,931,933,936],{"class":291,"line":908},43,[257,910,536],{"class":535},[257,912,539],{"class":338},[257,914,585],{"class":426},[257,916,595],{"class":444},[257,918,816],{"class":815},[257,920,423],{"class":338},[257,922,822],{"class":821},[257,924,445],{"class":444},[257,926,883],{"class":415},[257,928,539],{"class":338},[257,930,585],{"class":426},[257,932,423],{"class":338},[257,934,935],{"class":815},"uuid4",[257,937,938],{"class":338},"()))\n",[257,940,942],{"class":291,"line":941},44,[257,943,321],{"emptyLinePlaceholder":320},[257,945,947,949,952,954,956,958,960,962],{"class":291,"line":946},45,[257,948,626],{"class":415},[257,950,951],{"class":517}," all_steps_terminal",[257,953,423],{"class":338},[257,955,635],{"class":634},[257,957,638],{"class":338},[257,959,641],{"class":338},[257,961,644],{"class":426},[257,963,529],{"class":338},[257,965,967,969,972,974,977,979,982,985,988,991,994,996,998,1001],{"class":291,"line":966},46,[257,968,652],{"class":302},[257,970,971],{"class":535}," all",[257,973,423],{"class":338},[257,975,976],{"class":815},"s",[257,978,570],{"class":338},[257,980,981],{"class":815},"is_terminal",[257,983,984],{"class":338},"()",[257,986,987],{"class":302}," for",[257,989,990],{"class":815}," s ",[257,992,993],{"class":302},"in",[257,995,655],{"class":306},[257,997,570],{"class":338},[257,999,1000],{"class":573},"steps",[257,1002,684],{"class":338},[257,1004,1006],{"class":291,"line":1005},47,[257,1007,321],{"emptyLinePlaceholder":320},[257,1009,1011,1013,1016,1018,1020,1022,1024,1026],{"class":291,"line":1010},48,[257,1012,626],{"class":415},[257,1014,1015],{"class":517}," all_postconditions_satisfied",[257,1017,423],{"class":338},[257,1019,635],{"class":634},[257,1021,638],{"class":338},[257,1023,641],{"class":338},[257,1025,644],{"class":426},[257,1027,529],{"class":338},[257,1029,1031,1033,1035,1037,1040,1042,1045,1047,1050,1052,1054,1056,1059],{"class":291,"line":1030},49,[257,1032,652],{"class":302},[257,1034,971],{"class":535},[257,1036,423],{"class":338},[257,1038,1039],{"class":815},"pc",[257,1041,570],{"class":338},[257,1043,1044],{"class":573},"satisfied",[257,1046,987],{"class":302},[257,1048,1049],{"class":815}," pc ",[257,1051,993],{"class":302},[257,1053,655],{"class":306},[257,1055,570],{"class":338},[257,1057,1058],{"class":573},"postconditions",[257,1060,684],{"class":338},[257,1062,1064],{"class":291,"line":1063},50,[257,1065,321],{"emptyLinePlaceholder":320},[257,1067,1069,1071,1074,1076,1078,1080,1082,1084],{"class":291,"line":1068},51,[257,1070,626],{"class":415},[257,1072,1073],{"class":517}," is_ready_to_finalize",[257,1075,423],{"class":338},[257,1077,635],{"class":634},[257,1079,638],{"class":338},[257,1081,641],{"class":338},[257,1083,644],{"class":426},[257,1085,529],{"class":338},[257,1087,1089,1091,1093,1095,1098,1100,1103,1105,1107,1110],{"class":291,"line":1088},52,[257,1090,652],{"class":302},[257,1092,655],{"class":306},[257,1094,570],{"class":338},[257,1096,1097],{"class":815},"all_steps_terminal",[257,1099,984],{"class":338},[257,1101,1102],{"class":444}," and",[257,1104,655],{"class":306},[257,1106,570],{"class":338},[257,1108,1109],{"class":815},"all_postconditions_satisfied",[257,1111,1112],{"class":338},"()\n",[257,1114,1116],{"class":291,"line":1115},53,[257,1117,321],{"emptyLinePlaceholder":320},[257,1119,1121,1123,1126,1128,1130,1132,1134,1136],{"class":291,"line":1120},54,[257,1122,626],{"class":415},[257,1124,1125],{"class":517}," to_render",[257,1127,423],{"class":338},[257,1129,635],{"class":634},[257,1131,638],{"class":338},[257,1133,641],{"class":338},[257,1135,585],{"class":426},[257,1137,529],{"class":338},[257,1139,1141,1145,1149],{"class":291,"line":1140},55,[257,1142,1144],{"class":1143},"s2W-s","        \"\"\"",[257,1146,1148],{"class":1147},"sithA","Render the plan as a string the model can read.",[257,1150,1151],{"class":1143},"\"\"\"\n",[257,1153,1155,1158,1160,1163,1166,1169,1173,1175,1177,1180,1183,1186,1189],{"class":291,"line":1154},56,[257,1156,1157],{"class":313},"        lines ",[257,1159,445],{"class":444},[257,1161,1162],{"class":338}," [",[257,1164,1165],{"class":415},"f",[257,1167,1168],{"class":452},"\"# Plan: ",[257,1170,1172],{"class":1171},"srdBf","{",[257,1174,635],{"class":306},[257,1176,570],{"class":338},[257,1178,1179],{"class":573},"objective",[257,1181,1182],{"class":1171},"}",[257,1184,1185],{"class":306},"\\n",[257,1187,1188],{"class":452},"\"",[257,1190,1191],{"class":338},"]\n",[257,1193,1195,1198,1200,1203,1205,1207,1210,1212],{"class":291,"line":1194},57,[257,1196,1197],{"class":313},"        lines",[257,1199,570],{"class":338},[257,1201,1202],{"class":815},"append",[257,1204,423],{"class":338},[257,1206,1188],{"class":448},[257,1208,1209],{"class":452},"## Steps",[257,1211,1188],{"class":448},[257,1213,684],{"class":338},[257,1215,1217,1220,1223,1225,1227,1229,1232,1234,1236,1238,1240,1242,1245,1247,1250],{"class":291,"line":1216},58,[257,1218,1219],{"class":302},"        for",[257,1221,1222],{"class":313}," i",[257,1224,339],{"class":338},[257,1226,990],{"class":313},[257,1228,993],{"class":302},[257,1230,1231],{"class":535}," enumerate",[257,1233,423],{"class":338},[257,1235,635],{"class":306},[257,1237,570],{"class":338},[257,1239,1000],{"class":573},[257,1241,339],{"class":338},[257,1243,1244],{"class":821}," start",[257,1246,445],{"class":444},[257,1248,1249],{"class":1171},"1",[257,1251,435],{"class":338},[257,1253,1255,1258,1260,1263,1265,1267,1269,1271,1273,1276,1278,1280,1282,1284,1286,1288,1290,1293,1295],{"class":291,"line":1254},59,[257,1256,1257],{"class":313},"            mark ",[257,1259,445],{"class":444},[257,1261,1262],{"class":338}," {",[257,1264,1188],{"class":448},[257,1266,190],{"class":452},[257,1268,1188],{"class":448},[257,1270,539],{"class":338},[257,1272,449],{"class":448},[257,1274,1275],{"class":452},"[ ]",[257,1277,1188],{"class":448},[257,1279,339],{"class":338},[257,1281,449],{"class":448},[257,1283,204],{"class":452},[257,1285,1188],{"class":448},[257,1287,539],{"class":338},[257,1289,449],{"class":448},[257,1291,1292],{"class":452},"[.]",[257,1294,1188],{"class":448},[257,1296,1297],{"class":338},",\n",[257,1299,1301,1304,1306,1308,1310,1312,1315,1317,1319,1321,1323,1325,1327,1329,1332,1334,1337,1339,1341,1343,1345,1348],{"class":291,"line":1300},60,[257,1302,1303],{"class":448},"                    \"",[257,1305,230],{"class":452},[257,1307,1188],{"class":448},[257,1309,539],{"class":338},[257,1311,449],{"class":448},[257,1313,1314],{"class":452},"[x]",[257,1316,1188],{"class":448},[257,1318,339],{"class":338},[257,1320,449],{"class":448},[257,1322,217],{"class":452},[257,1324,1188],{"class":448},[257,1326,539],{"class":338},[257,1328,449],{"class":448},[257,1330,1331],{"class":452},"[!]",[257,1333,1188],{"class":448},[257,1335,1336],{"class":338},"}[",[257,1338,976],{"class":313},[257,1340,570],{"class":338},[257,1342,660],{"class":573},[257,1344,570],{"class":338},[257,1346,1347],{"class":573},"value",[257,1349,1191],{"class":338},[257,1351,1353,1356,1358,1360,1362,1364,1366,1368,1371,1373,1376,1378,1381,1383,1385,1387,1389,1392,1394,1396],{"class":291,"line":1352},61,[257,1354,1355],{"class":313},"            lines",[257,1357,570],{"class":338},[257,1359,1202],{"class":815},[257,1361,423],{"class":338},[257,1363,1165],{"class":415},[257,1365,1188],{"class":452},[257,1367,1172],{"class":1171},[257,1369,1370],{"class":815},"i",[257,1372,1182],{"class":1171},[257,1374,1375],{"class":452},". ",[257,1377,1172],{"class":1171},[257,1379,1380],{"class":815},"mark",[257,1382,1182],{"class":1171},[257,1384,1262],{"class":1171},[257,1386,976],{"class":815},[257,1388,570],{"class":338},[257,1390,1391],{"class":573},"description",[257,1393,1182],{"class":1171},[257,1395,1188],{"class":452},[257,1397,684],{"class":338},[257,1399,1401,1404,1407,1409,1412],{"class":291,"line":1400},62,[257,1402,1403],{"class":302},"            if",[257,1405,1406],{"class":313}," s",[257,1408,570],{"class":338},[257,1410,1411],{"class":573},"evidence",[257,1413,529],{"class":338},[257,1415,1417,1420,1422,1424,1426,1428,1431,1433,1435,1437,1439,1441,1443],{"class":291,"line":1416},63,[257,1418,1419],{"class":313},"                lines",[257,1421,570],{"class":338},[257,1423,1202],{"class":815},[257,1425,423],{"class":338},[257,1427,1165],{"class":415},[257,1429,1430],{"class":452},"\"     evidence: ",[257,1432,1172],{"class":1171},[257,1434,976],{"class":815},[257,1436,570],{"class":338},[257,1438,1411],{"class":573},[257,1440,1182],{"class":1171},[257,1442,1188],{"class":452},[257,1444,684],{"class":338},[257,1446,1448,1450,1452,1454,1457],{"class":291,"line":1447},64,[257,1449,1403],{"class":302},[257,1451,1406],{"class":313},[257,1453,570],{"class":338},[257,1455,1456],{"class":573},"notes",[257,1458,529],{"class":338},[257,1460,1462,1464,1466,1468,1470,1472,1475,1477,1479,1481,1483,1485,1487],{"class":291,"line":1461},65,[257,1463,1419],{"class":313},[257,1465,570],{"class":338},[257,1467,1202],{"class":815},[257,1469,423],{"class":338},[257,1471,1165],{"class":415},[257,1473,1474],{"class":452},"\"     notes: ",[257,1476,1172],{"class":1171},[257,1478,976],{"class":815},[257,1480,570],{"class":338},[257,1482,1456],{"class":573},[257,1484,1182],{"class":1171},[257,1486,1188],{"class":452},[257,1488,684],{"class":338},[257,1490,1492,1494,1496,1498,1500,1502,1504,1507,1509],{"class":291,"line":1491},66,[257,1493,1197],{"class":313},[257,1495,570],{"class":338},[257,1497,1202],{"class":815},[257,1499,423],{"class":338},[257,1501,1188],{"class":448},[257,1503,1185],{"class":306},[257,1505,1506],{"class":452},"## Postconditions",[257,1508,1188],{"class":448},[257,1510,684],{"class":338},[257,1512,1514,1516,1518,1520,1522,1524,1526,1528,1530,1532,1534,1536,1538,1540,1542],{"class":291,"line":1513},67,[257,1515,1219],{"class":302},[257,1517,1222],{"class":313},[257,1519,339],{"class":338},[257,1521,1049],{"class":313},[257,1523,993],{"class":302},[257,1525,1231],{"class":535},[257,1527,423],{"class":338},[257,1529,635],{"class":306},[257,1531,570],{"class":338},[257,1533,1058],{"class":573},[257,1535,339],{"class":338},[257,1537,1244],{"class":821},[257,1539,445],{"class":444},[257,1541,1249],{"class":1171},[257,1543,435],{"class":338},[257,1545,1547,1549,1551,1553,1555,1557,1560,1563,1565,1567,1570,1572,1574],{"class":291,"line":1546},68,[257,1548,1257],{"class":313},[257,1550,445],{"class":444},[257,1552,449],{"class":448},[257,1554,1314],{"class":452},[257,1556,1188],{"class":448},[257,1558,1559],{"class":302}," if",[257,1561,1562],{"class":313}," pc",[257,1564,570],{"class":338},[257,1566,1044],{"class":573},[257,1568,1569],{"class":302}," else",[257,1571,449],{"class":448},[257,1573,1275],{"class":452},[257,1575,455],{"class":448},[257,1577,1579,1581,1583,1585,1587,1589,1591,1593,1595,1597,1599,1601,1603,1605,1607,1609,1611,1613,1615,1617],{"class":291,"line":1578},69,[257,1580,1355],{"class":313},[257,1582,570],{"class":338},[257,1584,1202],{"class":815},[257,1586,423],{"class":338},[257,1588,1165],{"class":415},[257,1590,1188],{"class":452},[257,1592,1172],{"class":1171},[257,1594,1370],{"class":815},[257,1596,1182],{"class":1171},[257,1598,1375],{"class":452},[257,1600,1172],{"class":1171},[257,1602,1380],{"class":815},[257,1604,1182],{"class":1171},[257,1606,1262],{"class":1171},[257,1608,1039],{"class":815},[257,1610,570],{"class":338},[257,1612,1391],{"class":573},[257,1614,1182],{"class":1171},[257,1616,1188],{"class":452},[257,1618,684],{"class":338},[257,1620,1622,1624,1626,1628,1630],{"class":291,"line":1621},70,[257,1623,1403],{"class":302},[257,1625,1562],{"class":313},[257,1627,570],{"class":338},[257,1629,1411],{"class":573},[257,1631,529],{"class":338},[257,1633,1635,1637,1639,1641,1643,1645,1647,1649,1651,1653,1655,1657,1659],{"class":291,"line":1634},71,[257,1636,1419],{"class":313},[257,1638,570],{"class":338},[257,1640,1202],{"class":815},[257,1642,423],{"class":338},[257,1644,1165],{"class":415},[257,1646,1430],{"class":452},[257,1648,1172],{"class":1171},[257,1650,1039],{"class":815},[257,1652,570],{"class":338},[257,1654,1411],{"class":573},[257,1656,1182],{"class":1171},[257,1658,1188],{"class":452},[257,1660,684],{"class":338},[257,1662,1664,1666,1668,1670,1672,1674,1677,1679,1682],{"class":291,"line":1663},72,[257,1665,652],{"class":302},[257,1667,449],{"class":448},[257,1669,1185],{"class":306},[257,1671,1188],{"class":448},[257,1673,570],{"class":338},[257,1675,1676],{"class":815},"join",[257,1678,423],{"class":338},[257,1680,1681],{"class":815},"lines",[257,1683,684],{"class":338},[112,1685,1686],{},"Two distinctions worth naming.",[112,1688,1689,1692,1693,1696,1697,1700],{},[124,1690,1691],{},"Steps vs. postconditions."," A step is ",[115,1694,1695],{},"what you do",". A postcondition is ",[115,1698,1699],{},"what must be true at the end",". They overlap, but not fully: a plan might have five steps and two postconditions, and both kinds matter. Steps let the agent track progress mid-task; postconditions let the harness check that outcomes actually landed.",[112,1702,1703,1706,1707,1710],{},[124,1704,1705],{},"Evidence is a string."," Not a boolean. When the model marks a step done, it must provide evidence — \"ran tests; all passed, see scratchpad",[257,1708,1709],{},"test-results","\"; \"wrote file; confirmed with read_file_viewport at line 47-52.\" Evidence gives the harness something to check later, and gives debugging a paper trail. The harness doesn't parse the evidence; it just requires it's non-empty. The model knows to put useful things there because the plan's render shows the evidence field.",[273,1712],{},[276,1714,1716],{"id":1715},"_162-plan-tools","16.2 Plan Tools",[112,1718,1719],{},"The agent interacts with the plan via tools.",[281,1721,1723],{"className":283,"code":1722,"language":285,"meta":286,"style":286},"# src\u002Fharness\u002Fplans\u002Ftools.py\nfrom __future__ import annotations\n\nfrom dataclasses import dataclass\n\nfrom ..tools.base import Tool\nfrom ..tools.decorator import tool\nfrom .model import Plan, Postcondition, Step, StepStatus\n\n\n@dataclass\nclass PlanHolder:\n    \"\"\"Wraps a mutable Plan so tools can mutate it through a shared reference.\"\"\"\n    plan: Plan | None = None\n\n    def require(self) -> Plan:\n        if self.plan is None:\n            raise RuntimeError(\"no active plan\")\n        return self.plan\n\n\ndef plan_tools(holder: PlanHolder) -> list[Tool]:\n\n    @tool(side_effects={\"write\"})\n    def plan_create(objective: str, steps: list[str],\n                     postconditions: list[str]) -> str:\n        \"\"\"Create or replace the plan for this session.\n\n        objective: one-sentence description of what you're trying to\n                   accomplish.\n        steps: ordered list of step descriptions. Each is a specific\n               actionable item, not a vague intent.\n        postconditions: list of conditions that must be true when you\n                        declare the task complete. Examples: \"file X\n                        exists and contains Y\"; \"tests in module Z pass\".\n\n        Call this once at the start of any non-trivial task, before\n        beginning work. If the plan is wrong mid-task, call this again\n        to replace it — the harness records the rewrite.\n        \"\"\"\n        holder.plan = Plan(\n            objective=objective,\n            steps=[Step(id=f\"s{i}\", description=d) for i, d in enumerate(steps)],\n            postconditions=[Postcondition(description=d) for d in postconditions],\n        )\n        return f\"plan created with {len(steps)} steps and {len(postconditions)} postconditions\"\n\n    @tool(side_effects={\"read\"})\n    def plan_show() -> str:\n        \"\"\"Display the current plan with its step and postcondition status.\n\n        Use this any time you want to re-orient — especially after long\n        sub-tasks or compaction. The plan is durable; compaction won't\n        lose it.\n        \"\"\"\n        return holder.require().to_render()\n\n    @tool(side_effects={\"write\"})\n    def step_update(step_number: int, status: str, evidence: str = \"\",\n                     notes: str = \"\") -> str:\n        \"\"\"Update a step's status.\n\n        step_number: 1-based index from `plan_show`.\n        status: one of 'pending', 'in_progress', 'done', 'blocked'.\n        evidence: required for 'done'. One-sentence proof of completion\n                  (reference to a tool result, a scratchpad key, etc.).\n        notes: optional free text.\n        \"\"\"\n        plan = holder.require()\n        if step_number \u003C 1 or step_number > len(plan.steps):\n            return f\"step_number {step_number} out of range (1..{len(plan.steps)})\"\n        try:\n            new_status = StepStatus(status)\n        except ValueError:\n            return f\"invalid status {status!r}; use pending\u002Fin_progress\u002Fdone\u002Fblocked\"\n        if new_status == StepStatus.done and not evidence:\n            return (\"error: marking a step 'done' requires evidence. Describe \"\n                    \"what proved the step complete (e.g., 'wrote file and \"\n                    \"read it back; content matches').\")\n        s = plan.steps[step_number - 1]\n        plan.steps[step_number - 1] = Step(\n            id=s.id, description=s.description,\n            status=new_status, evidence=evidence or None,\n            notes=notes,\n        )\n        return f\"step {step_number} → {status}\"\n\n    @tool(side_effects={\"write\"})\n    def postcondition_verify(postcondition_number: int, evidence: str) -> str:\n        \"\"\"Mark a postcondition as verified.\n\n        postcondition_number: 1-based index.\n        evidence: required. Concrete proof the postcondition holds.\n\n        This is what the harness checks before letting you declare the\n        task complete. Do not verify a postcondition without evidence.\n        \"\"\"\n        plan = holder.require()\n        if postcondition_number \u003C 1 or postcondition_number > len(plan.postconditions):\n            return (f\"postcondition_number {postcondition_number} out of range \"\n                    f\"(1..{len(plan.postconditions)})\")\n        if not evidence:\n            return \"error: evidence is required to verify a postcondition\"\n        pc = plan.postconditions[postcondition_number - 1]\n        plan.postconditions[postcondition_number - 1] = Postcondition(\n            description=pc.description, satisfied=True, evidence=evidence,\n        )\n        return f\"postcondition {postcondition_number} verified\"\n\n    return [plan_create, plan_show, step_update, postcondition_verify]\n",[142,1724,1725,1730,1740,1744,1755,1759,1779,1797,1824,1828,1832,1838,1847,1857,1876,1880,1899,1918,1937,1948,1952,1956,1988,1992,2019,2050,2072,2079,2083,2088,2093,2098,2103,2108,2113,2118,2122,2127,2132,2137,2142,2158,2169,2232,2264,2269,2310,2314,2337,2352,2359,2363,2368,2373,2378,2382,2402,2406,2428,2470,2491,2498,2502,2507,2512,2517,2522,2527,2531,2546,2580,2618,2625,2641,2652,2674,2700,2714,2724,2736,2763,2789,2817,2844,2856,2861,2888,2893,2916,2949,2957,2962,2968,2974,2979,2985,2991,2996,3011,3041,3062,3092,3103,3115,3140,3165,3199,3204,3223,3228],{"__ignoreMap":286},[257,1726,1727],{"class":291,"line":292},[257,1728,1729],{"class":295},"# src\u002Fharness\u002Fplans\u002Ftools.py\n",[257,1731,1732,1734,1736,1738],{"class":291,"line":299},[257,1733,303],{"class":302},[257,1735,307],{"class":306},[257,1737,310],{"class":302},[257,1739,314],{"class":313},[257,1741,1742],{"class":291,"line":317},[257,1743,321],{"emptyLinePlaceholder":320},[257,1745,1746,1748,1750,1752],{"class":291,"line":324},[257,1747,303],{"class":302},[257,1749,329],{"class":313},[257,1751,332],{"class":302},[257,1753,1754],{"class":313}," dataclass\n",[257,1756,1757],{"class":291,"line":345},[257,1758,321],{"emptyLinePlaceholder":320},[257,1760,1761,1763,1766,1769,1771,1774,1776],{"class":291,"line":363},[257,1762,303],{"class":302},[257,1764,1765],{"class":338}," ..",[257,1767,1768],{"class":313},"tools",[257,1770,570],{"class":338},[257,1772,1773],{"class":313},"base ",[257,1775,332],{"class":302},[257,1777,1778],{"class":313}," Tool\n",[257,1780,1781,1783,1785,1787,1789,1792,1794],{"class":291,"line":376},[257,1782,303],{"class":302},[257,1784,1765],{"class":338},[257,1786,1768],{"class":313},[257,1788,570],{"class":338},[257,1790,1791],{"class":313},"decorator ",[257,1793,332],{"class":302},[257,1795,1796],{"class":313}," tool\n",[257,1798,1799,1801,1804,1807,1809,1811,1813,1815,1817,1819,1821],{"class":291,"line":389},[257,1800,303],{"class":302},[257,1802,1803],{"class":338}," .",[257,1805,1806],{"class":313},"model ",[257,1808,332],{"class":302},[257,1810,778],{"class":313},[257,1812,339],{"class":338},[257,1814,709],{"class":313},[257,1816,339],{"class":338},[257,1818,526],{"class":313},[257,1820,339],{"class":338},[257,1822,1823],{"class":313}," StepStatus\n",[257,1825,1826],{"class":291,"line":402},[257,1827,321],{"emptyLinePlaceholder":320},[257,1829,1830],{"class":291,"line":407},[257,1831,321],{"emptyLinePlaceholder":320},[257,1833,1834,1836],{"class":291,"line":412},[257,1835,514],{"class":513},[257,1837,518],{"class":517},[257,1839,1840,1842,1845],{"class":291,"line":438},[257,1841,416],{"class":415},[257,1843,1844],{"class":419}," PlanHolder",[257,1846,529],{"class":338},[257,1848,1849,1852,1855],{"class":291,"line":458},[257,1850,1851],{"class":1143},"    \"\"\"",[257,1853,1854],{"class":1147},"Wraps a mutable Plan so tools can mutate it through a shared reference.",[257,1856,1151],{"class":1143},[257,1858,1859,1862,1864,1867,1870,1872,1874],{"class":291,"line":472},[257,1860,1861],{"class":313},"    plan",[257,1863,539],{"class":338},[257,1865,1866],{"class":313}," Plan ",[257,1868,1869],{"class":444},"|",[257,1871,592],{"class":591},[257,1873,595],{"class":444},[257,1875,753],{"class":591},[257,1877,1878],{"class":291,"line":486},[257,1879,321],{"emptyLinePlaceholder":320},[257,1881,1882,1884,1887,1889,1891,1893,1895,1897],{"class":291,"line":500},[257,1883,626],{"class":415},[257,1885,1886],{"class":517}," require",[257,1888,423],{"class":338},[257,1890,635],{"class":634},[257,1892,638],{"class":338},[257,1894,641],{"class":338},[257,1896,778],{"class":313},[257,1898,529],{"class":338},[257,1900,1901,1904,1906,1908,1911,1914,1916],{"class":291,"line":505},[257,1902,1903],{"class":302},"        if",[257,1905,655],{"class":306},[257,1907,570],{"class":338},[257,1909,1910],{"class":573},"plan",[257,1912,1913],{"class":444}," is",[257,1915,592],{"class":591},[257,1917,529],{"class":338},[257,1919,1920,1923,1926,1928,1930,1933,1935],{"class":291,"line":510},[257,1921,1922],{"class":302},"            raise",[257,1924,1925],{"class":426}," RuntimeError",[257,1927,423],{"class":338},[257,1929,1188],{"class":448},[257,1931,1932],{"class":452},"no active plan",[257,1934,1188],{"class":448},[257,1936,684],{"class":338},[257,1938,1939,1941,1943,1945],{"class":291,"line":521},[257,1940,652],{"class":302},[257,1942,655],{"class":306},[257,1944,570],{"class":338},[257,1946,1947],{"class":573},"plan\n",[257,1949,1950],{"class":291,"line":532},[257,1951,321],{"emptyLinePlaceholder":320},[257,1953,1954],{"class":291,"line":545},[257,1955,321],{"emptyLinePlaceholder":320},[257,1957,1958,1961,1964,1966,1970,1972,1974,1976,1978,1980,1982,1985],{"class":291,"line":555},[257,1959,1960],{"class":415},"def",[257,1962,1963],{"class":517}," plan_tools",[257,1965,423],{"class":338},[257,1967,1969],{"class":1968},"sFwrP","holder",[257,1971,539],{"class":338},[257,1973,1844],{"class":313},[257,1975,638],{"class":338},[257,1977,641],{"class":338},[257,1979,801],{"class":313},[257,1981,804],{"class":338},[257,1983,1984],{"class":313},"Tool",[257,1986,1987],{"class":338},"]:\n",[257,1989,1990],{"class":291,"line":577},[257,1991,321],{"emptyLinePlaceholder":320},[257,1993,1994,1997,2000,2002,2005,2007,2009,2011,2014,2016],{"class":291,"line":603},[257,1995,1996],{"class":513},"    @",[257,1998,1999],{"class":517},"tool",[257,2001,423],{"class":338},[257,2003,2004],{"class":821},"side_effects",[257,2006,445],{"class":444},[257,2008,1172],{"class":338},[257,2010,1188],{"class":448},[257,2012,2013],{"class":452},"write",[257,2015,1188],{"class":448},[257,2017,2018],{"class":338},"})\n",[257,2020,2021,2023,2026,2028,2030,2032,2034,2036,2039,2041,2043,2045,2047],{"class":291,"line":618},[257,2022,626],{"class":415},[257,2024,2025],{"class":517}," plan_create",[257,2027,423],{"class":338},[257,2029,1179],{"class":1968},[257,2031,539],{"class":338},[257,2033,585],{"class":426},[257,2035,339],{"class":338},[257,2037,2038],{"class":1968}," steps",[257,2040,539],{"class":338},[257,2042,801],{"class":313},[257,2044,804],{"class":338},[257,2046,427],{"class":426},[257,2048,2049],{"class":338},"],\n",[257,2051,2052,2055,2057,2059,2061,2063,2066,2068,2070],{"class":291,"line":623},[257,2053,2054],{"class":1968},"                     postconditions",[257,2056,539],{"class":338},[257,2058,801],{"class":313},[257,2060,804],{"class":338},[257,2062,427],{"class":426},[257,2064,2065],{"class":338},"])",[257,2067,641],{"class":338},[257,2069,585],{"class":426},[257,2071,529],{"class":338},[257,2073,2074,2076],{"class":291,"line":649},[257,2075,1144],{"class":1143},[257,2077,2078],{"class":1147},"Create or replace the plan for this session.\n",[257,2080,2081],{"class":291,"line":687},[257,2082,321],{"emptyLinePlaceholder":320},[257,2084,2085],{"class":291,"line":692},[257,2086,2087],{"class":1147},"        objective: one-sentence description of what you're trying to\n",[257,2089,2090],{"class":291,"line":697},[257,2091,2092],{"class":1147},"                   accomplish.\n",[257,2094,2095],{"class":291,"line":704},[257,2096,2097],{"class":1147},"        steps: ordered list of step descriptions. Each is a specific\n",[257,2099,2100],{"class":291,"line":714},[257,2101,2102],{"class":1147},"               actionable item, not a vague intent.\n",[257,2104,2105],{"class":291,"line":723},[257,2106,2107],{"class":1147},"        postconditions: list of conditions that must be true when you\n",[257,2109,2110],{"class":291,"line":738},[257,2111,2112],{"class":1147},"                        declare the task complete. Examples: \"file X\n",[257,2114,2115],{"class":291,"line":756},[257,2116,2117],{"class":1147},"                        exists and contains Y\"; \"tests in module Z pass\".\n",[257,2119,2120],{"class":291,"line":761},[257,2121,321],{"emptyLinePlaceholder":320},[257,2123,2124],{"class":291,"line":766},[257,2125,2126],{"class":1147},"        Call this once at the start of any non-trivial task, before\n",[257,2128,2129],{"class":291,"line":773},[257,2130,2131],{"class":1147},"        beginning work. If the plan is wrong mid-task, call this again\n",[257,2133,2134],{"class":291,"line":783},[257,2135,2136],{"class":1147},"        to replace it — the harness records the rewrite.\n",[257,2138,2139],{"class":291,"line":793},[257,2140,2141],{"class":1143},"        \"\"\"\n",[257,2143,2144,2147,2149,2151,2153,2155],{"class":291,"line":832},[257,2145,2146],{"class":313},"        holder",[257,2148,570],{"class":338},[257,2150,1910],{"class":573},[257,2152,595],{"class":444},[257,2154,778],{"class":815},[257,2156,2157],{"class":338},"(\n",[257,2159,2160,2163,2165,2167],{"class":291,"line":863},[257,2161,2162],{"class":821},"            objective",[257,2164,445],{"class":444},[257,2166,1179],{"class":815},[257,2168,1297],{"class":338},[257,2170,2171,2174,2176,2178,2180,2182,2185,2187,2189,2192,2194,2196,2198,2200,2202,2205,2207,2210,2212,2214,2216,2218,2221,2223,2225,2227,2229],{"class":291,"line":908},[257,2172,2173],{"class":821},"            steps",[257,2175,445],{"class":444},[257,2177,804],{"class":338},[257,2179,807],{"class":815},[257,2181,423],{"class":338},[257,2183,2184],{"class":821},"id",[257,2186,445],{"class":444},[257,2188,1165],{"class":415},[257,2190,2191],{"class":452},"\"s",[257,2193,1172],{"class":1171},[257,2195,1370],{"class":815},[257,2197,1182],{"class":1171},[257,2199,1188],{"class":452},[257,2201,339],{"class":338},[257,2203,2204],{"class":821}," description",[257,2206,445],{"class":444},[257,2208,2209],{"class":815},"d",[257,2211,638],{"class":338},[257,2213,987],{"class":302},[257,2215,1222],{"class":815},[257,2217,339],{"class":338},[257,2219,2220],{"class":815}," d ",[257,2222,993],{"class":302},[257,2224,1231],{"class":535},[257,2226,423],{"class":338},[257,2228,1000],{"class":815},[257,2230,2231],{"class":338},")],\n",[257,2233,2234,2237,2239,2241,2243,2245,2247,2249,2251,2253,2255,2257,2259,2262],{"class":291,"line":941},[257,2235,2236],{"class":821},"            postconditions",[257,2238,445],{"class":444},[257,2240,804],{"class":338},[257,2242,844],{"class":815},[257,2244,423],{"class":338},[257,2246,1391],{"class":821},[257,2248,445],{"class":444},[257,2250,2209],{"class":815},[257,2252,638],{"class":338},[257,2254,987],{"class":302},[257,2256,2220],{"class":815},[257,2258,993],{"class":302},[257,2260,2261],{"class":815}," postconditions",[257,2263,2049],{"class":338},[257,2265,2266],{"class":291,"line":946},[257,2267,2268],{"class":338},"        )\n",[257,2270,2271,2273,2276,2279,2281,2284,2286,2288,2290,2292,2295,2297,2299,2301,2303,2305,2307],{"class":291,"line":966},[257,2272,652],{"class":302},[257,2274,2275],{"class":415}," f",[257,2277,2278],{"class":452},"\"plan created with ",[257,2280,1172],{"class":1171},[257,2282,2283],{"class":535},"len",[257,2285,423],{"class":338},[257,2287,1000],{"class":815},[257,2289,638],{"class":338},[257,2291,1182],{"class":1171},[257,2293,2294],{"class":452}," steps and ",[257,2296,1172],{"class":1171},[257,2298,2283],{"class":535},[257,2300,423],{"class":338},[257,2302,1058],{"class":815},[257,2304,638],{"class":338},[257,2306,1182],{"class":1171},[257,2308,2309],{"class":452}," postconditions\"\n",[257,2311,2312],{"class":291,"line":1005},[257,2313,321],{"emptyLinePlaceholder":320},[257,2315,2316,2318,2320,2322,2324,2326,2328,2330,2333,2335],{"class":291,"line":1010},[257,2317,1996],{"class":513},[257,2319,1999],{"class":517},[257,2321,423],{"class":338},[257,2323,2004],{"class":821},[257,2325,445],{"class":444},[257,2327,1172],{"class":338},[257,2329,1188],{"class":448},[257,2331,2332],{"class":452},"read",[257,2334,1188],{"class":448},[257,2336,2018],{"class":338},[257,2338,2339,2341,2344,2346,2348,2350],{"class":291,"line":1030},[257,2340,626],{"class":415},[257,2342,2343],{"class":517}," plan_show",[257,2345,984],{"class":338},[257,2347,641],{"class":338},[257,2349,585],{"class":426},[257,2351,529],{"class":338},[257,2353,2354,2356],{"class":291,"line":1063},[257,2355,1144],{"class":1143},[257,2357,2358],{"class":1147},"Display the current plan with its step and postcondition status.\n",[257,2360,2361],{"class":291,"line":1068},[257,2362,321],{"emptyLinePlaceholder":320},[257,2364,2365],{"class":291,"line":1088},[257,2366,2367],{"class":1147},"        Use this any time you want to re-orient — especially after long\n",[257,2369,2370],{"class":291,"line":1115},[257,2371,2372],{"class":1147},"        sub-tasks or compaction. The plan is durable; compaction won't\n",[257,2374,2375],{"class":291,"line":1120},[257,2376,2377],{"class":1147},"        lose it.\n",[257,2379,2380],{"class":291,"line":1140},[257,2381,2141],{"class":1143},[257,2383,2384,2386,2389,2391,2394,2397,2400],{"class":291,"line":1154},[257,2385,652],{"class":302},[257,2387,2388],{"class":313}," holder",[257,2390,570],{"class":338},[257,2392,2393],{"class":815},"require",[257,2395,2396],{"class":338},"().",[257,2398,2399],{"class":815},"to_render",[257,2401,1112],{"class":338},[257,2403,2404],{"class":291,"line":1194},[257,2405,321],{"emptyLinePlaceholder":320},[257,2407,2408,2410,2412,2414,2416,2418,2420,2422,2424,2426],{"class":291,"line":1216},[257,2409,1996],{"class":513},[257,2411,1999],{"class":517},[257,2413,423],{"class":338},[257,2415,2004],{"class":821},[257,2417,445],{"class":444},[257,2419,1172],{"class":338},[257,2421,1188],{"class":448},[257,2423,2013],{"class":452},[257,2425,1188],{"class":448},[257,2427,2018],{"class":338},[257,2429,2430,2432,2435,2437,2440,2442,2445,2447,2450,2452,2454,2456,2459,2461,2463,2465,2468],{"class":291,"line":1254},[257,2431,626],{"class":415},[257,2433,2434],{"class":517}," step_update",[257,2436,423],{"class":338},[257,2438,2439],{"class":1968},"step_number",[257,2441,539],{"class":338},[257,2443,2444],{"class":426}," int",[257,2446,339],{"class":338},[257,2448,2449],{"class":1968}," status",[257,2451,539],{"class":338},[257,2453,585],{"class":426},[257,2455,339],{"class":338},[257,2457,2458],{"class":1968}," evidence",[257,2460,539],{"class":338},[257,2462,585],{"class":426},[257,2464,595],{"class":444},[257,2466,2467],{"class":448}," \"\"",[257,2469,1297],{"class":338},[257,2471,2472,2475,2477,2479,2481,2483,2485,2487,2489],{"class":291,"line":1300},[257,2473,2474],{"class":1968},"                     notes",[257,2476,539],{"class":338},[257,2478,585],{"class":426},[257,2480,595],{"class":444},[257,2482,2467],{"class":448},[257,2484,638],{"class":338},[257,2486,641],{"class":338},[257,2488,585],{"class":426},[257,2490,529],{"class":338},[257,2492,2493,2495],{"class":291,"line":1352},[257,2494,1144],{"class":1143},[257,2496,2497],{"class":1147},"Update a step's status.\n",[257,2499,2500],{"class":291,"line":1400},[257,2501,321],{"emptyLinePlaceholder":320},[257,2503,2504],{"class":291,"line":1416},[257,2505,2506],{"class":1147},"        step_number: 1-based index from `plan_show`.\n",[257,2508,2509],{"class":291,"line":1447},[257,2510,2511],{"class":1147},"        status: one of 'pending', 'in_progress', 'done', 'blocked'.\n",[257,2513,2514],{"class":291,"line":1461},[257,2515,2516],{"class":1147},"        evidence: required for 'done'. One-sentence proof of completion\n",[257,2518,2519],{"class":291,"line":1491},[257,2520,2521],{"class":1147},"                  (reference to a tool result, a scratchpad key, etc.).\n",[257,2523,2524],{"class":291,"line":1513},[257,2525,2526],{"class":1147},"        notes: optional free text.\n",[257,2528,2529],{"class":291,"line":1546},[257,2530,2141],{"class":1143},[257,2532,2533,2536,2538,2540,2542,2544],{"class":291,"line":1578},[257,2534,2535],{"class":313},"        plan ",[257,2537,445],{"class":444},[257,2539,2388],{"class":313},[257,2541,570],{"class":338},[257,2543,2393],{"class":815},[257,2545,1112],{"class":338},[257,2547,2548,2550,2553,2556,2559,2562,2564,2567,2570,2572,2574,2576,2578],{"class":291,"line":1621},[257,2549,1903],{"class":302},[257,2551,2552],{"class":313}," step_number ",[257,2554,2555],{"class":444},"\u003C",[257,2557,2558],{"class":1171}," 1",[257,2560,2561],{"class":444}," or",[257,2563,2552],{"class":313},[257,2565,2566],{"class":444},">",[257,2568,2569],{"class":535}," len",[257,2571,423],{"class":338},[257,2573,1910],{"class":815},[257,2575,570],{"class":338},[257,2577,1000],{"class":573},[257,2579,435],{"class":338},[257,2581,2582,2585,2587,2590,2592,2594,2596,2599,2601,2603,2605,2607,2609,2611,2613,2615],{"class":291,"line":1634},[257,2583,2584],{"class":302},"            return",[257,2586,2275],{"class":415},[257,2588,2589],{"class":452},"\"step_number ",[257,2591,1172],{"class":1171},[257,2593,2439],{"class":313},[257,2595,1182],{"class":1171},[257,2597,2598],{"class":452}," out of range (1..",[257,2600,1172],{"class":1171},[257,2602,2283],{"class":535},[257,2604,423],{"class":338},[257,2606,1910],{"class":815},[257,2608,570],{"class":338},[257,2610,1000],{"class":573},[257,2612,638],{"class":338},[257,2614,1182],{"class":1171},[257,2616,2617],{"class":452},")\"\n",[257,2619,2620,2623],{"class":291,"line":1663},[257,2621,2622],{"class":302},"        try",[257,2624,529],{"class":338},[257,2626,2628,2631,2633,2635,2637,2639],{"class":291,"line":2627},73,[257,2629,2630],{"class":313},"            new_status ",[257,2632,445],{"class":444},[257,2634,420],{"class":815},[257,2636,423],{"class":338},[257,2638,660],{"class":815},[257,2640,684],{"class":338},[257,2642,2644,2647,2650],{"class":291,"line":2643},74,[257,2645,2646],{"class":302},"        except",[257,2648,2649],{"class":426}," ValueError",[257,2651,529],{"class":338},[257,2653,2655,2657,2659,2662,2664,2666,2669,2671],{"class":291,"line":2654},75,[257,2656,2584],{"class":302},[257,2658,2275],{"class":415},[257,2660,2661],{"class":452},"\"invalid status ",[257,2663,1172],{"class":1171},[257,2665,660],{"class":313},[257,2667,2668],{"class":415},"!r",[257,2670,1182],{"class":1171},[257,2672,2673],{"class":452},"; use pending\u002Fin_progress\u002Fdone\u002Fblocked\"\n",[257,2675,2677,2679,2682,2685,2687,2689,2691,2693,2696,2698],{"class":291,"line":2676},76,[257,2678,1903],{"class":302},[257,2680,2681],{"class":313}," new_status ",[257,2683,2684],{"class":444},"==",[257,2686,420],{"class":313},[257,2688,570],{"class":338},[257,2690,230],{"class":573},[257,2692,1102],{"class":444},[257,2694,2695],{"class":444}," not",[257,2697,2458],{"class":313},[257,2699,529],{"class":338},[257,2701,2703,2705,2707,2709,2712],{"class":291,"line":2702},77,[257,2704,2584],{"class":302},[257,2706,666],{"class":338},[257,2708,1188],{"class":448},[257,2710,2711],{"class":452},"error: marking a step 'done' requires evidence. Describe ",[257,2713,455],{"class":448},[257,2715,2717,2719,2722],{"class":291,"line":2716},78,[257,2718,1303],{"class":448},[257,2720,2721],{"class":452},"what proved the step complete (e.g., 'wrote file and ",[257,2723,455],{"class":448},[257,2725,2727,2729,2732,2734],{"class":291,"line":2726},79,[257,2728,1303],{"class":448},[257,2730,2731],{"class":452},"read it back; content matches').",[257,2733,1188],{"class":448},[257,2735,684],{"class":338},[257,2737,2739,2742,2744,2747,2749,2751,2753,2756,2759,2761],{"class":291,"line":2738},80,[257,2740,2741],{"class":313},"        s ",[257,2743,445],{"class":444},[257,2745,2746],{"class":313}," plan",[257,2748,570],{"class":338},[257,2750,1000],{"class":573},[257,2752,804],{"class":338},[257,2754,2755],{"class":573},"step_number ",[257,2757,2758],{"class":444},"-",[257,2760,2558],{"class":1171},[257,2762,1191],{"class":338},[257,2764,2766,2769,2771,2773,2775,2777,2779,2781,2783,2785,2787],{"class":291,"line":2765},81,[257,2767,2768],{"class":313},"        plan",[257,2770,570],{"class":338},[257,2772,1000],{"class":573},[257,2774,804],{"class":338},[257,2776,2755],{"class":573},[257,2778,2758],{"class":444},[257,2780,2558],{"class":1171},[257,2782,810],{"class":338},[257,2784,595],{"class":444},[257,2786,526],{"class":815},[257,2788,2157],{"class":338},[257,2790,2792,2795,2797,2799,2801,2803,2805,2807,2809,2811,2813,2815],{"class":291,"line":2791},82,[257,2793,2794],{"class":821},"            id",[257,2796,445],{"class":444},[257,2798,976],{"class":815},[257,2800,570],{"class":338},[257,2802,2184],{"class":573},[257,2804,339],{"class":338},[257,2806,2204],{"class":821},[257,2808,445],{"class":444},[257,2810,976],{"class":815},[257,2812,570],{"class":338},[257,2814,1391],{"class":573},[257,2816,1297],{"class":338},[257,2818,2820,2823,2825,2828,2830,2832,2834,2837,2840,2842],{"class":291,"line":2819},83,[257,2821,2822],{"class":821},"            status",[257,2824,445],{"class":444},[257,2826,2827],{"class":815},"new_status",[257,2829,339],{"class":338},[257,2831,2458],{"class":821},[257,2833,445],{"class":444},[257,2835,2836],{"class":815},"evidence ",[257,2838,2839],{"class":302},"or",[257,2841,592],{"class":591},[257,2843,1297],{"class":338},[257,2845,2847,2850,2852,2854],{"class":291,"line":2846},84,[257,2848,2849],{"class":821},"            notes",[257,2851,445],{"class":444},[257,2853,1456],{"class":815},[257,2855,1297],{"class":338},[257,2857,2859],{"class":291,"line":2858},85,[257,2860,2268],{"class":338},[257,2862,2864,2866,2868,2871,2873,2875,2877,2880,2882,2884,2886],{"class":291,"line":2863},86,[257,2865,652],{"class":302},[257,2867,2275],{"class":415},[257,2869,2870],{"class":452},"\"step ",[257,2872,1172],{"class":1171},[257,2874,2439],{"class":313},[257,2876,1182],{"class":1171},[257,2878,2879],{"class":452}," → ",[257,2881,1172],{"class":1171},[257,2883,660],{"class":313},[257,2885,1182],{"class":1171},[257,2887,455],{"class":452},[257,2889,2891],{"class":291,"line":2890},87,[257,2892,321],{"emptyLinePlaceholder":320},[257,2894,2896,2898,2900,2902,2904,2906,2908,2910,2912,2914],{"class":291,"line":2895},88,[257,2897,1996],{"class":513},[257,2899,1999],{"class":517},[257,2901,423],{"class":338},[257,2903,2004],{"class":821},[257,2905,445],{"class":444},[257,2907,1172],{"class":338},[257,2909,1188],{"class":448},[257,2911,2013],{"class":452},[257,2913,1188],{"class":448},[257,2915,2018],{"class":338},[257,2917,2919,2921,2924,2926,2929,2931,2933,2935,2937,2939,2941,2943,2945,2947],{"class":291,"line":2918},89,[257,2920,626],{"class":415},[257,2922,2923],{"class":517}," postcondition_verify",[257,2925,423],{"class":338},[257,2927,2928],{"class":1968},"postcondition_number",[257,2930,539],{"class":338},[257,2932,2444],{"class":426},[257,2934,339],{"class":338},[257,2936,2458],{"class":1968},[257,2938,539],{"class":338},[257,2940,585],{"class":426},[257,2942,638],{"class":338},[257,2944,641],{"class":338},[257,2946,585],{"class":426},[257,2948,529],{"class":338},[257,2950,2952,2954],{"class":291,"line":2951},90,[257,2953,1144],{"class":1143},[257,2955,2956],{"class":1147},"Mark a postcondition as verified.\n",[257,2958,2960],{"class":291,"line":2959},91,[257,2961,321],{"emptyLinePlaceholder":320},[257,2963,2965],{"class":291,"line":2964},92,[257,2966,2967],{"class":1147},"        postcondition_number: 1-based index.\n",[257,2969,2971],{"class":291,"line":2970},93,[257,2972,2973],{"class":1147},"        evidence: required. Concrete proof the postcondition holds.\n",[257,2975,2977],{"class":291,"line":2976},94,[257,2978,321],{"emptyLinePlaceholder":320},[257,2980,2982],{"class":291,"line":2981},95,[257,2983,2984],{"class":1147},"        This is what the harness checks before letting you declare the\n",[257,2986,2988],{"class":291,"line":2987},96,[257,2989,2990],{"class":1147},"        task complete. Do not verify a postcondition without evidence.\n",[257,2992,2994],{"class":291,"line":2993},97,[257,2995,2141],{"class":1143},[257,2997,2999,3001,3003,3005,3007,3009],{"class":291,"line":2998},98,[257,3000,2535],{"class":313},[257,3002,445],{"class":444},[257,3004,2388],{"class":313},[257,3006,570],{"class":338},[257,3008,2393],{"class":815},[257,3010,1112],{"class":338},[257,3012,3014,3016,3019,3021,3023,3025,3027,3029,3031,3033,3035,3037,3039],{"class":291,"line":3013},99,[257,3015,1903],{"class":302},[257,3017,3018],{"class":313}," postcondition_number ",[257,3020,2555],{"class":444},[257,3022,2558],{"class":1171},[257,3024,2561],{"class":444},[257,3026,3018],{"class":313},[257,3028,2566],{"class":444},[257,3030,2569],{"class":535},[257,3032,423],{"class":338},[257,3034,1910],{"class":815},[257,3036,570],{"class":338},[257,3038,1058],{"class":573},[257,3040,435],{"class":338},[257,3042,3044,3046,3048,3050,3053,3055,3057,3059],{"class":291,"line":3043},100,[257,3045,2584],{"class":302},[257,3047,666],{"class":338},[257,3049,1165],{"class":415},[257,3051,3052],{"class":452},"\"postcondition_number ",[257,3054,1172],{"class":1171},[257,3056,2928],{"class":313},[257,3058,1182],{"class":1171},[257,3060,3061],{"class":452}," out of range \"\n",[257,3063,3065,3068,3071,3073,3075,3077,3079,3081,3083,3085,3087,3090],{"class":291,"line":3064},101,[257,3066,3067],{"class":415},"                    f",[257,3069,3070],{"class":452},"\"(1..",[257,3072,1172],{"class":1171},[257,3074,2283],{"class":535},[257,3076,423],{"class":338},[257,3078,1910],{"class":815},[257,3080,570],{"class":338},[257,3082,1058],{"class":573},[257,3084,638],{"class":338},[257,3086,1182],{"class":1171},[257,3088,3089],{"class":452},")\"",[257,3091,684],{"class":338},[257,3093,3095,3097,3099,3101],{"class":291,"line":3094},102,[257,3096,1903],{"class":302},[257,3098,2695],{"class":444},[257,3100,2458],{"class":313},[257,3102,529],{"class":338},[257,3104,3106,3108,3110,3113],{"class":291,"line":3105},103,[257,3107,2584],{"class":302},[257,3109,449],{"class":448},[257,3111,3112],{"class":452},"error: evidence is required to verify a postcondition",[257,3114,455],{"class":448},[257,3116,3118,3121,3123,3125,3127,3129,3131,3134,3136,3138],{"class":291,"line":3117},104,[257,3119,3120],{"class":313},"        pc ",[257,3122,445],{"class":444},[257,3124,2746],{"class":313},[257,3126,570],{"class":338},[257,3128,1058],{"class":573},[257,3130,804],{"class":338},[257,3132,3133],{"class":573},"postcondition_number ",[257,3135,2758],{"class":444},[257,3137,2558],{"class":1171},[257,3139,1191],{"class":338},[257,3141,3143,3145,3147,3149,3151,3153,3155,3157,3159,3161,3163],{"class":291,"line":3142},105,[257,3144,2768],{"class":313},[257,3146,570],{"class":338},[257,3148,1058],{"class":573},[257,3150,804],{"class":338},[257,3152,3133],{"class":573},[257,3154,2758],{"class":444},[257,3156,2558],{"class":1171},[257,3158,810],{"class":338},[257,3160,595],{"class":444},[257,3162,709],{"class":815},[257,3164,2157],{"class":338},[257,3166,3168,3171,3173,3175,3177,3179,3181,3184,3186,3189,3191,3193,3195,3197],{"class":291,"line":3167},106,[257,3169,3170],{"class":821},"            description",[257,3172,445],{"class":444},[257,3174,1039],{"class":815},[257,3176,570],{"class":338},[257,3178,1391],{"class":573},[257,3180,339],{"class":338},[257,3182,3183],{"class":821}," satisfied",[257,3185,445],{"class":444},[257,3187,3188],{"class":591},"True",[257,3190,339],{"class":338},[257,3192,2458],{"class":821},[257,3194,445],{"class":444},[257,3196,1411],{"class":815},[257,3198,1297],{"class":338},[257,3200,3202],{"class":291,"line":3201},107,[257,3203,2268],{"class":338},[257,3205,3207,3209,3211,3214,3216,3218,3220],{"class":291,"line":3206},108,[257,3208,652],{"class":302},[257,3210,2275],{"class":415},[257,3212,3213],{"class":452},"\"postcondition ",[257,3215,1172],{"class":1171},[257,3217,2928],{"class":313},[257,3219,1182],{"class":1171},[257,3221,3222],{"class":452}," verified\"\n",[257,3224,3226],{"class":291,"line":3225},109,[257,3227,321],{"emptyLinePlaceholder":320},[257,3229,3231,3234,3236,3239,3241,3243,3245,3247,3249,3251],{"class":291,"line":3230},110,[257,3232,3233],{"class":302},"    return",[257,3235,1162],{"class":338},[257,3237,3238],{"class":313},"plan_create",[257,3240,339],{"class":338},[257,3242,2343],{"class":313},[257,3244,339],{"class":338},[257,3246,2434],{"class":313},[257,3248,339],{"class":338},[257,3250,2923],{"class":313},[257,3252,1191],{"class":338},[112,3254,3255],{},"Three points of discipline enforced at the tool level.",[112,3257,3258,3267,3268,3271],{},[124,3259,3260,3261,3263,3264,570],{},"Evidence is mandatory for ",[142,3262,230],{}," and ",[142,3265,3266],{},"verified"," If the model calls ",[142,3269,3270],{},"step_update(step_number=3, status=\"done\")"," without evidence, the tool returns an error explaining why. The model has to come back with a non-empty evidence string. This isn't security; it's a habit trainer. Evidence-producing models produce better evidence everywhere.",[112,3273,3274,3277,3278,3280],{},[124,3275,3276],{},"Plan rewriting is allowed, not hidden."," A mid-task plan rewrite is a legitimate move; circumstances change. What we don't want is the model silently drifting from the old plan. Calling ",[142,3279,3238],{}," again replaces the plan — and Chapter 18's observability will log it, so you can see whether rewriting is happening too often (a sign the initial planning is weak).",[112,3282,3283,3289],{},[124,3284,3285,3288],{},[142,3286,3287],{},"plan_show"," is read-only and cheap."," It's the first tool the agent should call after compaction or any long tool sequence, as a re-orientation. The system prompt should explicitly teach this.",[273,3291],{},[276,3293,3295],{"id":3294},"_163-harness-enforcement-of-completion","16.3 Harness Enforcement of Completion",[112,3297,3298],{},"The loop checks the plan before accepting a final answer.",[281,3300,3302],{"className":283,"code":3301,"language":285,"meta":286,"style":286},"# src\u002Fharness\u002Fagent.py (plan-aware version, sketch)\n\nasync def arun(\n    provider: Provider,\n    catalog: ToolCatalog,\n    user_message: str,\n    system: str | None = None,\n    # ...\n    plan_holder: \"PlanHolder | None\" = None,\n) -> str:\n    # ... existing setup\n\n    for _ in range(MAX_ITERATIONS):\n        # ... existing tool selection, compaction, turn execution\n\n        if response.is_final:\n            final_text = response.text or \"\"\n            if plan_holder and plan_holder.plan:\n                plan = plan_holder.plan\n                if not plan.is_ready_to_finalize():\n                    # reject the finalization; ask the agent to continue\n                    synthetic = (\n                        \"The plan is not complete. Before declaring the \"\n                        \"task done, either mark remaining steps as done \"\n                        \"with evidence, verify outstanding postconditions, \"\n                        \"or mark them blocked with a reason. Current plan:\\n\\n\"\n                        + plan.to_render()\n                    )\n                    transcript.append(Message.from_assistant_response(response))\n                    transcript.append(Message.user_text(synthetic))\n                    continue\n            transcript.append(Message.from_assistant_response(response))\n            return final_text\n\n        # ... existing tool dispatch\n",[142,3303,3304,3309,3313,3326,3338,3350,3361,3380,3385,3405,3415,3420,3424,3444,3449,3453,3467,3485,3504,3517,3534,3539,3549,3559,3568,3577,3589,3602,3607,3633,3657,3662,3685,3692,3696],{"__ignoreMap":286},[257,3305,3306],{"class":291,"line":292},[257,3307,3308],{"class":295},"# src\u002Fharness\u002Fagent.py (plan-aware version, sketch)\n",[257,3310,3311],{"class":291,"line":299},[257,3312,321],{"emptyLinePlaceholder":320},[257,3314,3315,3318,3321,3324],{"class":291,"line":317},[257,3316,3317],{"class":415},"async",[257,3319,3320],{"class":415}," def",[257,3322,3323],{"class":517}," arun",[257,3325,2157],{"class":338},[257,3327,3328,3331,3333,3336],{"class":291,"line":324},[257,3329,3330],{"class":1968},"    provider",[257,3332,539],{"class":338},[257,3334,3335],{"class":313}," Provider",[257,3337,1297],{"class":338},[257,3339,3340,3343,3345,3348],{"class":291,"line":345},[257,3341,3342],{"class":1968},"    catalog",[257,3344,539],{"class":338},[257,3346,3347],{"class":313}," ToolCatalog",[257,3349,1297],{"class":338},[257,3351,3352,3355,3357,3359],{"class":291,"line":363},[257,3353,3354],{"class":1968},"    user_message",[257,3356,539],{"class":338},[257,3358,585],{"class":426},[257,3360,1297],{"class":338},[257,3362,3363,3366,3368,3370,3372,3374,3376,3378],{"class":291,"line":376},[257,3364,3365],{"class":1968},"    system",[257,3367,539],{"class":338},[257,3369,585],{"class":426},[257,3371,588],{"class":444},[257,3373,592],{"class":591},[257,3375,595],{"class":444},[257,3377,592],{"class":591},[257,3379,1297],{"class":338},[257,3381,3382],{"class":291,"line":389},[257,3383,3384],{"class":295},"    # ...\n",[257,3386,3387,3390,3392,3394,3397,3399,3401,3403],{"class":291,"line":402},[257,3388,3389],{"class":1968},"    plan_holder",[257,3391,539],{"class":338},[257,3393,449],{"class":448},[257,3395,3396],{"class":452},"PlanHolder | None",[257,3398,1188],{"class":448},[257,3400,595],{"class":444},[257,3402,592],{"class":591},[257,3404,1297],{"class":338},[257,3406,3407,3409,3411,3413],{"class":291,"line":407},[257,3408,638],{"class":338},[257,3410,641],{"class":338},[257,3412,585],{"class":426},[257,3414,529],{"class":338},[257,3416,3417],{"class":291,"line":412},[257,3418,3419],{"class":295},"    # ... existing setup\n",[257,3421,3422],{"class":291,"line":438},[257,3423,321],{"emptyLinePlaceholder":320},[257,3425,3426,3429,3432,3434,3437,3439,3442],{"class":291,"line":458},[257,3427,3428],{"class":302},"    for",[257,3430,3431],{"class":313}," _ ",[257,3433,993],{"class":302},[257,3435,3436],{"class":535}," range",[257,3438,423],{"class":338},[257,3440,3441],{"class":535},"MAX_ITERATIONS",[257,3443,435],{"class":338},[257,3445,3446],{"class":291,"line":472},[257,3447,3448],{"class":295},"        # ... existing tool selection, compaction, turn execution\n",[257,3450,3451],{"class":291,"line":486},[257,3452,321],{"emptyLinePlaceholder":320},[257,3454,3455,3457,3460,3462,3465],{"class":291,"line":500},[257,3456,1903],{"class":302},[257,3458,3459],{"class":313}," response",[257,3461,570],{"class":338},[257,3463,3464],{"class":573},"is_final",[257,3466,529],{"class":338},[257,3468,3469,3472,3474,3476,3478,3481,3483],{"class":291,"line":505},[257,3470,3471],{"class":313},"            final_text ",[257,3473,445],{"class":444},[257,3475,3459],{"class":313},[257,3477,570],{"class":338},[257,3479,3480],{"class":573},"text",[257,3482,2561],{"class":444},[257,3484,615],{"class":448},[257,3486,3487,3489,3492,3495,3498,3500,3502],{"class":291,"line":510},[257,3488,1403],{"class":302},[257,3490,3491],{"class":313}," plan_holder ",[257,3493,3494],{"class":444},"and",[257,3496,3497],{"class":313}," plan_holder",[257,3499,570],{"class":338},[257,3501,1910],{"class":573},[257,3503,529],{"class":338},[257,3505,3506,3509,3511,3513,3515],{"class":291,"line":521},[257,3507,3508],{"class":313},"                plan ",[257,3510,445],{"class":444},[257,3512,3497],{"class":313},[257,3514,570],{"class":338},[257,3516,1947],{"class":573},[257,3518,3519,3522,3524,3526,3528,3531],{"class":291,"line":532},[257,3520,3521],{"class":302},"                if",[257,3523,2695],{"class":444},[257,3525,2746],{"class":313},[257,3527,570],{"class":338},[257,3529,3530],{"class":815},"is_ready_to_finalize",[257,3532,3533],{"class":338},"():\n",[257,3535,3536],{"class":291,"line":545},[257,3537,3538],{"class":295},"                    # reject the finalization; ask the agent to continue\n",[257,3540,3541,3544,3546],{"class":291,"line":555},[257,3542,3543],{"class":313},"                    synthetic ",[257,3545,445],{"class":444},[257,3547,3548],{"class":338}," (\n",[257,3550,3551,3554,3557],{"class":291,"line":577},[257,3552,3553],{"class":448},"                        \"",[257,3555,3556],{"class":452},"The plan is not complete. Before declaring the ",[257,3558,455],{"class":448},[257,3560,3561,3563,3566],{"class":291,"line":603},[257,3562,3553],{"class":448},[257,3564,3565],{"class":452},"task done, either mark remaining steps as done ",[257,3567,455],{"class":448},[257,3569,3570,3572,3575],{"class":291,"line":618},[257,3571,3553],{"class":448},[257,3573,3574],{"class":452},"with evidence, verify outstanding postconditions, ",[257,3576,455],{"class":448},[257,3578,3579,3581,3584,3587],{"class":291,"line":623},[257,3580,3553],{"class":448},[257,3582,3583],{"class":452},"or mark them blocked with a reason. Current plan:",[257,3585,3586],{"class":306},"\\n\\n",[257,3588,455],{"class":448},[257,3590,3591,3594,3596,3598,3600],{"class":291,"line":649},[257,3592,3593],{"class":444},"                        +",[257,3595,2746],{"class":313},[257,3597,570],{"class":338},[257,3599,2399],{"class":815},[257,3601,1112],{"class":338},[257,3603,3604],{"class":291,"line":687},[257,3605,3606],{"class":338},"                    )\n",[257,3608,3609,3612,3614,3616,3618,3621,3623,3626,3628,3631],{"class":291,"line":692},[257,3610,3611],{"class":313},"                    transcript",[257,3613,570],{"class":338},[257,3615,1202],{"class":815},[257,3617,423],{"class":338},[257,3619,3620],{"class":815},"Message",[257,3622,570],{"class":338},[257,3624,3625],{"class":815},"from_assistant_response",[257,3627,423],{"class":338},[257,3629,3630],{"class":815},"response",[257,3632,905],{"class":338},[257,3634,3635,3637,3639,3641,3643,3645,3647,3650,3652,3655],{"class":291,"line":697},[257,3636,3611],{"class":313},[257,3638,570],{"class":338},[257,3640,1202],{"class":815},[257,3642,423],{"class":338},[257,3644,3620],{"class":815},[257,3646,570],{"class":338},[257,3648,3649],{"class":815},"user_text",[257,3651,423],{"class":338},[257,3653,3654],{"class":815},"synthetic",[257,3656,905],{"class":338},[257,3658,3659],{"class":291,"line":704},[257,3660,3661],{"class":302},"                    continue\n",[257,3663,3664,3667,3669,3671,3673,3675,3677,3679,3681,3683],{"class":291,"line":714},[257,3665,3666],{"class":313},"            transcript",[257,3668,570],{"class":338},[257,3670,1202],{"class":815},[257,3672,423],{"class":338},[257,3674,3620],{"class":815},[257,3676,570],{"class":338},[257,3678,3625],{"class":815},[257,3680,423],{"class":338},[257,3682,3630],{"class":815},[257,3684,905],{"class":338},[257,3686,3687,3689],{"class":291,"line":723},[257,3688,2584],{"class":302},[257,3690,3691],{"class":313}," final_text\n",[257,3693,3694],{"class":291,"line":738},[257,3695,321],{"emptyLinePlaceholder":320},[257,3697,3698],{"class":291,"line":756},[257,3699,3700],{"class":295},"        # ... existing tool dispatch\n",[112,3702,3703],{},"The logic: when the model produces what it thinks is a final answer, and a plan is attached, the harness checks the plan. If every step is terminal (done or blocked) and every postcondition is satisfied, accept. Otherwise, append the model's attempted final answer to the transcript, append a synthetic user message explaining what's missing, and continue the loop.",[112,3705,3706],{},"This is the specific intervention that kills premature finalization. The model says \"all done\"; the harness says \"no, you haven't marked step 3 done and postcondition 2 isn't verified — here's the current state.\" The model either finishes properly or explicitly marks the missing work as blocked with a reason.",[112,3708,3709,3712],{},[124,3710,3711],{},"Why not just enforce during step_update?"," Because \"done\" is about a specific step, not the whole plan. A step can be legitimately done while the overall plan isn't. The completion check has to happen at finalization, not at each step update.",[273,3714],{},[276,3716,3718],{"id":3717},"_164-a-scenario-that-catches-premature-finalization","16.4 A Scenario That Catches Premature Finalization",[281,3720,3722],{"className":283,"code":3721,"language":285,"meta":286,"style":286},"# examples\u002Fch16_plan.py\nimport asyncio\n\nfrom harness.agent import arun\nfrom harness.plans.tools import PlanHolder, plan_tools\nfrom harness.providers.anthropic import AnthropicProvider\nfrom harness.tools.selector import ToolCatalog\nfrom harness.tools.std import STANDARD_TOOLS\n\n\nSYSTEM = \"\"\"\\\nYou are an agent that works from structured plans. For any non-trivial\ntask, your first action is to call plan_create with an explicit objective,\nsteps, and postconditions. After each major action, call step_update to\nrecord progress with evidence. Before declaring the task complete, verify\nevery postcondition with postcondition_verify.\n\nThe harness will reject your final answer if the plan is not complete.\nDo not claim completion prematurely. If a step cannot be completed, mark\nit 'blocked' with a reason rather than skipping it.\n\"\"\"\n\n\nasync def main() -> None:\n    provider = AnthropicProvider()\n    holder = PlanHolder()\n    catalog = ToolCatalog(tools=STANDARD_TOOLS + plan_tools(holder))\n\n    answer = await arun(\n        provider=provider,\n        catalog=catalog,\n        system=SYSTEM,\n        plan_holder=holder,\n        user_message=(\n            \"For each of these three files, verify they exist, measure \"\n            \"their size in bytes, and report the largest one: \"\n            \"\u002Fetc\u002Fhostname, \u002Fetc\u002Fos-release, \u002Fetc\u002Fmachine-id. \"\n            \"Produce a summary with file paths, sizes, and the winner.\"\n        ),\n    )\n    print(\"---\")\n    print(answer)\n    print(\"---\")\n    print(holder.plan.to_render() if holder.plan else \"(no plan)\")\n\n\nasyncio.run(main())\n",[142,3723,3724,3729,3736,3740,3757,3782,3803,3823,3843,3847,3851,3864,3869,3874,3879,3884,3889,3893,3898,3903,3908,3912,3916,3920,3937,3949,3960,3989,3993,4007,4019,4031,4042,4053,4062,4072,4081,4090,4099,4104,4109,4125,4136,4150,4187,4191,4195],{"__ignoreMap":286},[257,3725,3726],{"class":291,"line":292},[257,3727,3728],{"class":295},"# examples\u002Fch16_plan.py\n",[257,3730,3731,3733],{"class":291,"line":299},[257,3732,332],{"class":302},[257,3734,3735],{"class":313}," asyncio\n",[257,3737,3738],{"class":291,"line":317},[257,3739,321],{"emptyLinePlaceholder":320},[257,3741,3742,3744,3747,3749,3752,3754],{"class":291,"line":324},[257,3743,303],{"class":302},[257,3745,3746],{"class":313}," harness",[257,3748,570],{"class":338},[257,3750,3751],{"class":313},"agent ",[257,3753,332],{"class":302},[257,3755,3756],{"class":313}," arun\n",[257,3758,3759,3761,3763,3765,3768,3770,3773,3775,3777,3779],{"class":291,"line":345},[257,3760,303],{"class":302},[257,3762,3746],{"class":313},[257,3764,570],{"class":338},[257,3766,3767],{"class":313},"plans",[257,3769,570],{"class":338},[257,3771,3772],{"class":313},"tools ",[257,3774,332],{"class":302},[257,3776,1844],{"class":313},[257,3778,339],{"class":338},[257,3780,3781],{"class":313}," plan_tools\n",[257,3783,3784,3786,3788,3790,3793,3795,3798,3800],{"class":291,"line":363},[257,3785,303],{"class":302},[257,3787,3746],{"class":313},[257,3789,570],{"class":338},[257,3791,3792],{"class":313},"providers",[257,3794,570],{"class":338},[257,3796,3797],{"class":313},"anthropic ",[257,3799,332],{"class":302},[257,3801,3802],{"class":313}," AnthropicProvider\n",[257,3804,3805,3807,3809,3811,3813,3815,3818,3820],{"class":291,"line":376},[257,3806,303],{"class":302},[257,3808,3746],{"class":313},[257,3810,570],{"class":338},[257,3812,1768],{"class":313},[257,3814,570],{"class":338},[257,3816,3817],{"class":313},"selector ",[257,3819,332],{"class":302},[257,3821,3822],{"class":313}," ToolCatalog\n",[257,3824,3825,3827,3829,3831,3833,3835,3838,3840],{"class":291,"line":389},[257,3826,303],{"class":302},[257,3828,3746],{"class":313},[257,3830,570],{"class":338},[257,3832,1768],{"class":313},[257,3834,570],{"class":338},[257,3836,3837],{"class":313},"std ",[257,3839,332],{"class":302},[257,3841,3842],{"class":306}," STANDARD_TOOLS\n",[257,3844,3845],{"class":291,"line":402},[257,3846,321],{"emptyLinePlaceholder":320},[257,3848,3849],{"class":291,"line":407},[257,3850,321],{"emptyLinePlaceholder":320},[257,3852,3853,3856,3858,3861],{"class":291,"line":412},[257,3854,3855],{"class":306},"SYSTEM",[257,3857,595],{"class":444},[257,3859,3860],{"class":448}," \"\"\"",[257,3862,3863],{"class":591},"\\\n",[257,3865,3866],{"class":291,"line":438},[257,3867,3868],{"class":452},"You are an agent that works from structured plans. For any non-trivial\n",[257,3870,3871],{"class":291,"line":458},[257,3872,3873],{"class":452},"task, your first action is to call plan_create with an explicit objective,\n",[257,3875,3876],{"class":291,"line":472},[257,3877,3878],{"class":452},"steps, and postconditions. After each major action, call step_update to\n",[257,3880,3881],{"class":291,"line":486},[257,3882,3883],{"class":452},"record progress with evidence. Before declaring the task complete, verify\n",[257,3885,3886],{"class":291,"line":500},[257,3887,3888],{"class":452},"every postcondition with postcondition_verify.\n",[257,3890,3891],{"class":291,"line":505},[257,3892,321],{"emptyLinePlaceholder":320},[257,3894,3895],{"class":291,"line":510},[257,3896,3897],{"class":452},"The harness will reject your final answer if the plan is not complete.\n",[257,3899,3900],{"class":291,"line":521},[257,3901,3902],{"class":452},"Do not claim completion prematurely. If a step cannot be completed, mark\n",[257,3904,3905],{"class":291,"line":532},[257,3906,3907],{"class":452},"it 'blocked' with a reason rather than skipping it.\n",[257,3909,3910],{"class":291,"line":545},[257,3911,1151],{"class":448},[257,3913,3914],{"class":291,"line":555},[257,3915,321],{"emptyLinePlaceholder":320},[257,3917,3918],{"class":291,"line":577},[257,3919,321],{"emptyLinePlaceholder":320},[257,3921,3922,3924,3926,3929,3931,3933,3935],{"class":291,"line":603},[257,3923,3317],{"class":415},[257,3925,3320],{"class":415},[257,3927,3928],{"class":517}," main",[257,3930,984],{"class":338},[257,3932,641],{"class":338},[257,3934,592],{"class":591},[257,3936,529],{"class":338},[257,3938,3939,3942,3944,3947],{"class":291,"line":618},[257,3940,3941],{"class":313},"    provider ",[257,3943,445],{"class":444},[257,3945,3946],{"class":815}," AnthropicProvider",[257,3948,1112],{"class":338},[257,3950,3951,3954,3956,3958],{"class":291,"line":623},[257,3952,3953],{"class":313},"    holder ",[257,3955,445],{"class":444},[257,3957,1844],{"class":815},[257,3959,1112],{"class":338},[257,3961,3962,3965,3967,3969,3971,3973,3975,3978,3981,3983,3985,3987],{"class":291,"line":649},[257,3963,3964],{"class":313},"    catalog ",[257,3966,445],{"class":444},[257,3968,3347],{"class":815},[257,3970,423],{"class":338},[257,3972,1768],{"class":821},[257,3974,445],{"class":444},[257,3976,3977],{"class":535},"STANDARD_TOOLS",[257,3979,3980],{"class":444}," +",[257,3982,1963],{"class":815},[257,3984,423],{"class":338},[257,3986,1969],{"class":815},[257,3988,905],{"class":338},[257,3990,3991],{"class":291,"line":687},[257,3992,321],{"emptyLinePlaceholder":320},[257,3994,3995,3998,4000,4003,4005],{"class":291,"line":692},[257,3996,3997],{"class":313},"    answer ",[257,3999,445],{"class":444},[257,4001,4002],{"class":302}," await",[257,4004,3323],{"class":815},[257,4006,2157],{"class":338},[257,4008,4009,4012,4014,4017],{"class":291,"line":697},[257,4010,4011],{"class":821},"        provider",[257,4013,445],{"class":444},[257,4015,4016],{"class":815},"provider",[257,4018,1297],{"class":338},[257,4020,4021,4024,4026,4029],{"class":291,"line":704},[257,4022,4023],{"class":821},"        catalog",[257,4025,445],{"class":444},[257,4027,4028],{"class":815},"catalog",[257,4030,1297],{"class":338},[257,4032,4033,4036,4038,4040],{"class":291,"line":714},[257,4034,4035],{"class":821},"        system",[257,4037,445],{"class":444},[257,4039,3855],{"class":535},[257,4041,1297],{"class":338},[257,4043,4044,4047,4049,4051],{"class":291,"line":723},[257,4045,4046],{"class":821},"        plan_holder",[257,4048,445],{"class":444},[257,4050,1969],{"class":815},[257,4052,1297],{"class":338},[257,4054,4055,4058,4060],{"class":291,"line":738},[257,4056,4057],{"class":821},"        user_message",[257,4059,445],{"class":444},[257,4061,2157],{"class":338},[257,4063,4064,4067,4070],{"class":291,"line":756},[257,4065,4066],{"class":448},"            \"",[257,4068,4069],{"class":452},"For each of these three files, verify they exist, measure ",[257,4071,455],{"class":448},[257,4073,4074,4076,4079],{"class":291,"line":761},[257,4075,4066],{"class":448},[257,4077,4078],{"class":452},"their size in bytes, and report the largest one: ",[257,4080,455],{"class":448},[257,4082,4083,4085,4088],{"class":291,"line":766},[257,4084,4066],{"class":448},[257,4086,4087],{"class":452},"\u002Fetc\u002Fhostname, \u002Fetc\u002Fos-release, \u002Fetc\u002Fmachine-id. ",[257,4089,455],{"class":448},[257,4091,4092,4094,4097],{"class":291,"line":773},[257,4093,4066],{"class":448},[257,4095,4096],{"class":452},"Produce a summary with file paths, sizes, and the winner.",[257,4098,455],{"class":448},[257,4100,4101],{"class":291,"line":783},[257,4102,4103],{"class":338},"        ),\n",[257,4105,4106],{"class":291,"line":793},[257,4107,4108],{"class":338},"    )\n",[257,4110,4111,4114,4116,4118,4121,4123],{"class":291,"line":832},[257,4112,4113],{"class":535},"    print",[257,4115,423],{"class":338},[257,4117,1188],{"class":448},[257,4119,4120],{"class":452},"---",[257,4122,1188],{"class":448},[257,4124,684],{"class":338},[257,4126,4127,4129,4131,4134],{"class":291,"line":863},[257,4128,4113],{"class":535},[257,4130,423],{"class":338},[257,4132,4133],{"class":815},"answer",[257,4135,684],{"class":338},[257,4137,4138,4140,4142,4144,4146,4148],{"class":291,"line":908},[257,4139,4113],{"class":535},[257,4141,423],{"class":338},[257,4143,1188],{"class":448},[257,4145,4120],{"class":452},[257,4147,1188],{"class":448},[257,4149,684],{"class":338},[257,4151,4152,4154,4156,4158,4160,4162,4164,4166,4168,4170,4172,4174,4176,4178,4180,4183,4185],{"class":291,"line":941},[257,4153,4113],{"class":535},[257,4155,423],{"class":338},[257,4157,1969],{"class":815},[257,4159,570],{"class":338},[257,4161,1910],{"class":573},[257,4163,570],{"class":338},[257,4165,2399],{"class":815},[257,4167,984],{"class":338},[257,4169,1559],{"class":302},[257,4171,2388],{"class":815},[257,4173,570],{"class":338},[257,4175,1910],{"class":573},[257,4177,1569],{"class":302},[257,4179,449],{"class":448},[257,4181,4182],{"class":452},"(no plan)",[257,4184,1188],{"class":448},[257,4186,684],{"class":338},[257,4188,4189],{"class":291,"line":946},[257,4190,321],{"emptyLinePlaceholder":320},[257,4192,4193],{"class":291,"line":966},[257,4194,321],{"emptyLinePlaceholder":320},[257,4196,4197,4200,4202,4205,4207,4210],{"class":291,"line":1005},[257,4198,4199],{"class":313},"asyncio",[257,4201,570],{"class":338},[257,4203,4204],{"class":815},"run",[257,4206,423],{"class":338},[257,4208,4209],{"class":815},"main",[257,4211,4212],{"class":338},"())\n",[112,4214,4215],{},"Run it. Notice two behaviors.",[112,4217,4218,4219,4221],{},"At the start, the agent calls ",[142,4220,3238],{}," with three steps (one per file) and three postconditions (one per file's size reported, plus \"winner identified\"). Without the plan_holder mechanism, a careless agent might check two files, claim completion. With it, if the agent skips step 3 and tries to finalize, the harness rejects the final answer and the agent goes back to check the third file.",[112,4223,4224],{},"At the end, the plan's rendered form shows every step done with evidence and every postcondition verified. The agent's summary matches what the plan claims it did. These two are now guaranteed to match — by construction.",[273,4226],{},[276,4228,4230],{"id":4229},"_165-what-the-plan-doesnt-do","16.5 What the Plan Doesn't Do",[112,4232,4233],{},"Three limitations worth naming.",[112,4235,4236,4239,4240,4243],{},[124,4237,4238],{},"The plan doesn't validate evidence."," The agent can write ",[142,4241,4242],{},"evidence=\"I did the thing\""," and the harness accepts it. Evidence is about making the agent think — not about cryptographic proof. If you want verifiable evidence (the agent must prove postcondition X by running a specific test), you write a custom postcondition-verifier tool that actually runs the test. Chapter 19's eval harness is how you do this for regression testing.",[112,4245,4246,4249],{},[124,4247,4248],{},"The plan doesn't prevent drift."," The agent can rewrite the plan to remove inconvenient steps. We log the rewrite (Chapter 18) but don't prevent it. Preventing it would make the agent brittle — plans legitimately need revision when the initial plan was wrong. The right audit is observational, not enforcement.",[112,4251,4252,4255],{},[124,4253,4254],{},"The plan doesn't compose across sub-agents."," If the parent has a plan and spawns a sub-agent, the sub-agent either gets its own plan (usually the right choice) or no plan (often fine for narrow objectives). There is no notion of a shared plan hierarchy. Sub-agents report results; parents synthesize; the parent's plan marks the synthesis as a completed step.",[273,4257],{},[276,4259,4261],{"id":4260},"_166-commit","16.6 Commit",[281,4263,4267],{"className":4264,"code":4265,"language":4266,"meta":286,"style":286},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","git add -A && git commit -m \"ch16: structured plans with enforced completion\"\ngit tag ch16-plans\n","bash",[142,4268,4269,4300],{"__ignoreMap":286},[257,4270,4271,4274,4277,4281,4284,4287,4290,4293,4295,4298],{"class":291,"line":292},[257,4272,4273],{"class":419},"git",[257,4275,4276],{"class":452}," add",[257,4278,4280],{"class":4279},"stzsN"," -A",[257,4282,4283],{"class":338}," &&",[257,4285,4286],{"class":419}," git",[257,4288,4289],{"class":452}," commit",[257,4291,4292],{"class":4279}," -m",[257,4294,449],{"class":448},[257,4296,4297],{"class":452},"ch16: structured plans with enforced completion",[257,4299,455],{"class":448},[257,4301,4302,4304,4307],{"class":291,"line":299},[257,4303,4273],{"class":419},[257,4305,4306],{"class":452}," tag",[257,4308,4309],{"class":452}," ch16-plans\n",[276,4311,4313],{"id":4312},"_167-try-it-yourself","16.7 Try It Yourself",[4315,4316,4317,4324,4334],"ol",{},[4318,4319,4320,4323],"li",{},[124,4321,4322],{},"Induce a premature finalization."," Construct a task where the model is tempted to stop early — a checklist where the last item is tedious. Run with plans off; run with plans on. Does the enforcement actually catch the shortcut?",[4318,4325,4326,4329,4330,4333],{},[124,4327,4328],{},"Write a postcondition-verifier tool."," For a task that writes a file, add a tool ",[142,4331,4332],{},"verify_file_exists(path, expected_content_contains)"," that returns true\u002Ffalse. Have the agent call it during postcondition verification. The evidence now carries an actual tool-call outcome.",[4318,4335,4336,4339],{},[124,4337,4338],{},"Measure the overhead."," Compare total turns (and total cost) for the same task with and without plan tools. Does the structured approach cost more per run? If so, is the quality improvement worth it? What tasks is it worth it for?",[273,4341],{},[4343,4344,4345,4352],"what-you-understand",{},[112,4346,4347,4348,4351],{},"The agent works against a structured plan. Steps and postconditions are first-class objects that the agent marks with evidence. The harness enforces that a task can't be declared complete until everything is terminal and verified. Premature finalization is no longer something we hope the agent avoids; it's something the harness catches. The plan is also durable across compaction — it lives in the ",[142,4349,4350],{},"PlanHolder",", not in the transcript — so long sessions don't lose it.",[112,4353,4354],{},"What's still missing: parallelism. Everything we've built runs one sub-agent at a time, one step at a time. Real multi-agent systems want to run four research sub-agents in parallel, combine their results, then act. That brings shared-state problems we haven't faced yet — what happens when two sub-agents want to write to the same file, or update the same plan? Chapter 17 tackles it.",[4356,4357,4358],"style",{},"html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .stp6e, html code.shiki .stp6e{--shiki-light:#39ADB5;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sptTA, html code.shiki .sptTA{--shiki-light:#6182B8;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smCYv, html code.shiki .smCYv{--shiki-light:#E53935;--shiki-light-font-style:italic;--shiki-default:#24292E;--shiki-default-font-style:inherit;--shiki-dark:#E1E4E8;--shiki-dark-font-style:inherit}html pre.shiki code .slqww, html code.shiki .slqww{--shiki-light:#6182B8;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .s2W-s, html code.shiki .s2W-s{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#032F62;--shiki-default-font-style:inherit;--shiki-dark:#9ECBFF;--shiki-dark-font-style:inherit}html pre.shiki code .sithA, html code.shiki .sithA{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#032F62;--shiki-default-font-style:inherit;--shiki-dark:#9ECBFF;--shiki-dark-font-style:inherit}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sFwrP, html code.shiki .sFwrP{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#24292E;--shiki-default-font-style:inherit;--shiki-dark:#E1E4E8;--shiki-dark-font-style:inherit}html pre.shiki code .stzsN, html code.shiki .stzsN{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":286,"searchDepth":299,"depth":299,"links":4360},[4361,4362,4363,4364,4365,4366,4367],{"id":278,"depth":299,"text":279},{"id":1715,"depth":299,"text":1716},{"id":3294,"depth":299,"text":3295},{"id":3717,"depth":299,"text":3718},{"id":4229,"depth":299,"text":4230},{"id":4260,"depth":299,"text":4261},{"id":4312,"depth":299,"text":4313},"md",{},null,{"title":74,"description":117},"7zUffkv6EGe6QyjDXWqAOeaV_5WqiY1yRlBMGN7qHfI",[4374,4376],{"title":70,"path":71,"stem":72,"description":4375,"children":-1},"Previously: permissions, trust labels, sandbox interfaces. One well-governed agent can do a lot. Some tasks, though, decompose better into parallel or specialized work — and that's the case for sub-agents.",{"title":78,"path":79,"stem":80,"description":4377,"children":-1},"Previously: structured plans with evidence-backed completion. Sub-agents still run sequentially. The payoff for sub-agents comes from running them in parallel — the Anthropic multi-agent finding of 90%+ improvement over single-agent baselines rests on parallelism plus independent context windows, not sub-agents in series.",1776848986814]