{"id":25423,"date":"2026-06-16T14:34:20","date_gmt":"2026-06-16T14:34:20","guid":{"rendered":"https:\/\/umang.pk\/2026\/06\/16\/%d9%be%d8%b1%d9%88%da%88%da%a9%d8%b4%d9%86-%d8%b3%db%8c%da%a9%db%8c%d9%88%d8%b1-%d8%a7%db%8c%d8%ac%d9%86%d9%b9-%d9%84%d9%88%d9%be-%da%a9%db%8c%d8%b3%db%92-%d8%a8%d9%86%d8%a7%db%8c%d8%a7-%d8%ac%d8%a7\/"},"modified":"2026-06-16T14:34:20","modified_gmt":"2026-06-16T14:34:20","slug":"%d9%be%d8%b1%d9%88%da%88%da%a9%d8%b4%d9%86-%d8%b3%db%8c%da%a9%db%8c%d9%88%d8%b1-%d8%a7%db%8c%d8%ac%d9%86%d9%b9-%d9%84%d9%88%d9%be-%da%a9%db%8c%d8%b3%db%92-%d8%a8%d9%86%d8%a7%db%8c%d8%a7-%d8%ac%d8%a7","status":"publish","type":"post","link":"https:\/\/umang.pk\/ur\/2026\/06\/16\/%d9%be%d8%b1%d9%88%da%88%da%a9%d8%b4%d9%86-%d8%b3%db%8c%da%a9%db%8c%d9%88%d8%b1-%d8%a7%db%8c%d8%ac%d9%86%d9%b9-%d9%84%d9%88%d9%be-%da%a9%db%8c%d8%b3%db%92-%d8%a8%d9%86%d8%a7%db%8c%d8%a7-%d8%ac%d8%a7\/","title":{"rendered":"\u067e\u0631\u0648\u0688\u06a9\u0634\u0646 \u0633\u06cc\u06a9\u06cc\u0648\u0631 \u0627\u06cc\u062c\u0646\u0679 \u0644\u0648\u067e \u06a9\u06cc\u0633\u06d2 \u0628\u0646\u0627\u06cc\u0627 \u062c\u0627\u0626\u06d2: \u0627\u06cc\u06af\u0632\u0679 \u06a9\u0646\u0688\u06cc\u0634\u0646\u0632 \u0633\u06d2 \u0644\u06d2 \u06a9\u0631 \u0622\u0688\u0679 \u0679\u0631\u06cc\u0644\u0632 \u062a\u06a9"},"content":{"rendered":"\n<div id=\"\">\n<p>\u062c\u0648\u0644\u0627\u0626\u06cc 2025 \u0645\u06cc\u06ba\u060c Claude Code recursive loop 5 \u06af\u06be\u0646\u0679\u06d2 \u0645\u06cc\u06ba 16,000 USD \u0627\u0648\u0631 50,000 USD \u06a9\u06d2 \u062f\u0631\u0645\u06cc\u0627\u0646 \u062c\u0644 \u06af\u06cc\u0627\u06d4 \u06a9\u0648\u0626\u06cc \u06a9\u0631\u06cc\u0634 \u06cc\u0627 \u063a\u0644\u0637\u06cc\u0627\u06ba \u0646\u06c1\u06cc\u06ba \u062a\u06be\u06cc\u06ba\u060c \u0627\u0648\u0631 \u0686\u0648\u0646\u06a9\u06c1 \u06a9\u0633\u06cc \u0646\u06d2 \u06c1\u0645\u06cc\u06ba \u06cc\u06c1 \u0646\u06c1\u06cc\u06ba \u0628\u062a\u0627\u06cc\u0627 \u06a9\u06c1 \u06a9\u0628 \u0631\u06a9\u0646\u0627 \u06c1\u06d2\u060c \u0627\u06cc\u062c\u0646\u0679\u0648\u06ba \u0646\u06d2 \u0628\u0627\u0644\u06a9\u0644 \u0648\u06cc\u0633\u0627 \u06c1\u06cc \u06a9\u06cc\u0627 \u062c\u06cc\u0633\u0627 \u06a9\u06c1 \u0627\u0646\u06c1\u06cc\u06ba \u0628\u062a\u0627\u06cc\u0627 \u06af\u06cc\u0627 \u062a\u06be\u0627\u06d4<\/p>\n<p>4 \u0645\u06c1\u06cc\u0646\u0648\u06ba \u06a9\u06d2 \u0628\u0639\u062f\u060c 4 \u0627\u06cc\u062c\u0646\u0679\u0648\u06ba \u06a9\u06d2 \u0633\u0627\u062a\u06be \u0627\u06cc\u06a9 LangChain \u0644\u0648\u067e 11 \u062f\u0646 \u062a\u06a9 \u0686\u0644\u0627 \u0627\u0648\u0631 \u0627\u0633 \u06a9\u06cc \u0642\u06cc\u0645\u062a 47,000 USD \u062a\u06be\u06cc\u06d4 \u0628\u0644 \u0622\u0646\u06d2 \u062a\u06a9 \u06a9\u0633\u06cc \u0646\u06d2 \u0646\u0648\u0679\u0633 \u0646\u06c1\u06cc\u06ba \u0644\u06cc\u0627\u06d4 \u067e\u0627\u0626\u067e \u0644\u0627\u0626\u0646 \u0646\u06d2 \u06c1\u0645\u0627\u0631\u06d2 \u0679\u06cc\u0633\u0679\u0648\u06ba \u0645\u06cc\u06ba \u0635\u062d\u06cc\u062d \u06a9\u0627\u0631\u06a9\u0631\u062f\u06af\u06cc \u06a9\u0627 \u0645\u0638\u0627\u06c1\u0631\u06c1 \u06a9\u06cc\u0627 \u0627\u0648\u0631 \u0627\u06cc\u062c\u0646\u0679\u0648\u06ba \u0646\u06d2 \u0628\u0627\u0644\u06a9\u0644 \u0648\u06c1\u06cc \u06a9\u06cc\u0627 \u062c\u06cc\u0633\u0627 \u06a9\u06c1 \u06c1\u062f\u0627\u06cc\u062a \u06a9\u06cc \u06af\u0626\u06cc \u062a\u06be\u06cc\u06d4 \u0627\u06cc\u06a9 \u06c1\u06cc \u067e\u06cc\u0679\u0631\u0646.<\/p>\n<p>\u06cc\u06c1 \u0679\u06cc\u0648\u0679\u0648\u0631\u06cc\u0644 \u063a\u0627\u0626\u0628 \u06a9\u0645\u0627\u0646\u0688\u0632 \u06a9\u06d2 \u0628\u0627\u0631\u06d2 \u0645\u06cc\u06ba \u06c1\u06d2\u06d4<\/p>\n<p>\u06c1\u0645 \u067e\u0627\u0646\u0686 \u0686\u06be\u0648\u0679\u06d2 Python \u067e\u0631\u0627\u0626\u0645\u06cc\u0679\u0648\u0632 \u0628\u0646\u0627\u062a\u06d2 \u06c1\u06cc\u06ba \u062c\u0648 \u0632\u06cc\u0627\u062f\u06c1 \u062a\u0631 \u0627\u06cc\u062c\u0646\u0679 \u0644\u0648\u067e \u06a9\u06cc \u063a\u0644\u0637\u06cc\u0648\u06ba \u06a9\u0648 \u062c\u0627\u0631\u06cc \u06c1\u0648\u0646\u06d2 \u0633\u06d2 \u067e\u06c1\u0644\u06d2 \u067e\u06a9\u0691 \u0644\u06cc\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<ul>\n<li>\n<p>\u06a9\u0648\u0626\u06cc \u0631\u0627\u0633\u062a\u06c1 \u0646\u06c1\u06cc\u06ba <strong>\u0645\u062e\u0635\u0648\u0635 \u0645\u0635\u0646\u0641<\/strong> \u0644\u0648\u067e \u0634\u0631\u0648\u0639 \u06c1\u0648\u0646\u06d2 \u0633\u06d2 \u067e\u06c1\u0644\u06d2 \u0627\u0646\u062c\u0627\u0645 \u062f\u06cc\u0627 \u062c\u0627\u0646\u0627 \u0636\u0631\u0648\u0631\u06cc \u06c1\u06d2\u06d4<\/p>\n<\/li>\n<li>\n<p>\u06a9\u0648\u0626\u06cc \u0631\u0627\u0633\u062a\u06c1 \u0646\u06c1\u06cc\u06ba <strong>\u0633\u0631\u06a9\u0679 \u0628\u0631\u06cc\u06a9\u0631<\/strong> \u0633\u062e\u062a \u062d\u062f \u0633\u06d2 \u062a\u062c\u0627\u0648\u0632 \u06a9\u0631\u0646\u06d2 \u067e\u0631 \u0644\u0648\u067e \u0633\u06d2 \u0628\u0627\u06c1\u0631 \u0646\u06a9\u0644\u06cc\u06ba\u06d4<\/p>\n<\/li>\n<li>\n<p>\u06a9\u0648\u0626\u06cc \u0631\u0627\u0633\u062a\u06c1 \u0646\u06c1\u06cc\u06ba <strong>\u0644\u06cc\u062c\u0631<\/strong> \u0635\u0631\u0641 \u0636\u0645\u06cc\u0645\u06c1 SQLite \u0622\u0688\u0679 \u0679\u0631\u06cc\u0644 \u0645\u06cc\u06ba \u06c1\u0631 \u0686\u06cc\u0632 \u06a9\u0648 \u0644\u0627\u06af \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<\/li>\n<li>\n<p>\u0646\u06c1\u06cc\u06ba <strong>\u0627\u06cc\u062c\u0646\u0679 \u0644\u0648\u067e<\/strong> \u062c\u0648 \u062a\u06cc\u0646\u0648\u06ba \u06a9\u0648 \u0622\u067e\u0633 \u0645\u06cc\u06ba \u062c\u0648\u0691\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<\/li>\n<li>\n<p>\u06a9\u0648\u0626\u06cc \u0631\u0627\u0633\u062a\u06c1 \u0646\u06c1\u06cc\u06ba <strong>\u0633\u0637\u062d \u06a9\u0627 \u062c\u0627\u0626\u0632\u06c1<\/strong> \u062e\u06cc\u0627\u0644 \u06cc\u06c1 \u06c1\u06d2 \u06a9\u06c1 \u0646\u06cc\u0686\u06d2 \u062f\u06be\u0627\u0631\u06d2 \u06a9\u06d2 \u0646\u0638\u0627\u0645 \u06a9\u0648 \u06a9\u0686\u06be \u0628\u06be\u06cc \u0645\u0648\u0635\u0648\u0644 \u06c1\u0648\u0646\u06d2 \u0633\u06d2 \u067e\u06c1\u0644\u06d2 \u0627\u0646\u0633\u0627\u0646\u06cc \u062a\u0635\u062f\u06cc\u0642 \u067e\u0631 \u0645\u062c\u0628\u0648\u0631 \u06a9\u06cc\u0627 \u062c\u0627\u0626\u06d2\u06d4<\/p>\n<\/li>\n<\/ul>\n<p>\u0622\u062e\u0631 \u06a9\u0627\u0631 \u0622\u067e \u06a9\u06d2 \u067e\u0627\u0633 \u0627\u06cc\u06a9 \u06a9\u0627\u0645 \u06a9\u0631\u0646\u06d2 \u0648\u0627\u0644\u0627 \u0630\u062e\u06cc\u0631\u06c1 \u06c1\u0648\u06af\u0627 \u062c\u0633 \u0645\u06cc\u06ba \u0622\u067e \u06a9\u06d2 \u062a\u0645\u0627\u0645 \u0627\u06cc\u062c\u0646\u0679 \u067e\u0631\u0648\u062c\u06cc\u06a9\u0679 \u062c\u0627\u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 \u0645\u06a9\u0645\u0644 \u06a9\u0648\u0688 github.com\/dannwaneri\/production-safe-agent-loop \u067e\u0631 \u06c1\u06d2\u06d4<\/p>\n<h2 id=\"heading-table-of-contents\">\u0627\u0646\u0688\u06cc\u06a9\u0633<\/h2>\n<ol>\n<li>\n<p>\u0627\u06cc\u0633\u0627 \u06a9\u06cc\u0648\u06ba \u06c1\u0648\u062a\u0627 \u0631\u06c1\u062a\u0627 \u06c1\u06d2\u061f<\/p>\n<\/li>\n<li>\n<p>\u0634\u0631\u0637\u06cc\u06ba<\/p>\n<\/li>\n<li>\n<p>\u0645\u0631\u062d\u0644\u06c1 1: \u062a\u0639\u0645\u06cc\u0631 \u0633\u06d2 \u067e\u06c1\u0644\u06d2 \u0645\u06a9\u0645\u0644 \u06a9\u06cc \u0648\u0636\u0627\u062d\u062a \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<\/li>\n<li>\n<p>\u0645\u0631\u062d\u0644\u06c1 2: \u0631\u0646 \u0679\u0627\u0626\u0645 \u067e\u0631 \u062a\u06a9\u0645\u06cc\u0644 \u06a9\u0648 \u0627\u0646\u062c\u0627\u0645 \u062f\u06cc\u06ba\u06d4<\/p>\n<\/li>\n<li>\n<p>\u0645\u0631\u062d\u0644\u06c1 3: \u0633\u0628 \u06a9\u0686\u06be \u0631\u06cc\u06a9\u0627\u0631\u0688 \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<\/li>\n<li>\n<p>\u0645\u0631\u062d\u0644\u06c1 4: \u062d\u062f\u0648\u062f \u06a9\u0627 \u0627\u062d\u062a\u0631\u0627\u0645 \u06a9\u0631\u062a\u06d2 \u06c1\u0648\u0626\u06d2 \u0644\u0648\u067e<\/p>\n<\/li>\n<li>\n<p>\u0645\u0631\u062d\u0644\u06c1 5: \u0633\u0637\u062d \u06a9\u0627 \u062c\u0627\u0626\u0632\u06c1 \u0644\u06cc\u06ba\u06d4<\/p>\n<\/li>\n<li>\n<p>\u0645\u0631\u062d\u0644\u06c1 6: \u062d\u0642\u06cc\u0642\u06cc \u0632\u0646\u062f\u06af\u06cc \u06a9\u06cc \u0645\u062b\u0627\u0644\u060c SEO \u0622\u0688\u06cc\u0679\u0631<\/p>\n<\/li>\n<li>\n<p>\u067e\u0644\u06af \u0627\u06cc\u0628\u0644 \u0627\u06cc\u0644 \u0627\u06cc\u0644 \u0627\u06cc\u0645 \u06a9\u0644\u0627\u0626\u0646\u0679<\/p>\n<\/li>\n<li>\n<p>\u0679\u06cc\u0633\u0679 \u0686\u0644\u0627\u0626\u06cc\u06ba<\/p>\n<\/li>\n<li>\n<p>\u0622\u067e \u0646\u06d2 \u06a9\u06cc\u0627 \u0628\u0646\u0627\u06cc\u0627<\/p>\n<\/li>\n<li>\n<p>\u0627\u06af\u0644\u06d2 \u0627\u0642\u062f\u0627\u0645\u0627\u062a<\/p>\n<\/li>\n<\/ol>\n<h2 id=\"heading-why-this-keeps-happening\">\u0627\u06cc\u0633\u0627 \u06a9\u06cc\u0648\u06ba \u06c1\u0648\u062a\u0627 \u0631\u06c1\u062a\u0627 \u06c1\u06d2\u061f<\/h2>\n<p>\u06a9\u0645\u067e\u0646\u06cc \u06a9\u0648 \u0645\u0634\u06a9\u0644 \u0645\u06cc\u06ba \u0688\u0627\u0644\u0646\u06d2 \u0648\u0627\u0644\u0627 \u062d\u0633\u0627\u0628 \u06a9\u062a\u0627\u0628 \u0622\u0633\u0627\u0646 \u062a\u06be\u0627\u06d4 \u0627\u06cc\u06a9 \u0686\u06cc\u0679 \u0628\u0648\u0679 \u06a9\u06cc \u0642\u06cc\u0645\u062a \u062a\u0642\u0631\u06cc\u0628\u0627\u064b $0.04 \u0641\u06cc \u062a\u0639\u0627\u0645\u0644 \u06c1\u06d2\u06d4 \u0633\u06a9\u06cc\u0644\u0688 \u0645\u0644\u0679\u06cc \u0627\u06cc\u062c\u0646\u0679 \u0648\u0631\u06a9 \u0641\u0644\u0648 \u0644\u0627\u06af\u062a $1.20 \u06c1\u06d2\u06d4 \u06cc\u06c1 \u0627\u06cc\u06a9 30x \u0636\u0631\u0628 \u06c1\u06d2\u060c \u0627\u0648\u0631 \u067e\u06cc\u062f\u0627\u0648\u0627\u0631 \u06a9\u06d2 \u0645\u0639\u06cc\u0627\u0631\u0627\u062a \u0633\u06d2 \u067e\u062a\u06c1 \u0686\u0644\u062a\u0627 \u06c1\u06d2 \u06a9\u06c1 \u067e\u06cc\u0686\u06cc\u062f\u06c1 \u06a9\u0627\u0645\u0648\u06ba \u06a9\u06d2 \u0644\u06cc\u06d2 70x \u062a\u06a9 \u067e\u06c1\u0646\u0686\u0627 \u062c\u0627 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0645\u0633\u0626\u0644\u06c1 \u06cc\u06c1 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2 \u06a9\u06c1 \u0627\u06cc\u062c\u0646\u0679 \u0645\u06c1\u0646\u06af\u06d2 \u06c1\u06cc\u06ba\u06d4 \u0645\u0633\u0626\u0644\u06c1 \u06cc\u06c1 \u06c1\u06d2 \u06a9\u06c1 \u0632\u06cc\u0627\u062f\u06c1 \u062a\u0631 \u0679\u06cc\u0645\u0648\u06ba \u0646\u06d2 \u0686\u06cc\u0679 \u0628\u0648\u0679 \u06a9\u06d2 \u0627\u062e\u0631\u0627\u062c\u0627\u062a \u06a9\u06d2 \u0644\u06cc\u06d2 \u0628\u062c\u0679 \u0628\u0646\u0627\u06cc\u0627 \u06c1\u06d2 \u0627\u0648\u0631 \u0627\u06cc\u062c\u0646\u0679 \u06a9\u06d2 \u0641\u0646 \u062a\u0639\u0645\u06cc\u0631 \u06a9\u0648 \u062a\u0639\u06cc\u0646\u0627\u062a \u06a9\u06cc\u0627 \u06c1\u06d2\u06d4 \u06af\u0627\u0631\u0679\u0646\u0631 \u0646\u06d2 \u067e\u0627\u06cc\u0627 \u06a9\u06c1 \u067e\u0627\u0626\u0644\u0679 \u0686\u06cc\u0679 \u0628\u0648\u0679\u0633 \u0627\u0648\u0631 \u067e\u0631\u0648\u0688\u06a9\u0634\u0646 \u0627\u06cc\u062c\u0646\u0679 \u0648\u0631\u06a9 \u0641\u0644\u0648 \u06a9\u06d2 \u062f\u0631\u0645\u06cc\u0627\u0646 \u0679\u0648\u06a9\u0646 \u06a9\u06cc \u06a9\u06be\u067e\u062a \u06a9\u0627 \u0641\u0631\u0642 5 \u0633\u06d2 30 \u06af\u0646\u0627 \u062a\u06a9 \u06c1\u06d2\u06d4 FinOps \u0641\u0627\u0624\u0646\u0688\u06cc\u0634\u0646 \u06a9\u06cc 2026 \u0627\u0633\u0679\u06cc\u0679 \u0622\u0641 FinOps \u0631\u067e\u0648\u0631\u0679 \u06a9\u06d2 \u0645\u0637\u0627\u0628\u0642\u060c 73% \u06a9\u0645\u067e\u0646\u06cc\u0648\u06ba \u0646\u06d2 \u06a9\u06c1\u0627 \u06a9\u06c1 \u0627\u0646 \u06a9\u06cc AI \u06a9\u06cc \u0642\u06cc\u0645\u062a\u06cc\u06ba \u0627\u0635\u0644 \u062a\u0648\u0642\u0639 \u0633\u06d2 \u0632\u06cc\u0627\u062f\u06c1 \u062a\u06be\u06cc\u06ba\u06d4<\/p>\n<p>\u0627\u06cc\u06a9 \u0628\u0627\u0631 \u062c\u0628 \u0622\u067e \u0627\u0633\u06d2 \u062f\u06cc\u06a9\u06be\u06cc\u06ba \u06af\u06d2 \u062a\u0648 \u0637\u0631\u06cc\u0642\u06c1 \u06a9\u0627\u0631 \u0622\u0633\u0627\u0646 \u06c1\u06d2\u06d4 \u0627\u06af\u0631 \u0627\u06cc\u062c\u0646\u0679 \u06a9\u0633\u06cc \u0622\u067e\u0631\u06cc\u0634\u0646 \u0645\u06cc\u06ba \u0646\u0627\u06a9\u0627\u0645 \u06c1\u0648 \u062c\u0627\u062a\u0627 \u06c1\u06d2 \u0627\u0648\u0631 \u062f\u0648\u0628\u0627\u0631\u06c1 \u06a9\u0648\u0634\u0634 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u060c \u062a\u0648 \u06cc\u06c1 \u0646\u0626\u06d2 \u0633\u0631\u06d2 \u0633\u06d2 \u0634\u0631\u0648\u0639 \u0646\u06c1\u06cc\u06ba \u06c1\u0648\u062a\u0627 \u06c1\u06d2\u06d4 \u062f\u0648\u0628\u0627\u0631\u06c1 \u06a9\u0648\u0634\u0634 \u06a9\u0631\u0646\u06d2 \u0633\u06d2 \u067e\u06c1\u0644\u06d2 \u06c1\u0631 \u0646\u0627\u06a9\u0627\u0645 \u06a9\u0648\u0634\u0634 \u06a9\u06d2 \u0644\u06cc\u06d2 \u067e\u0648\u0631\u06cc \u0633\u06cc\u0627\u0642 \u0648 \u0633\u0628\u0627\u0642 \u06a9\u06cc \u0648\u0646\u0688\u0648 \u06a9\u0648 \u062f\u0648\u0628\u0627\u0631\u06c1 \u067e\u0691\u06be\u0627 \u062c\u0627\u062a\u0627 \u06c1\u06d2\u06d4 \u067e\u06c1\u0644\u06cc \u062a\u06a9\u0631\u0627\u0631 \u06a9\u06d2 \u0644\u06cc\u06d2 100 \u0679\u0648\u06a9\u0646 \u062f\u0631\u06a9\u0627\u0631 \u06c1\u06cc\u06ba\u06d4 2 \u062a\u06a9\u0631\u0627\u0631 \u06a9\u06cc \u0644\u0627\u06af\u062a 200 \u06c1\u06d2\u06d4 \u062f\u0633 \u062f\u06c1\u0631\u0627\u0646\u06d2 \u067e\u0631 \u06c1\u0632\u0627\u0631\u0648\u06ba \u0688\u0627\u0644\u0631 \u062e\u0631\u0686 \u06c1\u0648 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 \u0622\u067e \u06c1\u0631 \u0646\u0627\u06a9\u0627\u0645\u06cc \u06a9\u06cc \u0627\u062f\u0627\u0626\u06cc\u06af\u06cc \u062c\u0627\u0631\u06cc \u0631\u06a9\u06be\u06cc\u06ba \u06af\u06d2\u060c \u0645\u0644\u06cc \u0633\u06cc\u06a9\u0646\u0688 \u0628\u06c1 \u0645\u0644\u06cc \u0633\u06cc\u06a9\u0646\u0688\u06d4<\/p>\n<pre><code class=\"language-python\"># This is the entire problem in three lines\nwhile True:\n    result = agent.run(task)\n    # done when...?\n<\/code><\/pre>\n<p>\u0633\u0648\u0627\u0644\u06cc\u06c1 \u0646\u0634\u0627\u0646 \u06cc\u06c1 \u06c1\u06d2 \u06a9\u06c1 \u067e\u06cc\u0633\u06c1 \u06a9\u06c1\u0627\u06ba \u062c\u0627\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0627\u06cc\u06a9 \u0627\u0648\u0631 \u0686\u06cc\u0632 \u062c\u0648 \u0686\u06cc\u0632\u0648\u06ba \u06a9\u0648 \u0628\u062f\u062a\u0631 \u0628\u0646\u0627\u062a\u06cc \u06c1\u06d2 \u0648\u06c1 \u06cc\u06c1 \u06c1\u06d2 \u06a9\u06c1 \u0627\u06cc\u062c\u0646\u0679 \u0646\u0645\u0627\u06cc\u0627\u06ba \u0637\u0648\u0631 \u067e\u0631 \u0646\u0627\u06a9\u0627\u0645 \u0646\u06c1\u06cc\u06ba \u06c1\u0648\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 \u0645\u0648\u062c\u0648\u062f\u06c1 \u06a9\u0648\u0688 \u0627\u06cc\u06a9 \u063a\u06cc\u0631 \u0645\u062a\u0639\u06cc\u0646\u06c1 \u062d\u0627\u0644\u062a \u062a\u06a9 \u067e\u06c1\u0646\u0686 \u062c\u0627\u062a\u0627 \u06c1\u06d2 \u0627\u0648\u0631 \u06a9\u0631\u06cc\u0634 \u06c1\u0648 \u062c\u0627\u062a\u0627 \u06c1\u06d2\u06d4 LLM \u0627\u0628\u06c1\u0627\u0645 \u06a9\u0648 \u062d\u0644 \u06a9\u0631\u0646\u06d2 \u0627\u0648\u0631 \u0645\u062f\u062f\u06af\u0627\u0631 \u0628\u0646\u0646\u06d2 \u06a9\u06cc \u06a9\u0648\u0634\u0634 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4 \u0628\u0631\u0627\u06c1 \u06a9\u0631\u0645 \u062f\u0648\u0628\u0627\u0631\u06c1 \u06a9\u0648\u0634\u0634 \u06a9\u0631\u06cc\u06ba\u06d4 \u0679\u0648\u0644 \u06a9\u0627\u0644 \u06a9\u0648 \u062f\u0648\u0628\u0627\u0631\u06c1 \u0641\u0627\u0631\u0645\u06cc\u0679 \u06a9\u0631\u06cc\u06ba\u06d4 \u062a\u0635\u062f\u06cc\u0642\u06cc \u0627\u06cc\u062c\u0646\u0679 \u0686\u0644\u0627\u0626\u06cc\u06ba\u06d4 \u062a\u0635\u062f\u06cc\u0642 \u06a9\u0631\u0646\u06d2 \u0648\u0627\u0644\u06d2 \u0627\u06cc\u062c\u0646\u0679 \u0646\u06d2 \u06a9\u0686\u06be \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u06cc\u0627\u06d4 \u0627\u0635\u0644\u0627\u062d\u06cc \u0627\u0641\u0633\u0631\u0627\u0646 \u06a9\u0648 \u0628\u0631\u0637\u0631\u0641\u06d4 \u06a9\u0633\u06cc \u0646\u06d2 \u0628\u06be\u06cc \u0627\u0633 \u0628\u0627\u062a \u06a9\u06cc \u0648\u0636\u0627\u062d\u062a \u0646\u06c1\u06cc\u06ba \u06a9\u06cc \u06a9\u06c1 &quot;\u0635\u062d\u06cc\u062d&#8221; \u06a9\u0627 \u06a9\u06cc\u0627 \u0645\u0637\u0644\u0628 \u06c1\u06d2\u06d4 \u0622\u067e \u06a9\u06d2 \u062a\u0645\u0627\u0645 \u0688\u06cc\u0634 \u0628\u0648\u0631\u0688\u0632 \u067e\u0631 \u0644\u0648\u067e\u0633 \u062e\u0648\u0628\u0635\u0648\u0631\u062a \u0646\u0638\u0631 \u0622\u062a\u06d2 \u06c1\u06cc\u06ba &#8211; \u0633\u0631\u06af\u0631\u0645\u06cc\u0627\u06ba\u060c \u0679\u0648\u0644 \u06a9\u0627\u0644\u0632\u060c \u0641\u06cc\u0635\u062f \u0645\u06a9\u0645\u0644\u060c \u0648\u063a\u06cc\u0631\u06c1 &#8211; \u062e\u0627\u0645\u0648\u0634\u06cc \u0633\u06d2 \u0627\u067e\u0646\u0627 \u0628\u062c\u0679 \u06a9\u06be\u0627\u062a\u06d2 \u06c1\u0648\u0626\u06d2<\/p>\n<p>\u06af\u0627\u0631\u0679\u0646\u0631 \u0646\u06d2 \u067e\u06cc\u0634 \u06af\u0648\u0626\u06cc \u06a9\u06cc \u06c1\u06d2 \u06a9\u06c1 40% \u0627\u06cc\u062c\u0646\u0679 \u067e\u0631\u0648\u062c\u06cc\u06a9\u0679\u0633 2027 \u062a\u06a9 \u0645\u0639\u0627\u0634\u06cc \u0646\u0627\u06a9\u0627\u0645\u06cc \u06a9\u06cc \u0648\u062c\u06c1 \u0633\u06d2 \u062a\u0631\u06a9 \u06a9\u0631 \u062f\u06cc\u06d2 \u062c\u0627\u0626\u06cc\u06ba \u06af\u06d2\u06d4 \u0632\u06cc\u0627\u062f\u06c1 \u062a\u0631 \u0646\u0627\u06a9\u0627\u0645\u06cc\u0627\u06ba \u0631\u0648\u06a9\u06cc \u062c\u0627 \u0633\u06a9\u062a\u06cc \u06c1\u06cc\u06ba\u06d4 \u0628\u0631\u0637\u0631\u0641\u06cc \u06a9\u06cc \u0634\u0631\u0627\u0626\u0637 \u06c1\u06cc\u06ba\u060c \u0628\u06c1\u062a\u0631 \u0645\u0627\u0688\u0644 \u0646\u06c1\u06cc\u06ba\u06d4<\/p>\n<h2 id=\"heading-prerequisites\">\u0634\u0631\u0637\u06cc\u06ba<\/h2>\n<pre><code class=\"language-bash\">git clone https:\/\/github.com\/dannwaneri\/production-safe-agent-loop\ncd production-safe-agent-loop\npip install -r requirements.txt\nexport ANTHROPIC_API_KEY=sk-...\n<\/code><\/pre>\n<h2 id=\"heading-phase-1-define-done-before-you-build\">\u0645\u0631\u062d\u0644\u06c1 1: \u062a\u0639\u0645\u06cc\u0631 \u0633\u06d2 \u067e\u06c1\u0644\u06d2 \u0645\u06a9\u0645\u0644 \u06a9\u06cc \u0648\u0636\u0627\u062d\u062a \u06a9\u0631\u06cc\u06ba\u06d4<\/h2>\n<p>\u0627\u06cc\u062c\u0646\u0679 \u06a9\u06cc \u062a\u0631\u0642\u06cc \u0645\u06cc\u06ba \u0633\u0628 \u0633\u06d2 \u0645\u06c1\u0646\u06af\u06cc \u063a\u0644\u0637\u06cc \u063a\u0644\u0637 \u0645\u0627\u0688\u0644 \u06a9\u0627 \u0627\u0646\u062a\u062e\u0627\u0628 \u0646\u06c1 \u06a9\u0631\u0646\u0627 \u06cc\u0627 \u062f\u0648\u0628\u0627\u0631\u06c1 \u06a9\u0648\u0634\u0634 \u06a9\u06cc \u062d\u062f \u06a9\u0648 \u06a9\u06be\u0648\u0646\u0627 \u06c1\u06d2\u06d4 \u062a\u0639\u0645\u06cc\u0631 \u0634\u0631\u0648\u0639 \u06c1\u0648\u062a\u06cc \u06c1\u06d2 \u0627\u0633 \u0633\u06d2 \u067e\u06c1\u0644\u06d2 \u06a9\u06c1 \u0622\u067e \u0627\u06cc\u06a9 \u062c\u0645\u0644\u06d2 \u0645\u06cc\u06ba \u0627\u06cc\u06a9 \u0633\u0648\u0627\u0644 \u06a9\u0627 \u062c\u0648\u0627\u0628 \u062f\u06d2 \u0633\u06a9\u06cc\u06ba\u06d4<\/p>\n<p><strong>\u062a\u06a9\u0645\u06cc\u0644 \u06a9\u06cc\u0633\u06cc \u0646\u0638\u0631 \u0622\u062a\u06cc \u06c1\u06d2\u061f<\/strong><\/p>\n<p>\u0632\u06cc\u0627\u062f\u06c1 \u062a\u0631 \u0679\u06cc\u0645\u06cc\u06ba \u0627\u0633 \u06a9\u0627 \u062c\u0648\u0627\u0628 \u0646\u06c1\u06cc\u06ba \u062f\u06d2 \u0633\u06a9\u062a\u06cc\u06ba\u06d4 \u06cc\u06c1 \u0627\u0633 \u0644\u06cc\u06d2 \u0646\u06c1\u06cc\u06ba \u06a9\u06c1 \u0645\u06cc\u06ba \u0644\u0627\u067e\u0631\u0648\u0627\u06c1 \u06c1\u0648\u06ba\u060c \u0627\u0633 \u0644\u06cc\u06d2 \u06a9\u06c1 \u0645\u06cc\u06ba \u0679\u0631\u0645\u06cc\u0646\u0644 \u06a9\u06be\u0648\u0644\u0646\u06d2 \u0633\u06d2 \u067e\u06c1\u0644\u06d2 \u06a9\u0633\u06cc \u0686\u06cc\u0632 \u067e\u0631 \u0632\u0628\u0631\u062f\u0633\u062a\u06cc \u0646\u06c1\u06cc\u06ba \u06a9\u0631\u062a\u0627\u06d4 \u0645\u062e\u0635\u0648\u0635 \u0645\u0635\u0646\u0641 \u0641\u0646\u06a9\u0634\u0646 \u06a9\u0648 \u0646\u0627\u0641\u0630 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<pre><code class=\"language-python\"># spec_writer.py\nfrom spec_writer import SpecWriter\n\nspec = SpecWriter(db_path=\"spec.db\").run()\n<\/code><\/pre>\n<p>\u062c\u0628 \u0622\u067e \u06a9\u0627\u0644 \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 <code>.run()<\/code>\u0627\u0633\u06d2 \u0648\u0627\u067e\u0633 \u0646\u06c1\u06cc\u06ba \u06a9\u06cc\u0627 \u062c\u0627\u0626\u06d2 \u06af\u0627 \u062c\u0628 \u062a\u06a9 \u06a9\u06c1 \u062a\u06cc\u0646 \u0633\u0648\u0627\u0644\u0648\u06ba \u06a9\u06d2 \u062c\u0648\u0627\u0628 \u0646\u06c1 \u0645\u0644 \u062c\u0627\u0626\u06cc\u06ba\u06d4<\/p>\n<ol>\n<li>\n<p>\u06cc\u06c1 \u06a9\u06cc\u0627 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u061f<\/p>\n<\/li>\n<li>\n<p>\u06cc\u06c1 \u06a9\u06cc\u0627 \u0646\u06c1\u06cc\u06ba \u06a9\u0631\u062a\u0627\u061f<\/p>\n<\/li>\n<li>\n<p>\u0627\u06cc\u06a9 \u062c\u0645\u0644\u06d2 \u0645\u06cc\u06ba \u06a9\u06cc\u0627 \u0646\u0638\u0631 \u0622\u062a\u0627 \u06c1\u06d2\u061f<\/p>\n<\/li>\n<\/ol>\n<p>\u062a\u06cc\u0633\u0631\u0627 \u0633\u0648\u0627\u0644 \u0627\u06c1\u0645 \u06c1\u06d2\u06d4 \u06cc\u06c1 \u0633\u0628 \u0633\u06d2 \u0645\u0634\u06a9\u0644 \u06a9\u0627\u0645 \u0628\u06be\u06cc \u06c1\u06d2\u06d4 &quot;\u06a9\u0633\u06cc \u0627\u06cc\u062c\u0646\u0679 \u0633\u06d2 \u0633\u0627\u0626\u0679 \u06a9\u0627 \u0622\u0688\u0679 \u06a9\u0631\u0648\u0627\u0626\u06cc\u06ba&#8221; \u062c\u0648\u0627\u0628 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4 &quot;\u0627\u06cc\u062c\u0646\u0679 \u0679\u0627\u0631\u06af\u0679 \u06cc\u0648 \u0622\u0631 \u0627\u06cc\u0644 \u06a9\u0648 \u06a9\u0631\u0627\u0644 \u06a9\u0631\u062a\u0627 \u06c1\u06d2 \u0627\u0648\u0631 \u0633\u0628 \u06a9\u0686\u06be \u0646\u06a9\u0627\u0644\u062a\u0627 \u06c1\u06d2\u06d4 <code><title\/><\/code> \u0627\u0648\u0631 <code><meta description=\"\"\/><\/code> \u0679\u06cc\u06af\u0632\u060c \u062c\u06be\u0646\u0688\u0627 \u063a\u0627\u0626\u0628 \u06cc\u0627 \u0632\u06cc\u0627\u062f\u06c1 \u0637\u0648\u0627\u0644\u062a\u060c \u0627\u0648\u0631 \u0633\u0679\u0627\u067e&#8221; \u062c\u0648\u0627\u0628\u0627\u062a \u06c1\u06cc\u06ba\u06d4 \u0627\u0646 \u0645\u06cc\u06ba \u0633\u06d2 \u0627\u06cc\u06a9 \u0633\u0631\u06a9\u0679 \u0628\u0631\u06cc\u06a9\u0631 \u06a9\u0648 \u0646\u0627\u0641\u0630 \u06a9\u0631\u0646\u06d2 \u06a9\u06d2 \u0644\u06cc\u06d2 \u06a9\u0686\u06be \u062f\u06cc\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0648\u0636\u0627\u062d\u062a\u06cc\u06ba SQLite \u0645\u06cc\u06ba \u0645\u062d\u0641\u0648\u0638 \u06c1\u06cc\u06ba\u06d4 <code>SpecResult<\/code> \u0688\u06cc\u0679\u0627 \u06a9\u0644\u0627\u0633 <code>session_id<\/code>. \u0648\u06c1 ID \u0648\u06c1 \u062f\u06be\u0627\u06af\u06c1 \u0628\u0646 \u062c\u0627\u062a\u0627 \u06c1\u06d2 \u062c\u0648 \u0648\u0636\u0627\u062d\u062a\u06cc\u06ba\u060c \u0644\u06cc\u062c\u0631 \u06a9\u06cc \u0642\u0637\u0627\u0631\u06cc\u06ba\u060c \u0627\u0648\u0631 \u0644\u0648\u067e \u06a9\u06d2 \u0646\u062a\u0627\u0626\u062c \u06a9\u0648 \u062c\u0648\u0691\u062a\u0627 \u06c1\u06d2\u06d4 \u0627\u06cc\u06a9 \u0633\u06cc\u0634\u0646 \u06a9\u0648 \u0633\u0631\u06d2 \u0633\u06d2 \u0622\u062e\u0631 \u062a\u06a9 \u0679\u0631\u06cc\u06a9 \u06a9\u06cc\u0627 \u062c\u0627 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<pre><code class=\"language-python\">@dataclass(frozen=True)\nclass SpecResult:\n    what_it_does: str\n    what_it_does_not: str\n    done_looks_like: str\n    session_id: str\n<\/code><\/pre>\n<p><code>frozen=True<\/code>    \u06cc\u06c1 \u0636\u0631\u0648\u0631\u06cc \u06c1\u06d2\u06d4 \u062a\u0635\u0631\u06cc\u062d \u0627\u06cc\u06a9 \u0648\u0639\u062f\u06c1 \u06c1\u06d2\u060c \u0645\u0633\u0648\u062f\u06c1 \u0646\u06c1\u06cc\u06ba\u06d4 \u0627\u06cc\u06a9 \u0628\u0627\u0631 \u0644\u06a9\u06be\u0646\u06d2 \u06a9\u06d2 \u0628\u0639\u062f\u060c \u0627\u06cc\u06a9 \u0644\u0648\u067e \u0627\u0633 \u067e\u0631 \u0686\u0644\u062a\u0627 \u06c1\u06d2. \u06a9\u0648\u0626\u06cc \u062f\u0631\u0645\u06cc\u0627\u0646\u06cc \u0627\u0635\u0644\u0627\u062d\u0627\u062a \u0646\u06c1\u06cc\u06ba \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u062c\u0627\u0646\u0686 \u06a9\u06d2 \u0645\u0642\u0627\u0635\u062f \u06a9\u06d2 \u0644\u06cc\u06d2\u060c <code>SpecWriter<\/code> \u0627\u0646\u062c\u06cc\u06a9\u0634\u0646 \u0642\u0628\u0648\u0644 \u06a9\u0631\u06cc\u06ba\u06d4 <code>input_fn<\/code> \u0627\u0648\u0631 <code>output_fn<\/code> \u06a9\u0627\u0644 \u06a9\u06d2 \u0642\u0627\u0628\u0644\u06d4 \u06a9\u0648\u0626\u06cc \u0645\u0639\u06cc\u0627\u0631\u06cc \u0627\u0646 \u067e\u0679 \u0628\u0646\u062f\u0631 \u067e\u06cc\u0686\u0646\u06af \u06a9\u06cc \u0636\u0631\u0648\u0631\u062a \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4 \u062f\u06cc\u06a9\u06be\u06cc\u06ba <code>tests\/test_spec_writer.py<\/code> \u06a9\u0627\u0645 \u06a9\u0631\u0646\u06d2 \u0648\u0627\u0644\u06cc \u0645\u062b\u0627\u0644 \u06a9\u06d2 \u0637\u0648\u0631 \u067e\u0631 &#8211; \u062e\u0627\u0646\u062f\u0627\u0646 \u0686\u06be\u0648\u0679\u0627 \u06c1\u06d2\u06d4 <code>scripted_input<\/code> \u0627\u06cc\u06a9 \u0645\u062f\u062f\u06af\u0627\u0631 \u062c\u0648 \u062c\u0646\u0631\u06cc\u0679\u0631 \u0633\u06d2 \u062c\u0648\u0627\u0628\u0627\u062a \u0648\u0627\u067e\u0633 \u06a9\u0631\u062a\u0627 \u06c1\u06d2 \u0627\u0648\u0631 \u0627\u0646\u06c1\u06cc\u06ba pytest \u06a9\u06d2 \u0630\u0631\u06cc\u0639\u06d2 \u0679\u06cc\u0633\u0679 \u06a9\u06d2 \u0644\u06cc\u06d2 \u0645\u062e\u0635\u0648\u0635 SQLite \u0641\u0627\u0626\u0644 \u0645\u06cc\u06ba \u0644\u06a9\u06be\u062a\u0627 \u06c1\u06d2\u06d4 <code>tmp_path<\/code> \u0641\u06a9\u0633\u0686\u0631 SQLite <code>:memory:<\/code> \u06a9\u06cc\u0648\u0646\u06a9\u06c1 \u06cc\u06c1 \u06cc\u06c1\u0627\u06ba \u0645\u062d\u0641\u0648\u0638 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4 <code>SpecWriter<\/code> \u0641\u06cc \u0637\u0631\u06cc\u0642\u06c1 \u0627\u06cc\u06a9 \u0646\u06cc\u0627 \u06a9\u0646\u06a9\u0634\u0646 \u06a9\u06be\u0648\u0644\u062a\u0627 \u06c1\u06d2\u06d4 <code>:memory:<\/code> \u06a9\u0646\u06a9\u0634\u0646 \u0627\u0633 \u06a9\u0627 \u0627\u067e\u0646\u0627 \u0627\u0644\u06af \u062a\u06be\u0644\u06af \u0688\u06cc\u0679\u0627 \u0628\u06cc\u0633 \u06c1\u0648\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<h2 id=\"heading-phase-2-enforce-done-at-runtime\">\u0645\u0631\u062d\u0644\u06c1 2: \u0631\u0646 \u0679\u0627\u0626\u0645 \u067e\u0631 \u062a\u06a9\u0645\u06cc\u0644 \u06a9\u0648 \u0627\u0646\u062c\u0627\u0645 \u062f\u06cc\u06ba\u06d4<\/h2>\n<p>\u0627\u067e \u0627\u0633\u0679\u0631\u06cc\u0645 \u062e\u062a\u0645 \u06a9\u0631\u0646\u06d2 \u06a9\u06cc \u0634\u0631\u0627\u0626\u0637 \u06a9\u06cc \u0648\u0636\u0627\u062d\u062a \u06a9\u0631\u0646\u0627 \u0627\u06cc\u06a9 \u0646\u0638\u0645 \u0648 \u0636\u0628\u0637 \u06c1\u06d2\u06d4 \u0633\u0631\u06a9\u0679 \u0628\u0631\u06cc\u06a9\u0631\u0632 \u0627\u062b\u0631 \u0645\u06cc\u06ba \u06c1\u06cc\u06ba\u06d4<\/p>\n<pre><code class=\"language-python\"># circuit_breaker.py\nfrom circuit_breaker import CircuitBreaker, CircuitBreakerError\n\nbreaker = CircuitBreaker(turn_limit=5, token_limit=15000)\nbreaker.check(turn_count, accumulated_tokens)  # raises on breach\n<\/code><\/pre>\n<p>\u062f\u0648 \u0686\u06be\u062a\u06cc\u06ba \u06c1\u06cc\u06ba\u06d4 \u062f\u0648\u0646\u0648\u06ba \u0645\u0634\u06a9\u0644 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p><code>turn_limit<\/code>    \u0627\u06cc\u06a9 \u0644\u0648\u067e LLM \u06a9\u0648 \u06a9\u0627\u0644 \u06a9\u0631\u0646\u06d2 \u06a9\u06cc \u062a\u0639\u062f\u0627\u062f \u06a9\u0648 \u0645\u062d\u062f\u0648\u062f \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4 <code>token_limit<\/code> \u062a\u0645\u0627\u0645 \u0645\u0648\u0691 \u067e\u0631 \u06a9\u0644 \u0679\u0648\u06a9\u0646 \u06a9\u06cc \u06a9\u06be\u067e\u062a \u06a9\u0648 \u0645\u062d\u062f\u0648\u062f \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4 \u0679\u0631\u067e\u0646\u06af \u0645\u06cc\u06ba \u0633\u06d2 \u0627\u06cc\u06a9 \u0627\u0679\u06be\u0627\u062a\u0627 \u06c1\u06d2 <code>CircuitBreakerError<\/code> \u0641\u0648\u0631\u06cc \u0637\u0648\u0631 \u067e\u0631<\/p>\n<p>\u062d\u062f\u0648\u062f \u0633\u062e\u062a \u06c1\u06cc\u06ba\u06d4 <code>turn_count == turn_limit<\/code> \u0627\u0633 \u06a9\u06cc \u0627\u062c\u0627\u0632\u062a \u06c1\u06d2\u06d4 <code>turn_count == turn_limit + 1<\/code> \u0633\u0641\u0631 \u06a9\u0648\u0626\u06cc \u0631\u0639\u0627\u06cc\u062a\u06cc \u0645\u062f\u062a \u06cc\u0627 \u0627\u0646\u062a\u0628\u0627\u06c1 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4 \u0632\u0628\u0631\u062f\u0633\u062a\u06cc \u0631\u0648\u06a9\u0646\u0627 \u0627\u0646\u0633\u0627\u0646 \u06a9\u0648 \u0686\u0648\u06a9\u06cc \u0686\u0644\u0627\u0646\u06d2 \u067e\u0631 \u0645\u062c\u0628\u0648\u0631 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<pre><code class=\"language-python\">from dataclasses import dataclass\n\n\n@dataclass\nclass CircuitBreakerError(Exception):\n    reason: str          # \"turn_ceiling\" or \"token_ceiling\"\n    turn_count: int\n    accumulated_tokens: int\n\n    def __post_init__(self) -> None:\n        super().__init__(\n            f\"circuit breaker tripped: {self.reason} \"\n            f\"(turn={self.turn_count}, tokens={self.accumulated_tokens})\"\n        )\n\n\nclass CircuitBreaker:\n    def __init__(self, turn_limit: int = 5, token_limit: int = 15000) -> None:\n        self.turn_limit = turn_limit\n        self.token_limit = token_limit\n\n    def check(self, turn_count: int, accumulated_tokens: int) -> None:\n        if turn_count > self.turn_limit:\n            self._trip(\"turn_ceiling\", turn_count, accumulated_tokens)\n        if accumulated_tokens > self.token_limit:\n            self._trip(\"token_ceiling\", turn_count, accumulated_tokens)\n\n    def _trip(self, reason: str, turn_count: int, accumulated_tokens: int) -> None:\n        print(\n            \"\\n=== CIRCUIT BREAKER CHECKPOINT ===\\n\"\n            f\"reason         : {reason}\\n\"\n            f\"turn_count     : {turn_count} \/ limit {self.turn_limit}\\n\"\n            f\"tokens_used    : {accumulated_tokens} \/ limit {self.token_limit}\\n\"\n            \"action         : halt loop, surface to human reviewer\\n\"\n            \"==================================\"\n        )\n        raise CircuitBreakerError(\n            reason=reason,\n            turn_count=turn_count,\n            accumulated_tokens=accumulated_tokens,\n        )\n<\/code><\/pre>\n<p><code>CircuitBreakerError<\/code>    \u06cc\u06c1 \u0627\u06cc\u06a9 \u0627\u0633\u062a\u062b\u0646\u0627\u0621 \u06c1\u06d2\u060c \u0648\u0627\u067e\u0633\u06cc \u06a9\u0648\u0688 \u0646\u06c1\u06cc\u06ba\u06d4 \u06cc\u06c1 \u062c\u0627\u0646 \u0628\u0648\u062c\u06be \u06a9\u0631 \u06c1\u06d2\u06d4 \u0648\u0627\u067e\u0633\u06cc \u06a9\u0648\u0688 \u06a9\u0648 \u0646\u0638\u0631 \u0627\u0646\u062f\u0627\u0632 \u06a9\u06cc\u0627 \u062c\u0627 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4 \u063a\u06cc\u0631 \u067e\u06a9\u0691\u06d2 \u06af\u0626\u06d2 \u0645\u0633\u062a\u062b\u0646\u06cc\u0627\u062a \u0627\u06cc\u0633\u0627 \u0646\u06c1\u06cc\u06ba \u06a9\u0631 \u0633\u06a9\u062a\u06d2\u06d4 \u0627\u06cc\u06a9 \u062e\u0627\u0645\u0648\u0634 \u062e\u0644\u0627\u0641 \u0648\u0631\u0632\u06cc \u0646\u0627\u0645\u0645\u06a9\u0646 \u06c1\u06d2. \u0627\u06cc\u06a9 \u0627\u0646\u0633\u0627\u0646\u06cc \u067e\u0691\u06be\u0646\u06d2 \u06a9\u06d2 \u0642\u0627\u0628\u0644 \u0686\u06cc\u06a9 \u067e\u0648\u0627\u0626\u0646\u0679 \u0628\u06cc\u0646\u0631 \u06a9\u0648 \u0645\u0639\u06cc\u0627\u0631\u06cc \u0622\u0624\u0679 \u067e\u0679 \u067e\u0631 \u067e\u0631\u0646\u0679 \u06a9\u06cc\u0627 \u062c\u0627\u062a\u0627 \u06c1\u06d2: <code>_trip()<\/code> <em>\u067e\u06c1\u0644\u06d2<\/em> \u0627\u06cc\u06a9 \u0627\u0633\u062a\u062b\u0646\u06cc\u0670 \u0688\u0627\u0644\u0627 \u062c\u0627\u062a\u0627 \u06c1\u06d2\u060c \u0627\u0633 \u0644\u06cc\u06d2 \u0627\u06af\u0631 \u06a9\u0627\u0644 \u06a9\u0631\u0646\u06d2 \u0648\u0627\u0644\u0627 \u0627\u0633\u062a\u062b\u0646\u0627\u0621 \u06a9\u0648 \u0646\u06af\u0644 \u0628\u06be\u06cc \u0644\u06d2\u060c \u062a\u0628 \u0628\u06be\u06cc \u0622\u067e\u0631\u06cc\u0679\u0631 \u0631\u06cc\u0627\u0633\u062a \u06a9\u0648 \u062f\u06cc\u06a9\u06be \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0627\u06c1\u0645 \u0627\u0635\u0648\u0644: \u0641\u0648\u0646 <code>.check()<\/code> <strong>\u067e\u06c1\u0644\u06d2<\/strong> \u06a9\u0648\u0626\u06cc LLM \u06a9\u0627\u0644\u060c LLM \u06a9\u0627\u0644 \u06a9\u06d2 \u0628\u0639\u062f \u0646\u06c1\u06cc\u06ba\u06d4 \u067e\u0631\u0648\u0627\u0632 \u06a9\u06d2 \u0628\u0639\u062f \u06a9\u06cc \u062a\u0635\u062f\u06cc\u0642 \u06a9\u0627 \u0645\u0637\u0644\u0628 \u06c1\u06d2 \u06a9\u06c1 \u0622\u067e \u0646\u06d2 \u0627\u067e\u0646\u06d2 \u0679\u0648\u06a9\u0646\u0632 \u06a9\u0648 \u067e\u06c1\u0644\u06d2 \u06c1\u06cc \u062c\u0644\u0627 \u062f\u06cc\u0627 \u06c1\u06d2 \u0627\u0633 \u0633\u06d2 \u067e\u06c1\u0644\u06d2 \u06a9\u06c1 \u0622\u067e \u06a9\u0648 \u0645\u0639\u0644\u0648\u0645 \u06c1\u0648 \u06a9\u06c1 \u062d\u062f \u0633\u06d2 \u062a\u062c\u0627\u0648\u0632 \u06a9\u0631 \u06af\u06cc\u0627 \u06c1\u06d2\u06d4<\/p>\n<pre><code class=\"language-python\"># Wrong \u2014 post-flight\nresult = client.messages.create(...)\nbreaker.check(turn_count, accumulated_tokens)  # too late\n\n# Right \u2014 pre-flight\nbreaker.check(turn_count, accumulated_tokens)  # raises before any spend\nresult = client.messages.create(...)\n<\/code><\/pre>\n<p>\u0688\u06cc\u0641\u0627\u0644\u0679\u0633 (5 \u0645\u0648\u0691\u060c 15,000 \u0679\u0648\u06a9\u0646) \u0633\u062e\u062a \u0679\u06cc\u0648\u0679\u0648\u0631\u06cc\u0644 \u0688\u06cc\u0645\u0648 \u06a9\u06d2 \u0633\u0627\u062a\u06be \u0645\u0637\u0627\u0628\u0642\u062a \u0631\u06a9\u06be\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 \u067e\u06cc\u062f\u0627\u0648\u0627\u0631\u06cc \u0628\u062c\u0679 \u0645\u062e\u062a\u0644\u0641 \u06c1\u06cc\u06ba\u06d4 \u0627\u0646\u0633\u0679\u06cc \u0679\u06cc\u0648\u0679 \u067e\u0631 \u0627\u06cc\u0688\u062c\u0633\u0679\u0645\u0646\u0679:<\/p>\n<pre><code class=\"language-python\"># Production example \u2014 tighter token budget, more turns\nbreaker = CircuitBreaker(turn_limit=10, token_limit=50000)\n<\/code><\/pre>\n<h2 id=\"heading-phase-3-record-everything\">\u0645\u0631\u062d\u0644\u06c1 3: \u0633\u0628 \u06a9\u0686\u06be \u0631\u06cc\u06a9\u0627\u0631\u0688 \u06a9\u0631\u06cc\u06ba\u06d4<\/h2>\n<p>\u0633\u0631\u06a9\u0679 \u0628\u0631\u06cc\u06a9\u0631 \u0622\u067e \u06a9\u06d2 \u0628\u06cc\u0646\u06a9 \u06a9\u06be\u0627\u062a\u0648\u06ba \u06a9\u06cc \u062d\u0641\u0627\u0638\u062a \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 \u0644\u06cc\u062c\u0631 \u0622\u067e \u06a9\u06cc \u0633\u0645\u062c\u06be \u06a9\u06cc \u062d\u0641\u0627\u0638\u062a \u06a9\u0631\u062a\u0627 \u06c1\u06d2 \u06a9\u06c1 \u06a9\u06cc\u0627 \u06c1\u0648\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0632\u06cc\u0627\u062f\u06c1 \u062a\u0631 \u0679\u06cc\u0645\u06cc\u06ba \u0688\u06cc\u0628\u06af\u0646\u06af \u06a9\u06d2 \u0644\u06cc\u06d2 \u0644\u0627\u06af \u0627\u0646 \u06a9\u0631\u062a\u06cc \u06c1\u06cc\u06ba\u06d4 \u0627\u06cc\u06a9 \u0645\u0633\u0626\u0644\u06c1 \u06c1\u0648\u0646\u06d2 \u06a9\u06d2 \u0628\u0639\u062f\u060c \u0622\u067e \u062c\u0627\u0646\u0646\u0627 \u0686\u0627\u06c1\u062a\u06d2 \u06c1\u06cc\u06ba \u06a9\u06c1 \u06a9\u06cc\u0627 \u063a\u0644\u0637 \u06c1\u0648\u0627 \u06c1\u06d2\u06d4 \u0644\u06cc\u062c\u0631\u0632 \u06a9\u06d2 \u0645\u062e\u062a\u0644\u0641 \u0645\u0642\u0627\u0635\u062f \u06c1\u0648\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 \u06cc\u06c1 \u06af\u0648\u0631\u0646\u0646\u0633 \u06c1\u06d2\u06d4 \u06c1\u0631 \u0642\u0637\u0627\u0631 \u062b\u0627\u0628\u062a \u06a9\u0631\u062a\u06cc \u06c1\u06d2 \u06a9\u06c1 \u0622\u06cc\u0627 \u0644\u0648\u067e \u062d\u062f\u0648\u062f \u06a9\u06d2 \u0627\u0646\u062f\u0631 \u0631\u06c1\u0627\u060c \u0622\u06cc\u0627 \u0646\u06c1\u06cc\u06ba\u060c \u0627\u0648\u0631 \u0628\u0627\u0644\u06a9\u0644 \u06a9\u0628\u06d4<\/p>\n<pre><code class=\"language-python\"># ledger.py\nfrom ledger import Ledger\n\nledger = Ledger(db_path=\"ledger.db\")\nledger.write(\n    session_id=spec.session_id,\n    turn_count=1,\n    state_origin=\"llm\",\n    input_str=task,\n    token_delta=523,\n    execution_time_ms=1240,\n    pass_fail=True,\n)\n<\/code><\/pre>\n<p>\u0627\u06cc\u06a9 \u0644\u0627\u0626\u0646 \u0641\u06cc \u0645\u0648\u0691\u06d4 \u0635\u0631\u0641 \u0634\u0627\u0645\u0644 \u06a9\u0631\u06cc\u06ba\u060c \u06a9\u0648\u0626\u06cc \u0627\u067e \u0688\u06cc\u0679 \u0646\u06c1\u06cc\u06ba\u060c \u06a9\u0648\u0626\u06cc \u062d\u0630\u0641 \u0646\u06c1\u06cc\u06ba\u06d4 \u0639\u062f\u0645 \u062a\u063a\u06cc\u0631 \u06a9\u0644\u06cc\u062f \u06c1\u06d2\u06d4 \u062c\u0633 \u0644\u06cc\u062c\u0631 \u0645\u06cc\u06ba \u062a\u0631\u0645\u06cc\u0645 \u06a9\u06cc \u062c\u0627 \u0633\u06a9\u062a\u06cc \u06c1\u06d2 \u0648\u06c1 \u0646\u0648\u0679 \u0628\u06a9 \u06c1\u06d2\u060c \u0644\u06cc\u062c\u0631 \u0646\u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u0633\u06a9\u06cc\u0645\u0627:<\/p>\n<pre><code class=\"language-sql\">CREATE TABLE IF NOT EXISTS ledger (\n    id                 INTEGER PRIMARY KEY AUTOINCREMENT,\n    session_id         TEXT    NOT NULL,\n    turn_count         INTEGER NOT NULL,\n    state_origin       TEXT    NOT NULL,\n    input_hash         TEXT    NOT NULL,\n    token_delta        INTEGER NOT NULL,\n    execution_time_ms  INTEGER NOT NULL,\n    pass_fail          INTEGER NOT NULL,  -- 1=pass, 0=fail\n    breach_reason      TEXT,              -- NULL unless circuit breaker fired\n    created_at         TEXT    NOT NULL   -- ISO 8601, UTC\n);\nCREATE INDEX IF NOT EXISTS idx_ledger_session ON ledger(session_id);\n<\/code><\/pre>\n<p>\u062c\u0633\u0648 \u0628\u0646\u0627\u062a\u0627 \u06c1\u06d2\u06d4 <code>get_session(session_id)<\/code> &#8211; \u0628\u0646\u06cc\u0627\u062f\u06cc \u067e\u0691\u06be\u0646\u06d2 \u06a9\u0627 \u0631\u0627\u0633\u062a\u06c1 &#8211; \u062c\u06cc\u0633\u0627 \u06a9\u06c1 \u0644\u06cc\u062c\u0631 \u0628\u0691\u06be\u062a\u0627 \u06c1\u06d2 \u0645\u0633\u0644\u0633\u0644 \u062a\u0644\u0627\u0634\u06d4<\/p>\n<p>\u0648\u0636\u0627\u062d\u062a \u06a9\u06d2 \u0642\u0627\u0628\u0644 \u062a\u06cc\u0646 \u0641\u06cc\u0635\u0644\u06d2:<\/p>\n<ol>\n<li>\n<p><code>input_hash<\/code> <strong>~ \u0646\u06c1\u06cc\u06ba<\/strong> <code>input_text<\/code><strong>.<\/strong> \u062e\u0627\u0645 \u0627\u0646 \u067e\u0679 \u0633\u0679\u0631\u0646\u06af\u0632 \u0628\u0631\u0642\u0631\u0627\u0631 \u0646\u06c1\u06cc\u06ba \u06c1\u06cc\u06ba\u06d4 \u0635\u0631\u0641 SHA-256 \u06c1\u06cc\u0634\u0632 \u0642\u0628\u0648\u0644 \u06a9\u06cc \u062c\u0627\u062a\u06cc \u06c1\u06cc\u06ba\u06d4 \u0627\u0633 \u06a9\u06d2 \u062f\u0648 \u0641\u0627\u0626\u062f\u06d2 \u06c1\u06cc\u06ba: \u067e\u0648\u0631\u06d2 \u0639\u0645\u0644 \u0645\u06cc\u06ba \u0627\u06cc\u06a9 \u06c1\u06cc \u0627\u0646 \u067e\u0679 \u06a9\u0627 \u067e\u062a\u06c1 \u0644\u06af\u0627\u06cc\u0627 \u062c\u0627 \u0633\u06a9\u062a\u0627 \u06c1\u06d2 \u0627\u0648\u0631 \u0622\u0688\u0679 \u0679\u0631\u06cc\u0644 \u0645\u06cc\u06ba \u06a9\u0648\u0626\u06cc PII \u062f\u0627\u062e\u0644 \u0646\u06c1\u06cc\u06ba \u06a9\u06cc\u0627 \u062c\u0627\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<\/li>\n<li>\n<p><code>pass_fail<\/code> <strong>\u067e\u0633\u0646\u062f<\/strong> <code>INTEGER<\/code> <strong>~ \u0646\u06c1\u06cc\u06ba<\/strong> <code>BOOLEAN<\/code><strong>.<\/strong> SQLite \u0645\u06cc\u06ba \u06a9\u0648\u0626\u06cc \u0628\u0648\u0644\u06cc\u0646 \u0642\u0633\u0645 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4 <code>1<\/code> \u0627\u0648\u0631 <code>0<\/code> \u06cc\u06c1 \u0633\u0631\u06a9\u0627\u0631\u06cc \u06c1\u06d2\u06d4 API \u06a9\u06d2 \u06a9\u0646\u0627\u0631\u06d2 \u067e\u0631 Python ergonomics \u06a9\u0648 \u0635\u0627\u0641 \u06a9\u0631\u06cc\u06ba \u0627\u0648\u0631 \u0688\u0633\u06a9 \u067e\u0631 SQL \u06a9\u06cc \u0642\u0633\u0645\u06cc\u06ba \u0679\u06be\u06cc\u06a9 \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<\/li>\n<li>\n<p><code>created_at<\/code> <strong>\u067e\u0633\u0646\u062f<\/strong> <code>datetime.now(timezone.utc).isoformat()<\/code><strong>.<\/strong> <code>datetime.utcnow()<\/code>    Python 3.12 \u0645\u06cc\u06ba \u0641\u0631\u0633\u0648\u062f\u06c1\u06d4 \u0679\u0627\u0626\u0645 \u0632\u0648\u0646 \u0633\u06d2 \u0622\u06af\u0627\u06c1 \u0679\u0627\u0626\u0645 \u0627\u0633\u0679\u06cc\u0645\u067e \u0679\u0627\u0626\u0645 \u0632\u0648\u0646 \u06a9\u0648 \u0639\u0628\u0648\u0631 \u06a9\u0631\u0646\u06d2 \u0648\u0627\u0644\u06d2 \u06a9\u0633\u06cc \u0628\u06be\u06cc \u0633\u0633\u0679\u0645 \u067e\u0631 \u0641\u0679\u06af\u0646 \u06a9\u0648 \u0631\u0648\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<\/li>\n<\/ol>\n<p>\u0633\u06cc\u0634\u0646 \u06a9\u06d2 \u0644\u062d\u0627\u0638 \u0633\u06d2 \u062a\u0644\u0627\u0634 \u06a9\u0631\u06cc\u06ba:<\/p>\n<pre><code class=\"language-python\">rows = ledger.get_session(spec.session_id)\nfor row in rows:\n    print(f\"Turn {row.turn_count}: {'PASS' if row.pass_fail else 'FAIL'} \"\n          f\"| {row.token_delta} tokens | {row.execution_time_ms}ms\")\n<\/code><\/pre>\n<h2 id=\"heading-phase-4-the-loop-that-respects-its-boundaries\">\u0645\u0631\u062d\u0644\u06c1 4: \u062d\u062f\u0648\u062f \u06a9\u0627 \u0627\u062d\u062a\u0631\u0627\u0645 \u06a9\u0631\u062a\u06d2 \u06c1\u0648\u0626\u06d2 \u0644\u0648\u067e<\/h2>\n<p>\u0627\u06cc\u062c\u0646\u0679 \u0644\u0648\u067e \u062a\u06cc\u0646 \u067e\u0631\u0627\u0626\u0645\u06cc\u0679\u0648\u0632 \u06a9\u0648 \u0627\u06cc\u06a9 \u0633\u0627\u062a\u06be \u062c\u0648\u0691\u062a\u0627 \u06c1\u06d2\u06d4 \u06cc\u06c1 \u0648\u0627\u062d\u062f \u062c\u0632\u0648 \u06c1\u06d2 \u062c\u0648 \u0627\u06cc\u0644 \u0627\u06cc\u0644 \u0627\u06cc\u0645 \u06a9\u06c1\u062a\u0627 \u06c1\u06d2\u06d4 \u0628\u0627\u0642\u06cc \u0633\u0628 \u06a9\u0686\u06be \u0645\u0642\u0627\u0645\u06cc \u06c1\u06d2\u06d4<\/p>\n<pre><code class=\"language-python\"># agent_loop.py\nfrom agent_loop import AgentLoop\n\nloop = AgentLoop(spec, breaker, ledger, client)\nresult = loop.run(task)\n# LoopResult(success, turns, total_tokens, session_id, breach_reason)\n<\/code><\/pre>\n<p>\u0645\u0648\u0691 \u06a9\u06cc \u0633\u0627\u062e\u062a \u06a9\u0648 \u0645\u0646\u062f\u0631\u062c\u06c1 \u0630\u06cc\u0644 \u062a\u0631\u062a\u06cc\u0628 \u0645\u06cc\u06ba \u0628\u06cc\u0627\u0646 \u06a9\u06cc\u0627 \u06af\u06cc\u0627 \u06c1\u06d2\u06d4<\/p>\n<ol>\n<li>\n<p><code>circuit_breaker.check(turn_count, accumulated_tokens)<\/code>    &#8211; \u0627\u06af\u0631 \u0622\u067e \u062d\u062f \u0633\u06d2 \u062a\u062c\u0627\u0648\u0632 \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba \u062a\u0648 \u06cc\u06c1 \u0628\u0691\u06be \u062c\u0627\u0626\u06d2 \u06af\u0627\u06d4<\/p>\n<\/li>\n<li>\n<p><code>client.messages.create(...)<\/code>    &#8211; \u0627\u06cc\u06a9 \u062d\u0642\u06cc\u0642\u06cc LLM \u06a9\u0627\u0644<\/p>\n<\/li>\n<li>\n<p><code>ledger.write(...)<\/code>    &#8211; 1 \u0642\u0637\u0627\u0631\u060c \u0635\u0631\u0641 \u0634\u0627\u0645\u0644 \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<\/li>\n<li>\n<p>\u0627\u06af\u0631 <code>stop_reason == \"end_turn\"<\/code>\u0648\u0627\u067e\u0633\u06cc \u0648\u0631\u0646\u06c1 \u0644\u0648\u067e.<\/p>\n<\/li>\n<\/ol>\n<p>\u06c1\u0645 \u0628\u063a\u06cc\u0631 \u06a9\u0633\u06cc \u0627\u0633\u062a\u062b\u0646\u0627\u0621 \u06a9\u06d2 \u06c1\u0631 LLM \u06a9\u0627\u0644 \u0633\u06d2 \u067e\u06c1\u0644\u06d2 \u0641\u0644\u0627\u0626\u0679 \u0686\u06cc\u06a9 \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<pre><code class=\"language-python\">def run(self, task: str) -> LoopResult:\n    session_id = self.spec.session_id\n    messages: list[dict] = [{\"role\": \"user\", \"content\": task}]\n    turn = 0\n    total_tokens = 0\n\n    try:\n        while True:\n            turn += 1\n            self.circuit_breaker.check(turn, total_tokens)\n\n            started = time.perf_counter()\n            response = self.client.messages.create(\n                model=self.model,\n                max_tokens=self.max_tokens,\n                system=self._system_prompt(),\n                messages=messages,\n            )\n            elapsed_ms = int((time.perf_counter() - started) * 1000)\n\n            turn_tokens = (\n                getattr(response.usage, \"input_tokens\", 0)\n                + getattr(response.usage, \"output_tokens\", 0)\n            )\n            total_tokens += turn_tokens\n\n            text = self._text_from(response)\n            messages.append({\"role\": \"assistant\", \"content\": text})\n\n            self.ledger.write(\n                session_id=session_id,\n                turn_count=turn,\n                state_origin=\"llm\",\n                input_str=task,\n                token_delta=turn_tokens,\n                execution_time_ms=elapsed_ms,\n                pass_fail=True,\n            )\n\n            if getattr(response, \"stop_reason\", \"end_turn\") == \"end_turn\":\n                return LoopResult(\n                    success=True,\n                    turns=turn,\n                    total_tokens=total_tokens,\n                    session_id=session_id,\n                )\n\n            messages.append({\"role\": \"user\", \"content\": \"continue\"})\n\n    except CircuitBreakerError as err:\n        self.ledger.write(\n            session_id=session_id,\n            turn_count=turn,\n            state_origin=\"circuit_breaker\",\n            input_str=task,\n            token_delta=0,\n            execution_time_ms=0,\n            pass_fail=False,\n            breach_reason=err.reason,\n        )\n        return LoopResult(\n            success=False,\n            turns=turn,\n            total_tokens=total_tokens,\n            session_id=session_id,\n            breach_reason=err.reason,\n        )\n\ndef _system_prompt(self) -> str:\n    return (\n        \"You are an agent working on a tightly-scoped task.\\n\\n\"\n        f\"What this does: {self.spec.what_it_does}\\n\"\n        f\"What this does NOT do: {self.spec.what_it_does_not}\\n\"\n        f\"Done looks like: {self.spec.done_looks_like}\\n\"\n    )\n\n@staticmethod\ndef _text_from(response) -> str:\n    content = getattr(response, \"content\", None)\n    if not content:\n        return \"\"\n    block = content[0]\n    return getattr(block, \"text\", \"\") or \"\"\n<\/code><\/pre>\n<p>\u0627\u0633 \u0645\u062a\u0646 \u0645\u06cc\u06ba \u06a9\u0686\u06be \u0627\u062e\u062a\u06cc\u0627\u0631\u0627\u062a \u0642\u0627\u0628\u0644 \u0630\u06a9\u0631 \u06c1\u06cc\u06ba:<\/p>\n<ul>\n<li>\n<p><strong>\u067e\u0648\u0631\u06cc<\/strong> <code>while True:<\/code> <strong>\u0627\u06cc\u06a9 \u06a9\u06d2 \u0637\u0648\u0631 \u067e\u0631 \u067e\u06cc\u06a9 \u06a9\u06cc\u0627<\/strong> <code>try\/except CircuitBreakerError<\/code><strong>.<\/strong> \u0686\u06cc\u06a9 \u06c1\u0631 \u0645\u0648\u0691 \u06a9\u06d2 \u0627\u0648\u067e\u0631 \u06a9\u06cc\u0627 \u062c\u0627\u062a\u0627 \u06c1\u06d2\u060c \u0644\u06c1\u0630\u0627 \u062e\u0644\u0627\u0641 \u0648\u0631\u0632\u06cc \u0627\u0633\u06cc \u0637\u0631\u062d \u067e\u06a9\u0691\u06cc \u062c\u0627\u062a\u06cc \u06c1\u06d2 \u0686\u0627\u06c1\u06d2 \u06cc\u06c1 \u0645\u0648\u0691 1 \u067e\u0631 \u06c1\u0648 \u06cc\u0627 6 \u0645\u0648\u0691 \u067e\u0631\u06d4<\/p>\n<\/li>\n<li>\n<p><code>input_str=task<\/code>    \u06c1\u0631 \u0644\u06cc\u062c\u0631 \u0642\u0637\u0627\u0631 \u067e\u0631 &#8211; \u0627\u0635\u0644 \u0622\u067e\u0631\u06cc\u0634\u0646\u060c \u0622\u062e\u0631\u06cc \u062b\u0627\u0646\u0648\u06cc \u067e\u06cc\u063a\u0627\u0645 \u0646\u06c1\u06cc\u06ba\u06d4 \u06a9\u06c1 <code>input_hash<\/code> \u067e\u06be\u0631 \u06a9\u0627\u0644\u0645 \u0642\u0637\u0627\u0631\u0648\u06ba \u06a9\u0648 \u06af\u0631\u0648\u067e \u06a9\u0631\u062a\u0627 \u06c1\u06d2 \u062c\u0648 \u067e\u06be\u0627\u0646\u0633\u06cc\u0648\u06ba \u0645\u06cc\u06ba \u0627\u06cc\u06a9 \u06c1\u06cc \u0627\u0628\u062a\u062f\u0627\u0626\u06cc \u0627\u0646 \u067e\u0679 \u06a9\u0627 \u0627\u0634\u062a\u0631\u0627\u06a9 \u06a9\u0631\u062a\u06cc \u06c1\u06d2\u06d4<\/p>\n<\/li>\n<li>\n<p><code>pass_fail=True<\/code> <strong>\u06c1\u0631 \u0627\u06cc\u0644 \u0627\u06cc\u0644 \u0627\u06cc\u0645 \u06a9\u06cc \u0628\u0627\u0631\u06cc \u0648\u0627\u067e\u0633\u06cc \u06a9\u06d2 \u0644\u06cc\u06d2<\/strong>, <code>False<\/code> \u0635\u0631\u0641 \u062e\u0644\u0627\u0641 \u0648\u0631\u0632\u06cc \u06a9\u06cc \u0635\u0648\u0631\u062a \u0645\u06cc\u06ba\u06d4 \u067e\u0627\u0633\/\u0641\u06cc\u0644 \u0641\u0644\u06cc\u06af \u0627\u0633 \u0628\u0627\u062a \u067e\u0631 \u0646\u0638\u0631 \u0631\u06a9\u06be\u062a\u0627 \u06c1\u06d2 \u06a9\u06c1 \u0644\u0648\u067e \u0686\u0644 \u0631\u06c1\u0627 \u06c1\u06d2 \u06cc\u0627 \u0646\u06c1\u06cc\u06ba\u06d4 <em>\u067e\u06c1\u0646\u0686 \u06af\u0626\u06d2<\/em> \u06cc\u06c1 \u0627\u0633 \u0628\u0627\u0631\u06d2 \u0645\u06cc\u06ba \u0646\u06c1\u06cc\u06ba \u06c1\u06d2 \u06a9\u06c1 \u0622\u06cc\u0627 \u0645\u0627\u0688\u0644 \u06a9\u0627 \u0622\u0624\u0679 \u067e\u0679 \u0627\u0686\u06be\u0627 \u06c1\u06d2 \u06cc\u0627 \u0646\u06c1\u06cc\u06ba\u060c \u0644\u06cc\u06a9\u0646 \u0622\u06cc\u0627 \u06cc\u06c1 \u0627\u06cc\u06a9 \u062c\u0627\u0626\u0632 \u0642\u0637\u0627\u0631 \u06c1\u06d2\u06d4 \u0645\u0639\u06cc\u0627\u0631 \u06a9\u06cc \u062a\u0634\u062e\u06cc\u0635 \u0627\u06cc\u06a9 \u0627\u0644\u06af \u062a\u0634\u0648\u06cc\u0634 \u06c1\u06d2\u06d4<\/p>\n<\/li>\n<li>\n<p><code>_system_prompt()<\/code> <strong>\u062a\u06cc\u0646\u0648\u06ba \u0648\u0636\u0627\u062d\u062a\u06cc \u0641\u06cc\u0644\u0688\u0632 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u0631\u06cc\u06ba\u06d4<\/strong>\u06c1\u0627\u06ba <code>done_looks_like<\/code>. \u0645\u0627\u0688\u0644 \u0645\u06cc\u06ba \u0645\u0646\u0641\u06cc \u0631\u06cc\u0646\u062c \u06c1\u06d2 (<code>what_it_does_not<\/code>) \u06a9\u0645 \u0627\u0632 \u06a9\u0645 \u062c\u06c1\u0627\u06ba \u062a\u06a9 \u0645\u062b\u0628\u062a \u062d\u062f \u062a\u06a9\u06d4<\/p>\n<\/li>\n<li>\n<p><code>time.perf_counter()<\/code> <strong>~ \u0646\u06c1\u06cc\u06ba<\/strong> <code>time.time()<\/code>    &#8211; \u0646\u06cc\u0631\u0633 \u0627\u0648\u0631 \u0627\u0646\u0679\u0631\u0645\u06cc\u0688\u06cc\u0679 \u0648\u0627\u0644 \u06a9\u0644\u0627\u06a9 \u0627\u06cc\u0688\u062c\u0633\u0679\u0645\u0646\u0679 \u0633\u06d2 \u063a\u06cc\u0631 \u0645\u062a\u0627\u062b\u0631\u06d4<\/p>\n<\/li>\n<\/ul>\n<p><code>LoopResult.session_id<\/code>    \u0633\u06d2 \u0648\u0631\u0627\u062b\u062a \u0645\u06cc\u06ba \u0645\u0644\u0627 \u06c1\u06d2 <code>spec.session_id<\/code>. \u0644\u06cc\u062c\u0631 \u06a9\u06cc \u0642\u0637\u0627\u0631\u06cc\u06ba \u0628\u063a\u06cc\u0631 \u06a9\u0633\u06cc \u062c\u0648\u0691 \u06a9\u06d2 \u062a\u0641\u0635\u06cc\u0644\u0627\u062a \u0633\u06d2 \u0645\u0646\u0633\u0644\u06a9 \u06c1\u06cc\u06ba\u06d4 \u0627\u06cc\u06a9 \u0633\u06cc\u0634\u0646 ID\u060c \u0627\u06cc\u06a9 \u0679\u0631\u06cc\u0633 \u0627\u06cc\u0628\u0644 \u0627\u06cc\u06af\u0632\u06cc\u06a9\u06cc\u0648\u0634\u0646\u060c \u062e\u062a\u0645 \u06c1\u0648\u0646\u0627 \u0634\u0631\u0648\u0639 \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<h2 id=\"heading-phase-5-the-review-surface\">\u0645\u0631\u062d\u0644\u06c1 5: \u0633\u0637\u062d \u06a9\u0627 \u062c\u0627\u0626\u0632\u06c1 \u0644\u06cc\u06ba\u06d4<\/h2>\n<p>\u0633\u0631\u06a9\u0679 \u0628\u0631\u06cc\u06a9\u0631 \u0622\u067e \u06a9\u06d2 \u0628\u06cc\u0646\u06a9 \u06a9\u06be\u0627\u062a\u0648\u06ba \u06a9\u06cc \u062d\u0641\u0627\u0638\u062a \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 \u0644\u06cc\u062c\u0631 \u0631\u06cc\u06a9\u0627\u0631\u0688 \u06a9\u0631\u062a\u0627 \u06c1\u06d2 \u06a9\u06c1 \u06a9\u06cc\u0627 \u06c1\u0648\u0627\u06d4 \u0644\u06cc\u06a9\u0646 \u0646\u06c1 \u06c1\u06cc \u0622\u067e \u06a9\u0648 \u06cc\u06c1 \u0628\u062a\u0627\u062a\u0627 \u06c1\u06d2 \u06a9\u06c1 \u06a9\u06cc\u0627 \u0648\u06c1\u06cc \u06c1\u0648\u0627 \u062c\u0633 \u06a9\u0627 \u0648\u0639\u062f\u06c1 \u06a9\u06cc\u0627 \u06af\u06cc\u0627 \u062a\u06be\u0627\u06d4<\/p>\n<p>\u0648\u06c1 \u062e\u0644\u0627 \u06c1\u06d2 \u062c\u06c1\u0627\u06ba \u063a\u0644\u0637 \u0644\u0648\u067e \u06a9\u0648 \u0642\u0628\u0648\u0644 \u06a9\u06cc\u0627 \u062c\u0627\u062a\u0627 \u06c1\u06d2\u06d4 \u067e\u0627\u0644\u0634 \u0622\u0624\u0679 \u067e\u0679\u060c \u06af\u0631\u06cc\u0646 \u0688\u06cc\u0634 \u0628\u0648\u0631\u0688\u060c \u0627\u067e\u0646\u06d2 \u0648\u0639\u062f\u0648\u06ba \u06a9\u0648 \u067e\u0648\u0631\u0627 \u06a9\u0631\u0646\u06d2 \u0645\u06cc\u06ba \u0646\u0627\u06a9\u0627\u0645 \u0631\u06c1\u0627\u06d4 \u062c\u0627\u0626\u0632\u06c1 \u0644\u06cc\u0646\u06d2 \u0648\u0627\u0644\u0627 \u0646\u0645\u0648\u0646\u06d2 \u06a9\u0648 \u062f\u06cc\u06a9\u06be\u062a\u0627 \u06c1\u06d2\u060c \u0627\u0633 \u06a9\u06d2 \u0645\u0646\u0627\u0633\u0628 \u06c1\u0648\u0646\u06d2 \u06a9\u0627 \u062a\u0639\u06cc\u0646 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u060c \u0627\u0648\u0631 \u0627\u0633\u06d2 \u0645\u0646\u0638\u0648\u0631 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4 \u06a9\u0633\u06cc \u0646\u06d2 \u06cc\u06c1 \u0646\u06c1\u06cc\u06ba \u067e\u0648\u0686\u06be\u0627 \u06a9\u06c1 \u06a9\u06cc\u0627 \u0627\u0635\u0644 \u0648\u0639\u062f\u06c1 \u067e\u0648\u0631\u0627 \u06c1\u0648\u0627\u061f<\/p>\n<p>\u0627\u0633 \u062e\u0644\u0627 \u06a9\u0648 \u0628\u0646\u062f \u06a9\u0631\u0646\u06d2 \u0648\u0627\u0644\u06cc \u0633\u0637\u062d\u0648\u06ba \u06a9\u0627 \u062c\u0627\u0626\u0632\u06c1 \u0644\u06cc\u06ba\u06d4 SQLite \u0633\u06cc\u0634\u0646 \u06a9\u0648 \u067e\u0691\u06be\u062a\u0627 \u06c1\u06d2\u060c \u067e\u0627\u0646\u0686 \u0639\u0646\u0627\u0635\u0631 \u06a9\u0627 \u0627\u06cc\u06a9 \u0641\u0631\u06cc\u0645 \u062c\u0645\u0639 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u060c \u0627\u0648\u0631 \u0688\u0627\u0648\u0646 \u0627\u0633\u0679\u0631\u06cc\u0645 \u06a9\u0648 \u0622\u0624\u0679 \u067e\u0679 \u062d\u0627\u0635\u0644 \u06a9\u0631\u0646\u06d2 \u0633\u06d2 \u067e\u06c1\u0644\u06d2 \u0645\u0648\u0627\u0632\u0646\u06c1 \u067e\u0631 \u0645\u062c\u0628\u0648\u0631 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<pre><code class=\"language-python\">from review_surface import ReviewSurface\n\nrs = ReviewSurface(spec_db_path=\"spec.db\", ledger_db_path=\"ledger.db\")\nprint(rs.render(session_id))\n<\/code><\/pre>\n<p>\u0641\u0631\u06cc\u0645 5 \u0639\u0646\u0627\u0635\u0631 \u067e\u0631 \u0645\u0634\u062a\u0645\u0644 \u06c1\u06d2:<\/p>\n<ol>\n<li>\n<p><strong>\u0627\u0635\u0644 \u0648\u0639\u062f\u06c1<\/strong> \u2014 \u0645\u062e\u0635\u0648\u0635 \u062c\u062f\u0648\u0644 \u0633\u06d2 \u0644\u06cc\u0627 \u06af\u06cc\u0627: \u06cc\u06c1 \u06a9\u06cc\u0627 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u060c \u06a9\u06cc\u0627 \u0646\u06c1\u06cc\u06ba \u06a9\u0631\u062a\u0627\u060c \u0627\u0648\u0631 \u062c\u0628 \u06cc\u06c1 \u06c1\u0648 \u062c\u0627\u062a\u0627 \u06c1\u06d2 \u062a\u0648 \u06a9\u06cc\u0633\u0627 \u0644\u06af\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<\/li>\n<li>\n<p><strong>\u067e\u0627\u0633 \u06a9\u0631\u0646\u06d2 \u06a9\u0627 \u0645\u0639\u06cc\u0627\u0631<\/strong> &#8211; <code>done_looks_like<\/code> \u0648\u0627\u0636\u062d \u0628\u06cc\u0646\u0686 \u0645\u0627\u0631\u06a9\u0633 \u06a9\u06d2 \u0633\u0627\u062a\u06be \u067e\u06cc\u0634 \u06a9\u0631\u062f\u06c1 \u0641\u06cc\u0644\u0688\u0632<\/p>\n<\/li>\n<li>\n<p><strong>\u0641\u0631\u0642<\/strong> &#8211; \u067e\u06c1\u0644\u0627 \u0645\u0648\u0691 \u0627\u0646 \u067e\u0679 \u0628\u0645\u0642\u0627\u0628\u0644\u06c1 \u0622\u062e\u0631\u06cc \u0628\u0627\u0631\u06cc \u0622\u0624\u0679 \u067e\u0679\u060c \u0645\u0648\u0691 \u0645\u06a9\u0645\u0644\u060c \u06a9\u0644 \u0679\u0648\u06a9\u0646\u060c \u0644\u0648\u067e \u06a9\u06cc \u062e\u0644\u0627\u0641 \u0648\u0631\u0632\u06cc \u06cc\u0627 \u0646\u06c1\u06cc\u06ba<\/p>\n<\/li>\n<li>\n<p><strong>\u062b\u0628\u0648\u062a<\/strong> \u2014 \u0633\u06cc\u0634\u0646 \u0645\u06cc\u06ba \u0644\u06cc\u062c\u0631 \u06a9\u06cc \u062a\u0645\u0627\u0645 \u0642\u0637\u0627\u0631\u06cc\u06ba: \u0645\u0631\u062d\u0644\u06c1 \u067e\u0627\u0633\/\u0641\u06cc\u0644\u060c \u0679\u0648\u06a9\u0646 \u0688\u06cc\u0644\u0679\u0627\u060c \u0639\u0645\u0644 \u062f\u0631\u0622\u0645\u062f \u06a9\u0627 \u0648\u0642\u062a<\/p>\n<\/li>\n<li>\n<p><strong>\u063a\u06cc\u0631 \u062d\u0644 \u0634\u062f\u06c1 \u0645\u0641\u0631\u0648\u0636\u06d2\u06d4<\/strong> \u2014 \u062e\u0644\u0627\u0641 \u0648\u0631\u0632\u06cc \u06a9\u0631\u0646\u06d2 \u0648\u0627\u0644\u06cc \u0642\u0637\u0627\u0631\u0648\u06ba \u0627\u0648\u0631 \u0646\u0627\u06a9\u0627\u0645 \u06af\u0631\u062f\u0634\u0648\u06ba \u0633\u06d2 \u0645\u0627\u062e\u0648\u0630\u06d4 \u062c\u0628 \u06cc\u06c1 \u0635\u0627\u0641 \u06c1\u0648 \u062c\u0627\u0626\u06d2 \u062a\u0648 \u0627\u0633\u06d2 \u062e\u0627\u0644\u06cc \u0686\u06be\u0648\u0691 \u062f\u06cc\u06ba\u06d4<\/p>\n<\/li>\n<\/ol>\n<p>\u062c\u0627\u0626\u0632\u06c1 \u0644\u06cc\u0646\u06d2 \u0648\u0627\u0644\u06d2 \u06a9\u06d2 \u0627\u0637\u0645\u06cc\u0646\u0627\u0646 \u067e\u0631\u060c \u06c1\u0645 \u062a\u0635\u062f\u06cc\u0642 \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba \u06a9\u06c1:<\/p>\n<pre><code class=\"language-python\">attestation = rs.attest(\n    session_id=result.session_id,\n    reviewer=\"daniel\",\n    notes=\"Output matches spec. Approved.\"\n)\nprint(attestation.frame_hash)\n<\/code><\/pre>\n<p><code>.attest()<\/code>    \u06a9\u0648 \u0644\u06a9\u06be\u06cc\u06ba\u06d4 <code>attestations<\/code> \u0645\u06cc\u06ba \u0645\u06cc\u0632 <code>ledger.db<\/code>. \u06a9\u06c1 <code>frame_hash<\/code> \u0627\u06cc\u06a9 \u06c1\u06cc \u0633\u06cc\u0634\u0646 \u06a9\u06cc \u062a\u0648\u062b\u06cc\u0642 \u06a9\u0631\u0646\u06d2 \u0648\u0627\u0644\u06d2 \u062c\u0627\u0626\u0632\u06c1 \u0644\u06cc\u0646\u06d2 \u0648\u0627\u0644\u0648\u06ba \u06a9\u06d2 \u062f\u0631\u0645\u06cc\u0627\u0646 \u062d\u062a\u0645\u06cc \u0641\u0631\u06cc\u0645 \u0634\u062f\u06c1 \u0688\u06cc\u0679\u0627 \u06a9\u0627 SHA-256\u06d4 \u06cc\u06c1 \u0634\u06a9\u0631\u06cc\u06c1 \u06a9\u06cc \u0631\u0633\u06cc\u062f \u06c1\u06d2\u06d4 \u0627\u0633 \u0633\u06d2 \u062b\u0627\u0628\u062a \u06c1\u0648\u062a\u0627 \u06c1\u06d2 \u06a9\u06c1 \u062c\u0627\u0626\u0632\u06c1 \u0644\u06cc\u0646\u06d2 \u0648\u0627\u0644\u06d2 \u0646\u06d2 \u0628\u0627\u0644\u06a9\u0644 \u0679\u06be\u06cc\u06a9 \u0641\u0631\u06cc\u0645 \u06a9\u0648 \u067e\u06cc\u0634 \u06a9\u0631\u062f\u06c1 \u06a9\u06d2 \u0637\u0648\u0631 \u067e\u0631 \u062f\u06cc\u06a9\u06be\u0627\u060c \u062e\u0644\u0627\u0635\u06c1 \u06cc\u0627 \u067e\u06cc\u0631\u0627 \u0641\u0631\u06cc\u0633 \u0646\u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u0645\u0646\u0638\u0648\u0631\u06cc \u0627\u0633 \u0628\u0627\u062a \u06a9\u06cc \u062a\u0635\u062f\u06cc\u0642 \u06a9\u0631\u062a\u06cc \u06c1\u06d2 \u06a9\u06c1 \u0639\u0645\u0644 \u0645\u06a9\u0645\u0644 \u06c1\u0648 \u06af\u06cc\u0627 \u06c1\u06d2\u06d4 \u062a\u0635\u062f\u06cc\u0642 \u0627\u0633 \u0628\u0627\u062a \u06a9\u06cc \u062a\u0635\u062f\u06cc\u0642 \u06a9\u0631\u062a\u06cc \u06c1\u06d2 \u06a9\u06c1 \u062c\u0627\u0626\u0632\u06c1 \u0644\u06cc\u0646\u06d2 \u0648\u0627\u0644\u06d2 \u0646\u06d2 \u0648\u0639\u062f\u06d2 \u06a9\u06d2 \u0633\u0627\u062a\u06be \u0622\u0624\u0679 \u067e\u0679 \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u06cc\u0627 \u06c1\u06d2\u06d4 \u0627\u06cc\u06a9 \u0628\u0627\u0631 \u062c\u0628 \u0644\u0648\u067e \u06a9\u0633\u06cc \u0631\u06cc\u06af\u0648\u0644\u06cc\u0679\u0688 \u06c1\u0633\u062a\u06cc \u06a9\u0648 \u0686\u06be\u0648\u062a\u0627 \u06c1\u06d2\u060c \u062a\u0648 \u06cc\u06c1 \u0627\u06cc\u06a9 \u0645\u062e\u062a\u0644\u0641 \u0642\u0627\u0646\u0648\u0646\u06cc \u062f\u0633\u062a\u0627\u0648\u06cc\u0632 \u06c1\u0648\u062a\u06cc \u06c1\u06d2\u06d4<\/p>\n<pre><code class=\"language-python\">@dataclass(frozen=True)\nclass ReviewFrame:\n    session_id: str\n    original_promise: SpecResult\n    acceptance_criteria: str\n    diff: DiffResult\n    evidence: tuple  # tuple[LedgerRow, ...]\n    unresolved_assumptions: tuple  # tuple[str, ...]\n    created_at: str\n<\/code><\/pre>\n<p><code>ReviewFrame<\/code>    \u0627\u0633\u06cc \u0648\u062c\u06c1 \u0633\u06d2 \u0627\u0633\u06d2 \u0645\u0646\u062c\u0645\u062f \u06a9\u06cc\u0627 \u06af\u06cc\u0627 \u062a\u06be\u0627\u06d4 <code>SpecResult<\/code> &#8211; \u0641\u0631\u06cc\u0645 \u0627\u06cc\u06a9 \u062b\u0628\u0648\u062a \u06c1\u06d2\u060c \u0645\u0633\u0648\u062f\u06c1 \u0646\u06c1\u06cc\u06ba\u06d4 <code>evidence<\/code> \u0627\u0648\u0631 <code>unresolved_assumptions<\/code> \u0641\u06c1\u0631\u0633\u062a\u06cc\u06ba \u0679\u06cc\u067e\u0644\u0632 \u06c1\u06cc\u06ba \u06a9\u06cc\u0648\u0646\u06a9\u06c1 \u0648\u06c1 \u06c1\u06cc\u0634 \u0627\u06cc\u0628\u0644 \u0646\u06c1\u06cc\u06ba \u06c1\u06cc\u06ba \u0627\u0648\u0631 \u0641\u06a9\u0633\u0688 \u0688\u06cc\u0679\u0627 \u06a9\u0644\u0627\u0633\u0632 \u06a9\u0648 \u06c1\u06cc\u0634 \u0627\u06cc\u0628\u0644 \u0641\u06cc\u0644\u0688\u0632 \u06a9\u06cc \u0636\u0631\u0648\u0631\u062a \u06c1\u0648\u062a\u06cc \u06c1\u06d2\u06d4<\/p>\n<p>\u062c\u0627\u0626\u0632\u06c1 \u0627\u0633\u06a9\u0631\u06cc\u0646 \u06a9\u06d2 \u0630\u0631\u06cc\u0639\u06d2 \u0645\u06a9\u0645\u0644 \u0627\u062e\u062a\u062a\u0627\u0645 \u0633\u06d2 \u0622\u062e\u0631 \u062a\u06a9 \u0628\u06c1\u0627\u0624 \u0645\u0646\u062f\u0631\u062c\u06c1 \u0630\u06cc\u0644 \u06c1\u06d2: <code>examples\/review_example.py<\/code> \u0631\u06cc\u067e\u0648 \u0633\u06d2\u06d4 \u0633\u06cc\u0634\u0646 \u0645\u06a9\u0645\u0644 \u06c1\u0648\u0646\u06d2 \u06a9\u06d2 \u0628\u0639\u062f \u0686\u0644\u062a\u0627 \u06c1\u06d2\u06d4 \u06cc\u06c1 \u067e\u0627\u0646\u0686 \u0639\u0646\u0627\u0635\u0631 \u06a9\u0627 \u0641\u0631\u06cc\u0645 \u067e\u06cc\u0634 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u060c \u062b\u0628\u0648\u062a \u06a9\u06cc \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u060c \u0627\u0648\u0631 \u0627\u06af\u0631 \u0645\u0646\u0638\u0648\u0631 \u06c1\u0648 \u062c\u0627\u0626\u06d2 \u062a\u0648 \u0627\u06cc\u06a9 \u0631\u0633\u06cc\u062f \u0628\u0646\u0627\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0644\u0648\u067e \u0622\u067e \u06a9\u06cc \u0637\u0631\u0641 \u062f\u0648\u0691\u062a\u0627 \u06c1\u06d2\u06d4 \u0688\u0627\u0624\u0646 \u0627\u0633\u0679\u0631\u06cc\u0645 \u0633\u0633\u0679\u0645 \u06a9\u0648 \u0627\u0633 \u0648\u0642\u062a \u062a\u06a9 \u06a9\u0686\u06be \u0646\u06c1\u06cc\u06ba \u0645\u0644\u062a\u0627 \u062c\u0628 \u062a\u06a9 \u06a9\u0648\u0626\u06cc \u062f\u0633\u062a\u062e\u0637 \u0646\u06c1 \u06a9\u0631\u06d2\u06d4<\/p>\n<h2 id=\"heading-phase-6-a-real-example-seo-audit-agent\">\u0645\u0631\u062d\u0644\u06c1 6: \u062d\u0642\u06cc\u0642\u06cc \u062f\u0646\u06cc\u0627 \u06a9\u06cc \u0645\u062b\u0627\u0644\u06cc\u06ba \u2014 SEO \u0622\u0688\u06cc\u0679\u0631\u0632<\/h2>\n<p>\u067e\u06cc\u0679\u0631\u0646 \u0635\u0631\u0641 \u062d\u0642\u06cc\u0642\u06cc \u0645\u0633\u0627\u0626\u0644 \u06a9\u06d2 \u0644\u06cc\u06d2 \u0645\u0639\u0646\u06cc \u0631\u06a9\u06be\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 \u06cc\u06c1 \u0645\u06cc\u0631\u06d2 SEO-\u0627\u06cc\u062c\u0646\u0679 \u067e\u0631\u0648\u062c\u06cc\u06a9\u0679 \u06a9\u06d2 \u067e\u06cc\u0686\u06be\u06d2 \u0648\u06c1\u06cc \u0627\u06cc\u062c\u0646\u0679 \u0641\u0646 \u062a\u0639\u0645\u06cc\u0631 \u06c1\u06d2\u06d4<\/p>\n<p>SEO \u0622\u0688\u0679 \u06a9\u0627 \u0627\u06cc\u06a9 \u0641\u0637\u0631\u06cc \u0628\u06c1\u0627\u0624 \u06c1\u0648\u062a\u0627 \u06c1\u06d2: \u0631\u06cc\u0646\u06af\u0646\u0627\u060c \u0679\u0648\u0679\u06d2 \u06c1\u0648\u0626\u06d2 \u062d\u0635\u0648\u06ba \u06a9\u0648 \u0633\u0631\u0641\u06cc\u0633 \u06a9\u0631\u0646\u0627\u060c \u0627\u0646\u06c1\u06cc\u06ba \u0679\u06be\u06cc\u06a9 \u06a9\u0631\u0646\u0627\u060c \u0627\u0648\u0631 \u0627\u0646 \u06a9\u06d2 \u062f\u0648\u0628\u0627\u0631\u06c1 \u0627\u0646\u0688\u06cc\u06a9\u0633 \u06c1\u0648\u0646\u06d2 \u06a9\u0627 \u0627\u0646\u062a\u0638\u0627\u0631 \u06a9\u0631\u0646\u0627\u06d4 \u0627\u06cc\u062c\u0646\u0679 \u06a9\u0648 \u0645\u0633\u0644\u0633\u0644 \u0686\u0644\u0627\u0646\u06d2 \u0633\u06d2 \u0627\u0633 \u06a9\u0627 \u0686\u06a9\u0631 \u062a\u0628\u062f\u06cc\u0644 \u0646\u06c1\u06cc\u06ba \u06c1\u0648\u062a\u0627 \u06c1\u06d2\u06d4 \u0622\u067e \u0635\u0631\u0641 \u0627\u06c1\u0645 \u0644\u0645\u062d\u0627\u062a \u06a9\u06d2 \u062f\u0631\u0645\u06cc\u0627\u0646 \u062e\u0627\u0644\u06cc \u062c\u06af\u06c1 \u067e\u0631 \u0679\u0648\u06a9\u0646 \u062c\u0644\u0627\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 \u0644\u0648\u067e \u0645\u06cc\u06ba \u062c\u06a9\u0691\u06d2 \u06c1\u0648\u0626\u06d2 \u06a9\u0631\u0648\u0646 \u062c\u0627\u0628 \u0627\u06cc\u06a9 \u0627\u06cc\u0645\u0627\u0646\u062f\u0627\u0631 \u0641\u0646 \u062a\u0639\u0645\u06cc\u0631 \u06c1\u06d2\u06d4<\/p>\n<pre><code class=\"language-python\"># examples\/seo_audit_example.py\nimport requests\nfrom bs4 import BeautifulSoup\nimport anthropic\nfrom spec_writer import SpecWriter\nfrom circuit_breaker import CircuitBreaker\nfrom ledger import Ledger\nfrom agent_loop import AgentLoop\n\ndef crawl_url(url: str) -> str:\n    response = requests.get(url, timeout=10)\n    soup = BeautifulSoup(response.text, \"html.parser\")\n    title = soup.find(\"title\")\n    meta_desc = soup.find(\"meta\", attrs={\"name\": \"description\"})\n    h1_tags = soup.find_all(\"h1\")\n    return (\n        f\"URL: {url}\\n\"\n        f\"Title: {title.text if title else 'MISSING'}\\n\"\n        f\"Meta description: \"\n        f\"{meta_desc['content'] if meta_desc else 'MISSING'}\\n\"\n        f\"H1 count: {len(h1_tags)}\\n\"\n        f\"H1 tags: {[h.text[:50] for h in h1_tags]}\"\n    )\n\ndef run_seo_audit(url: str) -> None:\n    # Step 1: Define done before the loop starts\n    spec = SpecWriter(db_path=\"spec.db\").run()\n\n    # Step 2: Initialise circuit breaker and ledger\n    breaker = CircuitBreaker(turn_limit=5, token_limit=15000)\n    ledger = Ledger(db_path=\"ledger.db\")\n    client = anthropic.Anthropic()\n\n    # Step 3: Crawl the URL\n    site_data = crawl_url(url)\n\n    # Step 4: Run the loop\n    # AgentLoop catches CircuitBreakerError internally and returns\n    # LoopResult(success=False, breach_reason=...). Branch on the\n    # result \u2014 do NOT wrap loop.run() in try\/except CircuitBreakerError.\n    loop = AgentLoop(spec, breaker, ledger, client)\n    result = loop.run(\n        f\"Audit this page for SEO issues:\\n\\n{site_data}\"\n    )\n\n    # Step 5: Print the ledger\n    print(f\"\\nResult: {'SUCCESS' if result.success else 'BREACH'}\")\n    if not result.success:\n        print(f\"Breach reason: {result.breach_reason}\")\n    print(f\"Turns: {result.turns} | Tokens: {result.total_tokens}\")\n    print(\"\\nAudit trail:\")\n    for row in ledger.get_session(result.session_id):\n        status = \"PASS\" if row.pass_fail else \"FAIL\"\n        print(f\"  Turn {row.turn_count}: {status} | \"\n              f\"{row.token_delta} tokens | {row.execution_time_ms}ms\")\n\nif __name__ == \"__main__\":\n    import sys\n    run_seo_audit(sys.argv[1] if len(sys.argv) > 1 else \"https:\/\/example.com\")\n<\/code><\/pre>\n<p>\u0686\u0644\u0627\u0626\u06cc\u06ba:<\/p>\n<pre><code class=\"language-bash\">python examples\/seo_audit_example.py https:\/\/yourdomain.com\n<\/code><\/pre>\n<p>\u0645\u062e\u0635\u0648\u0635 \u0645\u0635\u0646\u0641 \u0627\u06cc\u06a9 \u067e\u06cc\u063a\u0627\u0645 \u062f\u06a9\u06be\u0627\u062a\u0627 \u06c1\u06d2\u06d4 \u0644\u0648\u067e \u0686\u0644\u062a\u0627 \u06c1\u06d2\u060c \u062d\u062f \u0633\u06d2 \u062a\u062c\u0627\u0648\u0632 \u06a9\u0631\u0646\u06d2 \u067e\u0631 \u0633\u0631\u06a9\u0679 \u0628\u0631\u06cc\u06a9\u0631 \u0679\u0631\u067e \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u060c \u0627\u0648\u0631 \u0644\u06cc\u062c\u0631 \u06c1\u0631 \u06af\u0631\u062f\u0634 \u06a9\u0648 \u0631\u06cc\u06a9\u0627\u0631\u0688 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4 \u0622\u0624\u0679 \u067e\u0679 \u0622\u067e \u06a9\u06d2 \u0633\u0627\u0645\u0646\u06d2 \u0622\u062a\u0627 \u06c1\u06d2 \u0627\u0648\u0631 \u0622\u067e \u0641\u06cc\u0635\u0644\u06c1 \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba \u06a9\u06c1 \u06a9\u06cc\u0627 \u0679\u06be\u06cc\u06a9 \u06a9\u0631\u0646\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0644\u0648\u067e \u0622\u067e \u06a9\u06cc \u0637\u0631\u0641 \u062f\u0648\u0691\u062a\u0627 \u06c1\u06d2\u060c \u062c\u06af\u06c1 \u0646\u06c1\u06cc\u06ba\u06d4<\/p>\n<h2 id=\"heading-pluggable-llm-client\">\u067e\u0644\u06af \u0627\u06cc\u0628\u0644 \u0627\u06cc\u0644 \u0627\u06cc\u0644 \u0627\u06cc\u0645 \u06a9\u0644\u0627\u0626\u0646\u0679<\/h2>\n<p>\u0644\u0648\u067e \u0627\u0646 \u062a\u0645\u0627\u0645 \u06a9\u0644\u0627\u0626\u0646\u0679\u0633 \u067e\u0631 \u06a9\u0627\u0645 \u06a9\u0631\u062a\u0627 \u06c1\u06d2 \u062c\u0648 \u0645\u0637\u0645\u0626\u0646 \u06c1\u06cc\u06ba: <code>LLMClient<\/code> \u067e\u0631\u0648\u0679\u0648\u06a9\u0648\u0644 (\u0628\u0630\u0631\u06cc\u0639\u06c1 \u0688\u06cc\u0641\u0627\u0644\u0679 \u0627\u06cc\u0646\u062a\u06be\u0631\u0648\u067e\u06a9)\u06d4 ~20 \u0644\u0627\u0626\u0646 \u0627\u0688\u0627\u067e\u0679\u0631 \u06a9\u06d2 \u0633\u0627\u062a\u06be \u0627\u067e\u0646\u0627 \u0627\u067e\u0646\u0627 \u0644\u0627\u0626\u06cc\u06ba\u06d4<\/p>\n<pre><code class=\"language-python\"># agent_loop.py\nfrom typing import Protocol, runtime_checkable\n\n\n@runtime_checkable\nclass MessagesEndpoint(Protocol):\n    def create(self, *, model: str, max_tokens: int,\n               system: str, messages: list) -> object: ...\n\n\n@runtime_checkable\nclass LLMClient(Protocol):\n    messages: MessagesEndpoint\n<\/code><\/pre>\n<p><code>messages<\/code>    \u06cc\u06c1 \u0627\u06cc\u06a9 \u0645\u062b\u0627\u0644\u06cc \u062e\u0627\u0635\u06cc\u062a \u06c1\u06d2 (\u06af\u06be\u0631\u0648\u06ba \u0648\u0627\u0644\u06cc \u06a9\u0644\u0627\u0633 \u0646\u06c1\u06cc\u06ba) \u06a9\u06cc\u0648\u0646\u06a9\u06c1 \u0627\u0633 \u0637\u0631\u062d \u0627\u0635\u0644 \u0627\u06cc\u0646\u062a\u06be\u0631\u0648\u067e\u06a9 SDK \u0627\u0633\u06d2 \u0628\u06d2 \u0646\u0642\u0627\u0628 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4 <code>anthropic.Anthropic().messages.create(...)<\/code>. \u0627\u0633\u06d2 \u0646\u06cc\u0633\u0679\u0688 \u06a9\u0644\u0627\u0633 \u06a9\u06d2 \u0637\u0648\u0631 \u067e\u0631 \u0645\u0627\u0688\u0644\u0646\u06af \u06a9\u0631\u0646\u06d2 \u06a9\u0627 \u0645\u0637\u0644\u0628 \u06c1\u06d2 \u06a9\u06c1 \u0627\u0635\u0644 \u06a9\u0644\u0627\u0626\u0646\u0679 \u067e\u0631\u0648\u0679\u0648\u06a9\u0648\u0644 \u06a9\u0648 \u0645\u0637\u0645\u0626\u0646 \u0646\u06c1\u06cc\u06ba \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4 \u06a9\u06c1 <code>@runtime_checkable<\/code> \u0688\u06cc\u06a9\u0648\u0631\u06cc\u0679\u0631 \u0622\u067e \u06a9\u0648 \u0645\u0637\u0627\u0628\u0642\u062a \u0628\u0631\u0642\u0631\u0627\u0631 \u0631\u06a9\u06be\u0646\u06d2 \u06a9\u0648 \u06cc\u0642\u06cc\u0646\u06cc \u0628\u0646\u0627\u0646\u06d2 \u06a9\u06cc \u0627\u062c\u0627\u0632\u062a \u062f\u06cc\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 <code>isinstance(client, LLMClient)<\/code>\u0631\u06cc\u067e\u0648\u0632\u0679\u0631\u06cc \u06a9\u0627 \u0679\u06cc\u0633\u0679 \u0633\u0648\u06cc\u0679 \u0627\u0633 \u062f\u0639\u0648\u06d2 \u06a9\u0648 \u0628\u0627\u0644\u06a9\u0644 \u0679\u06be\u06cc\u06a9 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4 <code>FakeClient<\/code> \u0688\u0628\u0644 \u0679\u06cc\u0633\u0679\u06d4<\/p>\n<p>\u0630\u06cc\u0644 \u0645\u06cc\u06ba \u0627\u0648\u067e\u0646 \u0627\u06d2 \u0622\u0626\u06cc \u0627\u0688\u0627\u067e\u0679\u0631 \u06a9\u06cc \u0627\u06cc\u06a9 \u0645\u062b\u0627\u0644 \u062f\u06cc \u06af\u0626\u06cc \u06c1\u06d2 (\u0635\u0631\u0641 \u0645\u062b\u0627\u0644\u06cc \u0645\u0642\u0627\u0635\u062f \u06a9\u06d2 \u0644\u06cc\u06d2\u061b \u067e\u0631\u0648\u0688\u06a9\u0634\u0646 \u0627\u0688\u0627\u067e\u0679\u0631 \u0627\u0633\u0679\u0631\u06cc\u0645\u0646\u06af\u060c \u0679\u0648\u0644\u0646\u06af\u060c \u0627\u0648\u0631 \u063a\u0644\u0637\u06cc \u06a9\u06cc \u0627\u0642\u0633\u0627\u0645 \u06a9\u0627 \u0646\u0642\u0634\u06c1 \u0628\u06be\u06cc \u0628\u0646\u0627\u062a\u0627 \u06c1\u06d2):<\/p>\n<pre><code class=\"language-python\"># openai_adapter.py \u2014 illustrative pseudocode, not production-ready.\nfrom openai import OpenAI as _OpenAI\n\n\nclass _MessagesAdapter:\n    def __init__(self, client):\n        self._client = client\n\n    def create(self, *, model, max_tokens, system, messages):\n        completion = self._client.chat.completions.create(\n            model=model,\n            max_tokens=max_tokens,\n            messages=[{\"role\": \"system\", \"content\": system}] + messages,\n        )\n        # Reshape OpenAI's response into the Anthropic-shaped surface\n        # AgentLoop reads: response.usage.{input,output}_tokens,\n        # response.content[0].text, response.stop_reason.\n        return _adapt_response(completion)\n\n\nclass OpenAIAdapter:\n    def __init__(self, api_key: str):\n        self._client = _OpenAI(api_key=api_key)\n        self.messages = _MessagesAdapter(self._client)  # instance attr, not a nested class\n<\/code><\/pre>\n<p>\u0627\u0688\u0627\u067e\u0679\u0631 \u067e\u06cc\u0679\u0631\u0646 \u0648\u0627\u0636\u062d \u0637\u0648\u0631 \u067e\u0631 \u0633\u06a9\u06be\u0627\u0646\u06d2 \u06a9\u06d2 \u0642\u0627\u0628\u0644 \u06c1\u06d2. \u0641\u0631\u0627\u06c1\u0645 \u06a9\u0646\u0646\u062f\u06c1 APIs \u0638\u0627\u06c1\u0631\u06cc \u0634\u06a9\u0644 \u06a9\u0627 \u0627\u0634\u062a\u0631\u0627\u06a9 \u0646\u06c1\u06cc\u06ba \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 \u0627\u0646\u0633\u0627\u0646\u06cc\u062a \u06a9\u06d2 \u067e\u0627\u0624\u06ba <code>system<\/code> \u0627\u0639\u0644\u06cc\u0670 \u062a\u0631\u06cc\u0646 \u0633\u0637\u062d \u067e\u0631\u06d4 OpenAI \u0627\u0633\u06d2 \u0627\u06cc\u06a9 \u067e\u06cc\u063a\u0627\u0645 \u06a9\u06cc \u0635\u0641 \u0645\u06cc\u06ba \u0631\u06a9\u06be\u062a\u0627 \u06c1\u06d2\u06d4 \u0627\u0688\u0627\u067e\u0679\u0631 \u0634\u06cc\u0645 ~ 20 \u0644\u0627\u0626\u0646\u06cc\u06ba \u0644\u0645\u0628\u0627 \u06c1\u06d2 \u0627\u0648\u0631 \u0627\u0633\u06d2 \u06a9\u0633\u06cc \u0628\u06be\u06cc \u0686\u06cc\u0632 \u06a9\u0648 \u062f\u0648\u0628\u0627\u0631\u06c1 \u0644\u06a9\u06be\u06d2 \u0628\u063a\u06cc\u0631 \u0644\u0648\u067e \u0641\u0631\u0627\u06c1\u0645 \u06a9\u0646\u0646\u062f\u06c1 \u06a9\u0648 \u0627\u062c\u0646\u0627\u0633\u0679\u06a9 \u0628\u0646\u0627 \u062f\u06cc\u062a\u0627 \u06c1\u06d2\u06d4 \u0628\u0631\u0627\u06c1 \u06a9\u0631\u0645 \u0627\u0633 \u06a9\u0627 \u062d\u0648\u0627\u0644\u06c1 \u062f\u06cc\u06ba\u06d4 <code>self.messages<\/code> \u06a9\u0648 \u062a\u0641\u0648\u06cc\u0636 \u06a9\u06cc\u0627 \u062c\u0627\u062a\u0627 \u06c1\u06d2\u06d4 <code>__init__<\/code> \u0644\u06c1\u0630\u0627 \u06cc\u06c1 \u06c1\u0631 \u0627\u0688\u0627\u067e\u0679\u0631 \u0645\u062b\u0627\u0644 \u06a9\u06cc \u0627\u0635\u0644 \u062e\u0635\u0648\u0635\u06cc\u0627\u062a \u06c1\u06cc\u06ba \u0627\u0648\u0631 \u0627\u0635\u0644 SDK \u062c\u06cc\u0633\u06cc \u0638\u0627\u06c1\u0631\u06cc \u0634\u06a9\u0644 \u06c1\u06d2\u06d4<\/p>\n<h2 id=\"heading-running-the-tests\">\u0679\u06cc\u0633\u0679 \u0686\u0644\u0627\u0626\u06cc\u06ba<\/h2>\n<pre><code class=\"language-bash\">python -m pytest tests\/\n<\/code><\/pre>\n<p>\u0644\u0627\u06af\u0648 \u0639\u0644\u0627\u0642\u06c1:<\/p>\n<pre><code class=\"language-bash\">python -m coverage run --source=circuit_breaker,ledger,spec_writer,agent_loop,review_surface -m pytest tests\/\npython -m coverage report -m\n<\/code><\/pre>\n<p>80 \u0679\u06cc\u0633\u0679\u060c \u062a\u0645\u0627\u0645 5 \u0628\u0646\u06cc\u0627\u062f\u06cc \u0645\u0627\u0688\u06cc\u0648\u0644\u0632 \u06a9\u06cc 100% \u06a9\u0648\u0631\u06cc\u062c\u06d4 \u0644\u0648\u067e \u0627\u0633 \u06a9\u06d2 \u0644\u06cc\u06d2 \u0686\u0644\u062a\u0627 \u06c1\u06d2: <code>FakeClient<\/code> \u0688\u0628\u0644 \u0679\u06cc\u0633\u0679 \u06a9\u06cc \u0648\u0636\u0627\u062d\u062a \u0627\u0646 \u0644\u0627\u0626\u0646 <code>tests\/test_agent_loop.py<\/code>. \u06cc\u06c1 \u0645\u0646\u062f\u0631\u062c\u06c1 \u0630\u06cc\u0644 \u06a9\u0648 \u0645\u0637\u0645\u0626\u0646 \u06a9\u0631\u062a\u0627 \u06c1\u06d2: <code>LLMClient<\/code> \u0628\u062a\u06be \u0679\u0627\u0626\u067e\u0646\u06af \u06a9\u06d2 \u0630\u0631\u06cc\u0639\u06d2 \u067e\u0631\u0648\u0679\u0648\u06a9\u0648\u0644: <code>messages<\/code> \u067e\u0631 \u0645\u0642\u0631\u0631 \u06c1\u06d2 <code>self<\/code>\u062a\u0648 <code>client.messages.create(...)<\/code> \u06cc\u06c1 \u0627\u06cc\u06a9 \u06c1\u06cc \u0634\u06d2 \u06a9\u06cc \u0637\u0631\u0641 \u0648\u0627\u067e\u0633 \u062c\u0627\u062a\u0627 \u06c1\u06d2 \u0627\u0648\u0631 \u06c1\u0631 \u0679\u06cc\u0633\u0679 \u06a9\u06d2 \u0645\u0646\u0638\u0631 \u0646\u0627\u0645\u06d2 \u06a9\u06d2 \u0644\u06cc\u06d2 \u0627\u0633\u06a9\u0631\u067e\u0679 \u0634\u062f\u06c1 \u062c\u0648\u0627\u0628\u0627\u062a \u0641\u0631\u0627\u06c1\u0645 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4 \u0630\u062e\u06cc\u0631\u06c1 \u06a9\u0644\u0648\u0646 \u06a9\u0631\u06cc\u06ba \u0627\u0648\u0631 \u0627\u0633\u06d2 \u0686\u0644\u0627\u0626\u06cc\u06ba\u06d4 <code>pytest<\/code> \u062f\u06cc\u06a9\u06be\u06cc\u06ba \u06a9\u06c1 \u06a9\u06cc\u0627 \u062a\u0645\u0627\u0645 80 \u0679\u06cc\u0633\u0679 \u0646\u06cc\u0679 \u0648\u0631\u06a9 \u06a9\u0648 \u0686\u06be\u0648\u0626\u06d2 \u0628\u063a\u06cc\u0631 \u06cc\u0627 API \u06a9\u0644\u06cc\u062f \u06a9\u06cc \u0636\u0631\u0648\u0631\u062a \u06a9\u06d2 \u0628\u063a\u06cc\u0631 \u067e\u0627\u0633 \u06c1\u0648 \u062c\u0627\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p><code>circuit_breaker.py<\/code>    100% \u06a9\u0648\u0631\u06cc\u062c \u06c1\u06d2 \u0627\u0648\u0631 \u06a9\u0648\u0626\u06cc \u0628\u06be\u06cc \u0631\u0627\u0633\u062a\u06c1 \u0628\u063a\u06cc\u0631 \u0679\u06cc\u0633\u0679 \u0634\u062f\u06c1 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4 \u06cc\u06c1 \u0645\u0627\u0644\u06cc\u0627\u062a\u06cc \u062d\u0641\u0627\u0638\u062a \u06a9\u0627 \u062d\u0635\u06c1 \u06c1\u06d2\u06d4 \u062c\u0648 \u0628\u06be\u06cc \u0631\u0627\u0633\u062a\u06c1 \u0627\u0633 \u0633\u06d2 \u06af\u0632\u0631\u062a\u0627 \u06c1\u06d2 \u0627\u0633\u06d2 \u067e\u06be\u0627\u0646\u0633\u06cc \u062f\u06cc \u062c\u0627\u062a\u06cc \u06c1\u06d2\u06d4<\/p>\n<h2 id=\"heading-what-youve-built\">\u0622\u067e \u0646\u06d2 \u06a9\u06cc\u0627 \u0628\u0646\u0627\u06cc\u0627<\/h2>\n<p>\u0627\u0633 \u0679\u06cc\u0648\u0679\u0648\u0631\u06cc\u0644 \u0645\u06cc\u06ba\u060c \u06c1\u0645 \u0646\u06d2 \u067e\u0627\u0646\u0686 \u0686\u06be\u0648\u0679\u06d2 \u067e\u0631\u0627\u0626\u0645\u06cc\u0679\u0648\u0632 \u0628\u0646\u0627\u0626\u06d2 \u06c1\u06cc\u06ba\u060c \u062c\u0646 \u0645\u06cc\u06ba \u0633\u06d2 \u06c1\u0631 \u0627\u06cc\u06a9 \u06a9\u0648 \u0622\u0632\u0627\u062f\u0627\u0646\u06c1 \u0637\u0648\u0631 \u067e\u0631 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u06cc\u0627 \u062c\u0627 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<table>\n<thead>\n<tr>\n<th>\u0645\u0627\u0688\u06cc\u0648\u0644<\/th>\n<th>\u06a9\u0631\u062f\u0627\u0631<\/th>\n<th>\u0633\u0645\u0648\u0686<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>spec_writer.py<\/code><\/td>\n<td>\u0644\u0648\u067e \u0686\u0644\u0646\u06d2 \u0633\u06d2 \u067e\u06c1\u0644\u06d2 \u062a\u06cc\u0646 \u062c\u0648\u0627\u0628\u0627\u062a \u067e\u0631 \u0645\u062c\u0628\u0648\u0631 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4<\/td>\n<td>104<\/td>\n<\/tr>\n<tr>\n<td><code>circuit_breaker.py<\/code><\/td>\n<td>\u0645\u0648\u0691 \u0627\u0648\u0631 \u0679\u0648\u06a9\u0646 \u067e\u0631 \u0633\u062e\u062a \u0686\u06be\u062a<\/td>\n<td>41<\/td>\n<\/tr>\n<tr>\n<td><code>ledger.py<\/code><\/td>\n<td>\u0635\u0631\u0641 SQLite \u0622\u0688\u0679 \u0679\u0631\u06cc\u0644 \u0634\u0627\u0645\u0644 \u06a9\u0631\u06cc\u06ba\u06d4<\/td>\n<td>113<\/td>\n<\/tr>\n<tr>\n<td><code>agent_loop.py<\/code><\/td>\n<td>\u0627\u06cc\u06a9 \u0644\u0648\u067e \u062c\u0648 \u062f\u0648\u0646\u0648\u06ba \u06a9\u0627 \u0627\u062d\u062a\u0631\u0627\u0645 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4<\/td>\n<td>128<\/td>\n<\/tr>\n<tr>\n<td><code>review_surface.py<\/code><\/td>\n<td>\u067e\u0627\u0646\u0686 \u0639\u0646\u0627\u0635\u0631 \u06a9\u06d2 \u0641\u0631\u06cc\u0645 \u06a9\u0648 \u062c\u0645\u0639 \u06a9\u0631\u06cc\u06ba \u0627\u0648\u0631 \u0627\u0646\u0633\u0627\u0646\u06cc \u06af\u0648\u0627\u06c1\u06cc \u06a9\u0648 \u0631\u06cc\u06a9\u0627\u0631\u0688 \u06a9\u0631\u06cc\u06ba\u06d4<\/td>\n<td>114<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u067e\u06cc\u0679\u0631\u0646: \u0627\u067e \u0627\u0633\u0679\u0631\u06cc\u0645 \u0688\u0633\u067e\u0644\u0646 \u062d\u062f\u0648\u062f \u06a9\u06cc \u0648\u0636\u0627\u062d\u062a \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 \u0688\u0627\u0624\u0646 \u0627\u0633\u0679\u0631\u06cc\u0645 \u0646\u0641\u0627\u0630 \u0633\u0631\u06a9\u0679 \u06a9\u0648 \u062a\u0648\u0691 \u062f\u06cc\u062a\u0627 \u06c1\u06d2\u06d4 \u0646\u06c1 \u06c1\u06cc \u062e\u0648\u062f \u067e\u0648\u0644\u06cc\u0633 \u06a9\u0648 \u0645\u0627\u0688\u0644 \u067e\u0631 \u0628\u06be\u0631\u0648\u0633\u06c1 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0627\u06cc\u06a9 \u0644\u0648\u067e \u062c\u0648 \u0628\u0627\u06c1\u0631 \u0646\u06a9\u0644\u0646\u06d2 \u06a9\u06cc \u0634\u0631\u0637 \u06a9\u06d2 \u0628\u063a\u06cc\u0631 \u0686\u0644\u062a\u0627 \u06c1\u06d2 \u0648\u06c1 \u062e\u0648\u062f \u0645\u062e\u062a\u0627\u0631 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4 \u0627\u062f\u0627\u0626\u06cc\u06af\u06cc \u06a9\u06cc \u062a\u0642\u0631\u06cc\u0628 \u06a9\u0627 \u0627\u0646\u062a\u0638\u0627\u0631 \u06c1\u06d2\u06d4<\/p>\n<p>\u0634\u0631\u0648\u0639 \u06a9\u0631\u0646\u06d2 \u0633\u06d2 \u067e\u06c1\u0644\u06d2\u060c \u0648\u0636\u0627\u062d\u062a \u06a9\u0631\u06cc\u06ba \u06a9\u06c1 \u062a\u06cc\u0627\u0631 \u0634\u062f\u06c1 \u0634\u06a9\u0644 \u06a9\u06cc\u0633\u06cc \u06c1\u0648\u06af\u06cc\u06d4 \u06cc\u06c1 \u0648\u06c1\u06cc \u06c1\u06d2\u060c \u0627\u0648\u0631 \u06cc\u06c1 \u06c1\u0645\u06cc\u0634\u06c1 \u0627\u06cc\u0633\u0627 \u06c1\u06cc \u0631\u06c1\u0627 \u06c1\u06d2\u06d4<\/p>\n<h2 id=\"heading-next-steps\">\u0627\u06af\u0644\u06d2 \u0627\u0642\u062f\u0627\u0645\u0627\u062a<\/h2>\n<p>\u0630\u062e\u06cc\u0631\u06c1 github.com\/dannwaneri\/production-safe-agent-loop \u067e\u0631 \u06c1\u06d2\u06d4<\/p>\n<p>\u0627\u06af\u0631 \u0622\u067e \u0645\u0632\u06cc\u062f \u062c\u0627\u0646\u0627 \u0686\u0627\u06c1\u062a\u06d2 \u06c1\u06cc\u06ba \u062a\u0648\u060c \u062a\u06cc\u0646 \u0642\u062f\u0631\u062a\u06cc \u062a\u0648\u0633\u06cc\u0639\u0627\u062a \u06c1\u06cc\u06ba:<\/p>\n<h3 id=\"heading-1-graduation-to-distributed-systems\">1. \u062a\u0642\u0633\u06cc\u0645 \u0634\u062f\u06c1 \u0646\u0638\u0627\u0645\u0648\u06ba \u0645\u06cc\u06ba \u06af\u0631\u06cc\u062c\u0648\u06cc\u0634\u0646<\/h3>\n<p>SQLite \u0644\u06cc\u062c\u0631\u0632 \u0627\u0644\u06af \u062a\u06be\u0644\u06af \u062a\u0631\u062a\u06cc\u0628 \u0648\u0627\u0631 \u0644\u0648\u067e\u0633 \u067e\u0631 \u06a9\u0627\u0645 \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 \u062c\u0633 \u0644\u0645\u062d\u06d2 \u0622\u067e \u0645\u0634\u062a\u0631\u06a9\u06c1 \u0631\u06cc\u0627\u0633\u062a \u067e\u0631 \u0627\u06cc\u06a9 \u0633\u06d2 \u0632\u06cc\u0627\u062f\u06c1 \u0627\u06cc\u062c\u0646\u0679 \u0686\u0644\u0627\u062a\u06d2 \u06c1\u06cc\u06ba\u060c \u0622\u067e \u06a9\u0648 \u0633\u06cc\u0631\u06cc\u0644\u0627\u0626\u0632\u0628\u0644 \u0622\u0626\u0633\u0648\u0644\u06cc\u0634\u0646 \u06a9\u06cc \u0636\u0631\u0648\u0631\u062a \u06c1\u0648\u062a\u06cc \u06c1\u06d2\u06d4 \u0627\u0633 \u06a9\u0627 \u0645\u0637\u0644\u0628 \u06cc\u06c1 \u06c1\u06d2 \u06a9\u06c1 \u0641\u0644\u06cc\u0679 JSON \u06a9\u0648 \u06a9\u0646\u06a9\u0631\u0646\u0679 \u0631\u0627\u0626\u0679 \u062e\u0648\u062f \u0628\u062e\u0648\u062f \u0679\u0648\u0679 \u062c\u0627\u062a\u06cc \u06c1\u06cc\u06ba\u06d4 README \u062a\u06cc\u0646 \u0627\u06c1\u0645 \u0645\u0648\u0691 \u06a9\u0648 \u062f\u0633\u062a\u0627\u0648\u06cc\u0632 \u06a9\u0631\u062a\u0627 \u06c1\u06d2 \u062c\u06c1\u0627\u06ba \u0633\u06d2 \u0627\u06cc\u06a9 \u0641\u0644\u06cc\u0679 \u0644\u06cc\u062c\u0631 \u06a9\u0648 \u06af\u0631\u06cc\u062c\u0648\u06cc\u0679 \u06c1\u0648\u0646\u0627 \u0636\u0631\u0648\u0631\u06cc \u06c1\u06d2:<\/p>\n<h3 id=\"heading-2-cryptographic-signing\">2. \u06a9\u0631\u067e\u0679\u0648\u06af\u0631\u0627\u0641\u06a9 \u062f\u0633\u062a\u062e\u0637<\/h3>\n<p>\u062a\u0639\u0645\u06cc\u0644 \u067e\u06cc\u0645\u0627\u0646\u06d2 \u06a9\u06d2 \u0646\u0638\u0627\u0645 \u06a9\u06d2 \u0644\u06cc\u06d2 \u062c\u06c1\u0627\u06ba \u0644\u0648\u067e \u06a9\u06d2 \u0686\u0644\u0646\u06d2 \u067e\u0631 \u06a9\u0648\u0626\u06cc \u0622\u0688\u06cc\u0679\u0631 \u0645\u0648\u062c\u0648\u062f \u0646\u06c1\u06cc\u06ba \u062a\u06be\u0627\u060c \u0627\u06a9\u06cc\u0644\u06d2 SQLite \u0642\u0637\u0627\u0631\u06cc\u06ba \u06a9\u0627\u0641\u06cc \u0646\u06c1\u06cc\u06ba \u06c1\u0648\u06ba \u06af\u06cc\u06d4 \u0688\u06cc\u0679\u0627 \u0628\u06cc\u0633 \u0627\u06cc\u0688\u0645\u0646\u0633\u0679\u0631\u06cc\u0679\u0631 \u0686\u0644\u0627 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba: <code>UPDATE<\/code> \u0633\u0648\u0627\u0644 Ed25519 \u062f\u0633\u062a\u062e\u0637 \u06c1\u0631 \u0644\u06cc\u062c\u0631 \u06a9\u06cc \u0642\u0637\u0627\u0631 \u06a9\u0648 \u0627\u06cc\u06a9 \u0631\u0633\u06cc\u062f \u0645\u06cc\u06ba \u0644\u067e\u06cc\u0679\u062a\u0627 \u06c1\u06d2 \u062c\u0648 \u062b\u0627\u0628\u062a \u06a9\u0631\u062a\u0627 \u06c1\u06d2 \u06a9\u06c1 \u0644\u0627\u06af \u0627\u0646 \u06a9\u0648 \u067e\u06be\u0627\u0646\u0633\u06cc \u06a9\u06d2 \u0628\u0639\u062f \u0633\u06d2 \u062a\u0628\u062f\u06cc\u0644 \u0646\u06c1\u06cc\u06ba \u06a9\u06cc\u0627 \u06af\u06cc\u0627 \u06c1\u06d2\u06d4 \u0644\u06cc\u06a9\u0646 \u06cc\u06c1 \u0627\u06cc\u06a9 \u0645\u062e\u062a\u0644\u0641 \u0679\u06cc\u0648\u0679\u0648\u0631\u06cc\u0644 \u06c1\u06d2\u06d4<\/p>\n<h3 id=\"heading-wiring-a-cron-job\">\u06a9\u0631\u0648\u0646 \u062c\u0627\u0628 \u06a9\u0646\u06a9\u0634\u0646<\/h3>\n<p>SEO \u0622\u0688\u0679 \u0627\u06cc\u062c\u0646\u0679 \u06a9\u0627 \u062f\u06cc\u0627\u0646\u062a \u062f\u0627\u0631 \u0641\u0646 \u062a\u0639\u0645\u06cc\u0631 \u062e\u0648\u062f \u0645\u062e\u062a\u0627\u0631 24\/7 \u0622\u067e\u0631\u06cc\u0634\u0646 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4 \u0627\u06cc\u06a9 \u06a9\u0631\u0648\u0646 \u062c\u0627\u0628 \u062c\u0648 \u0627\u06cc\u06a9 \u0634\u06cc\u0688\u0648\u0644 \u067e\u0631 \u0686\u0644\u062a\u06cc \u06c1\u06d2\u060c \u06a9\u0633\u06cc \u0628\u06be\u06cc \u0628\u062f\u0639\u0646\u0648\u0627\u0646\u06cc \u06a9\u0648 \u0688\u06be\u0648\u0646\u0688\u062a\u06cc \u06c1\u06d2\u060c \u0627\u0648\u0631 \u067e\u06be\u0631 \u0627\u0633\u06d2 \u0631\u0648\u06a9 \u062f\u06cc\u062a\u06cc \u06c1\u06d2\u06d4 <code>0 3 * * 2 python examples\/seo_audit_example.py https:\/\/yourdomain.com<\/code> \u0628\u0633\u06d4 \u0644\u0648\u067e \u0622\u067e \u06a9\u06cc \u0637\u0631\u0641 \u062f\u0648\u0691\u062a\u0627 \u06c1\u06d2\u060c \u062c\u06af\u06c1 \u0646\u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u0627\u06af\u0631 \u0622\u067e \u06a9\u0648 \u0627\u067e\u0646\u06d2 \u0627\u0633\u0679\u06cc\u06a9 (\u0633\u0631\u06a9\u0679 \u0628\u0631\u06cc\u06a9\u0631\u0632\u060c \u0622\u0688\u0679 \u0679\u0631\u06cc\u0644\u0632\u060c \u067e\u0631\u0648\u0688\u06a9\u0634\u0646 \u0633\u06cc\u0641\u0679\u06cc \u0627\u06cc\u062c\u0646\u0679 \u0644\u0648\u067e\u0633) \u06a9\u06d2 \u0644\u06cc\u06d2 \u0628\u0646\u0627\u0626\u06d2 \u06af\u0626\u06d2 \u0627\u0633 \u0641\u0646 \u062a\u0639\u0645\u06cc\u0631 \u06a9\u06cc \u0636\u0631\u0648\u0631\u062a \u06c1\u06d2 \u062a\u0648 \u06a9\u0686\u06be \u0641\u0631\u06cc \u0644\u0627\u0646\u0633 \u06a9\u0627\u0645 \u06a9\u0631\u06cc\u06ba\u06d4 dannwaneri.com\/ai-agents\/<\/p>\n<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u062c\u0648\u0644\u0627\u0626\u06cc 2025 \u0645\u06cc\u06ba\u060c Claude Code recursive loop 5 \u06af\u06be\u0646\u0679\u06d2 \u0645\u06cc\u06ba 16,000 USD \u0627\u0648\u0631 50,000 USD \u06a9\u06d2 \u062f\u0631\u0645\u06cc\u0627\u0646 \u062c\u0644 \u06af\u06cc\u0627\u06d4 \u06a9\u0648\u0626\u06cc \u06a9\u0631\u06cc\u0634 \u06cc\u0627 \u063a\u0644\u0637\u06cc\u0627\u06ba \u0646\u06c1\u06cc\u06ba \u062a\u06be\u06cc\u06ba\u060c \u0627\u0648\u0631 \u0686\u0648\u0646\u06a9\u06c1 \u06a9\u0633\u06cc \u0646\u06d2 \u06c1\u0645\u06cc\u06ba \u06cc\u06c1 \u0646\u06c1\u06cc\u06ba \u0628\u062a\u0627\u06cc\u0627 \u06a9\u06c1 \u06a9\u0628 \u0631\u06a9\u0646\u0627 \u06c1\u06d2\u060c \u0627\u06cc\u062c\u0646\u0679\u0648\u06ba \u0646\u06d2 \u0628\u0627\u0644\u06a9\u0644 \u0648\u06cc\u0633\u0627 \u06c1\u06cc \u06a9\u06cc\u0627 \u062c\u06cc\u0633\u0627 \u06a9\u06c1 \u0627\u0646\u06c1\u06cc\u06ba \u0628\u062a\u0627\u06cc\u0627 \u06af\u06cc\u0627 \u062a\u06be\u0627\u06d4 4 \u0645\u06c1\u06cc\u0646\u0648\u06ba \u06a9\u06d2 \u0628\u0639\u062f\u060c 4 \u0627\u06cc\u062c\u0646\u0679\u0648\u06ba [&hellip;]<\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[1],"tags":[],"class_list":["post-25423","post","type-post","status-publish","format-standard","hentry","category-blog"],"_links":{"self":[{"href":"https:\/\/umang.pk\/ur\/wp-json\/wp\/v2\/posts\/25423","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/umang.pk\/ur\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/umang.pk\/ur\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/umang.pk\/ur\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/umang.pk\/ur\/wp-json\/wp\/v2\/comments?post=25423"}],"version-history":[{"count":0,"href":"https:\/\/umang.pk\/ur\/wp-json\/wp\/v2\/posts\/25423\/revisions"}],"wp:attachment":[{"href":"https:\/\/umang.pk\/ur\/wp-json\/wp\/v2\/media?parent=25423"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/umang.pk\/ur\/wp-json\/wp\/v2\/categories?post=25423"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/umang.pk\/ur\/wp-json\/wp\/v2\/tags?post=25423"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}