[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M70SJ02CTB40V2VFGAF80SBG":3,"skill-same:01M70SJ02CTB40V2VFGAF80SBG":67},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":44,"commitSha":45,"skillDirectory":46,"forksCount":47,"repositoryHtmlUrl":48,"repositoryHomepageUrl":49,"ownerHtmlUrl":50,"ownerBlogUrl":6,"ownerDescription":51,"updatedAt":52,"install":53,"resources":66},"01M70SJ02CTB40V2VFGAF80SBG","verify-run-pipeline",null,"Formally verify the \u002Frun phase machine before or after changing it. Use when editing internal\u002Ftui\u002Frun.go's phase transitions (handleRunAgentDone, runGates result handling, verifyRunComplete, retryRun, reportGateHang, merge), internal\u002Fsop\u002Fverdict.go's Passed, or the checklist refresh — or when a run merged work it should not have, retried a hung gate, lost a cycle at the retry budget, or merged on a stale PASS.","dimetron\u002Fpi-go","dimetron","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F877433?v=4","01M6E34QX9HKYKMWJVZQEPR2Q3","Dmytro Rashko","01M6E34R2A6563XM0PTZE8KPGG",224,"MIT","https:\u002F\u002Fgithub.com\u002Fdimetron\u002Fpi-go\u002Fblob\u002Fmain\u002Finternal\u002Fextension\u002Fbundled_skills\u002Fverify-run-pipeline\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"verify run pipeline","verify","run","run pipeline","pipeline","sop","merge","result","transitions","verdict","work","refresh","phase","when","use","machine","run phase","cycle","editing","retry","2026-11-10 10:12:30",false,"---\nname: verify-run-pipeline\ndescription: Formally verify the \u002Frun phase machine before or after changing it. Use when editing internal\u002Ftui\u002Frun.go's phase transitions (handleRunAgentDone, runGates result handling, verifyRunComplete, retryRun, reportGateHang, merge), internal\u002Fsop\u002Fverdict.go's Passed, or the checklist refresh — or when a run merged work it should not have, retried a hung gate, lost a cycle at the retry budget, or merged on a stale PASS.\n---\n\n# Verify the \u002Frun pipeline\n\n`\u002Frun` has seven phases as bare strings and a merge gate that depends on two\nindependent signals agreeing. Both are easy to weaken by accident: dropping one\nsignal still merges, and treating a hang like a failure still retries.\n\nThe property: **a run merges only when every slice landed AND a stated verdict is\nPASS**, and **a hung gate never retries and never merges**.\n\n## Does my change touch the verified code\n\n```bash\ngit diff --stat \u003Csync-commit>..HEAD -- \\\n  internal\u002Ftui\u002Frun.go internal\u002Fsop\u002Fverdict.go internal\u002Ftui\u002Fsop_status.go\n```\n\n**Model covers** (each model step names the function it stands for):\n\n| Model action | Code |\n|---|---|\n| `Start` | `handleRunCommand` spawn, `run.go:548, 645` |\n| `AgentFailedRetry` \u002F `AgentFailedGiveUp` | `handleRunAgentDone` bad status, `run.go:872-893` |\n| `AgentDoneNoGates` \u002F `AgentDoneGates` | all agents finished, `run.go:900-917` |\n| `GateResult` | the `runGateResultMsg` outcome, `run.go:1355` |\n| `GatesPassed` | `run.go:1357-1365` |\n| `GatesFailedRetry` \u002F `GatesFailedGiveUp` | `run.go:1370-1385` |\n| `GatesHung` | `reportGateHang`, `run.go:1366-1369, 1394-1420` |\n| `ChecklistTicked` \u002F `ChecklistLeftOpen` | `refreshRunChecklist` + `unfinishedSlices`, `run.go:922-932` |\n| `ReadVerdict` | `sop.ParseVerdict`, `run.go:958`, `sop\u002Fverdict.go:84` |\n| `VerifyPass` | the two-signal merge gate, `run.go:975-981` |\n| `VerifyFailRetry` \u002F `VerifyFailGiveUp` | `run.go:983-1000` |\n| `RetrySpawned` \u002F `RetryBudgetSpent` | `retryRun`, `run.go:1040-1115` |\n| `MergeOk` \u002F `MergeFailed` | the merge command result, `run.go:1500-1550` |\n\n**Not modelled, and why:** the parallel-agent fan-in and\n`collapseParallel`\u002F`carried` (the model has one coordinator); gate execution\n(timing, sandbox, `GateHang` detection by elapsed time); `writeRunSummary`;\n`pr-autofix` (its own stage machine, derived from the SOP engine); the sidebar's\nrendering of the phase (`sop_status.go`). A bug in any of those is invisible here.\n\n## Run it\n\n```bash\nhack\u002Fformal\u002Fcheck.sh run           # all rules hold, or the first one that breaks\nhack\u002Fformal\u002Fcheck.sh run --chart   # also draw the statechart\n```\n\nCurrent cost: 110 distinct states, well under a second. Exit `0` every rule\nholds, `1` a rule broke, `2` TLC or the environment failed (never a verdict about\nthe code). The run begins with `go run .\u002Fhack\u002Fformal\u002Flint\u002Fmain`, so a structurally broken\nmodel is reported before TLC is started.\n\n## Read a result\n\nSame three-way triage as `verify-goal-loop`: **a real bug** (replay the step\nsequence against the real code as a test in `internal\u002Ftui`), **a modelling error**\n(fix the model, not the rule), or **a rule stronger than the code promises**\n(check the comment the rule cites; this model has already required restating\n`NoStalePassAfterRetry`, because `retryRun` sets the phase to `retrying` *before*\nthe new coordinator clears the verdict).\n\n## Rules, and the harm each one names\n\n| Rule | The promise | What breaking it means for a user |\n|---|---|---|\n| `MergeRequiresBothSignals` | done ⇒ checklist whole AND stated PASS | half-implemented work merges; this is the failure `verifyRunComplete` exists to catch |\n| `HangNeverRetries` | a hung gate never reaches `retrying` | the retry budget is spent re-running a command known not to return |\n| `HangNeverMerges` | a hung gate never reaches `done` | unverified work ships over a gate that never answered |\n| `RetriesBounded` | `retries \u003C= MaxRetries` | an unbounded retry loop bills without end |\n| `NoStalePassAfterRetry` | a running retry has no PASS in hand | cycle N's verdict satisfies cycle N+1's verification |\n\n## The trap that made this model pass wrongly\n\n**A rule over a variable that no action assigns is vacuously true.** The first\nversion of this model never assigned `gateOutcome` — it only *tested* it — so both\ngate rules held over an empty set. A mutation that made a hung gate retry passed\ncleanly. `go run .\u002Fhack\u002Fformal\u002Flint\u002Fmain` now fails the run for an unassigned variable and\nfor a rule whose premise needs a literal no action produces; both checks were\nconfirmed against this exact defect.\n\nThe second trap is the one `verify-goal-loop` documents: **two assignments to one\nvariable in one action are a conjunction**, so the contradicting branch is dead.\nThe lint catches that too. If you add an action, run the lint before trusting a\npass, and confirm a deliberate break reproduces:\n\n```bash\n# In a scratch copy, make GatesHung retry instead of fail:\n#   add `\u002F\\ CanRetry` and change `phase' = \"failed\"` to `phase' = \"retrying\"`.\n# HangNeverRetries must break.\n```\n\n## After confirming the model is still true\n\n- **Sync commit:** `cc79aceb43df31012e9e5c1f69a7ba1231c32470`\n- **Constants:** `MaxRetries = 2` (enough for one retry and one exhaustion).\n- **Chart budget:** 110 states, so the full chart always draws.\n\nMove the sync commit forward only after confirming the model describes the code\nat the new commit, and record the new sha here.\n\n## Draw the chart\n\n`hack\u002Fformal\u002Fcheck.sh run --chart` writes `hack\u002Fformal\u002Frun\u002Fout\u002Freport.md` and\n`chart.mmd` via the pstack `\u002Fstatechart` skill. Read results with `\u002Fstatechart`:\nit renders each violation as the shortest path in the user's words.\n","# Verify the \u002Frun pipeline\n\n`\u002Frun` has seven phases as bare strings and a merge gate that depends on two\nindependent signals agreeing. Both are easy to weaken by accident: dropping one\nsignal still merges, and treating a hang like a failure still retries.\n\nThe property: **a run merges only when every slice landed AND a stated verdict is\nPASS**, and **a hung gate never retries and never merges**.\n\n## Does my change touch the verified code\n\n```bash\ngit diff --stat \u003Csync-commit>..HEAD -- \\\n  internal\u002Ftui\u002Frun.go internal\u002Fsop\u002Fverdict.go internal\u002Ftui\u002Fsop_status.go\n```\n\n**Model covers** (each model step names the function it stands for):\n\n| Model action | Code |\n|---|---|\n| `Start` | `handleRunCommand` spawn, `run.go:548, 645` |\n| `AgentFailedRetry` \u002F `AgentFailedGiveUp` | `handleRunAgentDone` bad status, `run.go:872-893` |\n| `AgentDoneNoGates` \u002F `AgentDoneGates` | all agents finished, `run.go:900-917` |\n| `GateResult` | the `runGateResultMsg` outcome, `run.go:1355` |\n| `GatesPassed` | `run.go:1357-1365` |\n| `GatesFailedRetry` \u002F `GatesFailedGiveUp` | `run.go:1370-1385` |\n| `GatesHung` | `reportGateHang`, `run.go:1366-1369, 1394-1420` |\n| `ChecklistTicked` \u002F `ChecklistLeftOpen` | `refreshRunChecklist` + `unfinishedSlices`, `run.go:922-932` |\n| `ReadVerdict` | `sop.ParseVerdict`, `run.go:958`, `sop\u002Fverdict.go:84` |\n| `VerifyPass` | the two-signal merge gate, `run.go:975-981` |\n| `VerifyFailRetry` \u002F `VerifyFailGiveUp` | `run.go:983-1000` |\n| `RetrySpawned` \u002F `RetryBudgetSpent` | `retryRun`, `run.go:1040-1115` |\n| `MergeOk` \u002F `MergeFailed` | the merge command result, `run.go:1500-1550` |\n\n**Not modelled, and why:** the parallel-agent fan-in and\n`collapseParallel`\u002F`carried` (the model has one coordinator); gate execution\n(timing, sandbox, `GateHang` detection by elapsed time); `writeRunSummary`;\n`pr-autofix` (its own stage machine, derived from the SOP engine); the sidebar's\nrendering of the phase (`sop_status.go`). A bug in any of those is invisible here.\n\n## Run it\n\n```bash\nhack\u002Fformal\u002Fcheck.sh run           # all rules hold, or the first one that breaks\nhack\u002Fformal\u002Fcheck.sh run --chart   # also draw the statechart\n```\n\nCurrent cost: 110 distinct states, well under a second. Exit `0` every rule\nholds, `1` a rule broke, `2` TLC or the environment failed (never a verdict about\nthe code). The run begins with `go run .\u002Fhack\u002Fformal\u002Flint\u002Fmain`, so a structurally broken\nmodel is reported before TLC is started.\n\n## Read a result\n\nSame three-way triage as `verify-goal-loop`: **a real bug** (replay the step\nsequence against the real code as a test in `internal\u002Ftui`), **a modelling error**\n(fix the model, not the rule), or **a rule stronger than the code promises**\n(check the comment the rule cites; this model has already required restating\n`NoStalePassAfterRetry`, because `retryRun` sets the phase to `retrying` *before*\nthe new coordinator clears the verdict).\n\n## Rules, and the harm each one names\n\n| Rule | The promise | What breaking it means for a user |\n|---|---|---|\n| `MergeRequiresBothSignals` | done ⇒ checklist whole AND stated PASS | half-implemented work merges; this is the failure `verifyRunComplete` exists to catch |\n| `HangNeverRetries` | a hung gate never reaches `retrying` | the retry budget is spent re-running a command known not to return |\n| `HangNeverMerges` | a hung gate never reaches `done` | unverified work ships over a gate that never answered |\n| `RetriesBounded` | `retries \u003C= MaxRetries` | an unbounded retry loop bills without end |\n| `NoStalePassAfterRetry` | a running retry has no PASS in hand | cycle N's verdict satisfies cycle N+1's verification |\n\n## The trap that made this model pass wrongly\n\n**A rule over a variable that no action assigns is vacuously true.** The first\nversion of this model never assigned `gateOutcome` — it only *tested* it — so both\ngate rules held over an empty set. A mutation that made a hung gate retry passed\ncleanly. `go run .\u002Fhack\u002Fformal\u002Flint\u002Fmain` now fails the run for an unassigned variable and\nfor a rule whose premise needs a literal no action produces; both checks were\nconfirmed against this exact defect.\n\nThe second trap is the one `verify-goal-loop` documents: **two assignments to one\nvariable in one action are a conjunction**, so the contradicting branch is dead.\nThe lint catches that too. If you add an action, run the lint before trusting a\npass, and confirm a deliberate break reproduces:\n\n```bash\n# In a scratch copy, make GatesHung retry instead of fail:\n#   add `\u002F\\ CanRetry` and change `phase' = \"failed\"` to `phase' = \"retrying\"`.\n# HangNeverRetries must break.\n```\n\n## After confirming the model is still true\n\n- **Sync commit:** `cc79aceb43df31012e9e5c1f69a7ba1231c32470`\n- **Constants:** `MaxRetries = 2` (enough for one retry and one exhaustion).\n- **Chart budget:** 110 states, so the full chart always draws.\n\nMove the sync commit forward only after confirming the model describes the code\nat the new commit, and record the new sha here.\n\n## Draw the chart\n\n`hack\u002Fformal\u002Fcheck.sh run --chart` writes `hack\u002Fformal\u002Frun\u002Fout\u002Freport.md` and\n`chart.mmd` via the pstack `\u002Fstatechart` skill. Read results with `\u002Fstatechart`:\nit renders each violation as the shortest path in the user's words.\n",{"name":5,"description":7},"main","29fdab7a38eef7b4e1ef4101155eb2708f86fa5d","internal\u002Fextension\u002Fbundled_skills\u002Fverify-run-pipeline",34,"https:\u002F\u002Fgithub.com\u002Fdimetron\u002Fpi-go","https:\u002F\u002Fpi-go.sh","https:\u002F\u002Fgithub.com\u002Fdimetron","🎸💻 🚧🦞","2026-11-12 06:53:11",{"source":8,"skillName":5,"commands":54,"prompt":64,"zipAvailable":65},[55,58,61],{"tool":56,"command":57},"npx","npx skills add dimetron\u002Fpi-go --skill verify-run-pipeline",{"tool":59,"command":60},"bunx","bunx skills add dimetron\u002Fpi-go --skill verify-run-pipeline",{"tool":62,"command":63},"pnpm","pnpm dlx skills add dimetron\u002Fpi-go --skill verify-run-pipeline","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fdimetron\u002Fpi-go\u002Fblob\u002Fmain\u002Finternal\u002Fextension\u002Fbundled_skills\u002Fverify-run-pipeline\u002FSKILL.md",true,[],[68,96,115,131,152,166],{"skillNo":69,"name":70,"nameZh":6,"description":71,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":72,"categories":73,"keywords":79,"publishedAt":39},"01M70SJ3216A0Y2NXYJJ2MVER0","verify-session-flow","Formally verify the interactive session flow before or after changing it. Use when editing internal\u002Ftui\u002Ftui.go's handleKey, handleInterruptKey, handleInputSubmit, ctrlCCount or quitting, internal\u002Ftui\u002Fagent_loop.go's enqueuePrompt, submit, steerPrompt, cancelAgent or handleAgentDone, or the deferred-init splash — or when a user reports that Ctrl+C quit on the first press, that Esc did not stop a turn or a goal loop, that a queued prompt was lost when they canceled, or that the TUI hung on a spinner nothing could clear.","https:\u002F\u002Fgithub.com\u002Fdimetron\u002Fpi-go\u002Fblob\u002Fmain\u002Finternal\u002Fextension\u002Fbundled_skills\u002Fverify-session-flow\u002FSKILL.md",[74],{"categoryNo":75,"categoryName":76,"taxonomyType":77,"taxonomyTypeDesc":78},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[80,81,20,82,83,84,85,86,87,88,89,90,37,91,33,92,93,32,94,95],"session","verify session flow","flow","tui","first","spinner","go","clear","CTRL","goal","submit","init","loop","prompt","interactive","reports",{"skillNo":97,"name":98,"nameZh":6,"description":99,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":103,"publishedAt":39},"01M70SHWJV9N3PQWRAMCQE9C2E","verify-history-rewrite","Formally verify the session-history rewrite path before or after changing it. Use when editing internal\u002Fsession\u002Fautocompact.go, internal\u002Fsession\u002Fcompaction*.go, internal\u002Fsession\u002Fstore.go's Compact\u002FClearEvents\u002FrewriteEvents, internal\u002Fagent\u002Fagent.go's Run\u002FRunStreaming\u002FrunPreTurn, or internal\u002Ftui\u002Fcommands.go's clearConversation\u002FclearSessionContext and the context gauge — or when a turn is canceled mid-flight, a tool call and its result get separated, a session's history disappears while the agent is still working, or the model is sent a tool result whose call was compacted away.","https:\u002F\u002Fgithub.com\u002Fdimetron\u002Fpi-go\u002Fblob\u002Fmain\u002Finternal\u002Fextension\u002Fbundled_skills\u002Fverify-history-rewrite\u002FSKILL.md",[102],{"categoryNo":75,"categoryName":76,"taxonomyType":77,"taxonomyTypeDesc":78},[20,104,105,106,107,86,108,21,26,109,110,32,111,33,83,112,113,114,37,80],"verify history rewrite","rewrite","history","gauge","commands","call","store","compact","tool","get","model",{"skillNo":116,"name":117,"nameZh":6,"description":118,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":119,"categories":120,"keywords":122,"publishedAt":39},"01M70SHSJ5A2XV5SXBXM96RH7P","verify-goal-loop","Formally verify the \u002Fgoal automatic loop before or after changing it. Use when editing internal\u002Ftui\u002Fgoal.go, internal\u002Ftui\u002Fagent_loop.go's handleAgentDone\u002FcancelAgent\u002FsteerPrompt, or internal\u002Ftools\u002Fgoal.go's GoalController — or when a goal loop will not stop, stops one cycle early, closes a goal that is not met, or restarts a goal you finished.","https:\u002F\u002Fgithub.com\u002Fdimetron\u002Fpi-go\u002Fblob\u002Fmain\u002Finternal\u002Fextension\u002Fbundled_skills\u002Fverify-goal-loop\u002FSKILL.md",[121],{"categoryNo":75,"categoryName":76,"taxonomyType":77,"taxonomyTypeDesc":78},[123,89,20,124,125,92,37,36,33,32,126,127,86,83,128,129,130],"goal loop","verify goal","verify goal loop","you","automatic","Tools","it","stop",{"skillNo":132,"name":133,"nameZh":6,"description":134,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":135,"categories":136,"keywords":138,"publishedAt":39},"01M70SHPYN1AS6D6RJ8HN270RZ","verify-agent-lifecycle","Formally verify the subagent lifecycle before or after changing it. Use when editing internal\u002Fsubagent\u002Forchestrator.go's Spawn, trackAgent, forwardAgentEvents, terminalStatus, Cancel, ShutdownWithTimeout or evictCompletedAgentsLocked, or internal\u002Fsubagent\u002Fpool.go — or when a canceled agent is reported as failed, an agent vanishes from the list with no verdict, the orchestrator panics on a pool release, or an agent can be canceled twice.","https:\u002F\u002Fgithub.com\u002Fdimetron\u002Fpi-go\u002Fblob\u002Fmain\u002Finternal\u002Fextension\u002Fbundled_skills\u002Fverify-agent-lifecycle\u002FSKILL.md",[137],{"categoryNo":75,"categoryName":76,"taxonomyType":77,"taxonomyTypeDesc":78},[139,140,141,20,142,143,37,33,32,144,145,146,147,28,148,149,150,151,86,129],"lifecycle","verify agent lifecycle","agent lifecycle","pool","as","cancel","subagent","can","with","orchestrator","spawn","release","list",{"skillNo":153,"name":154,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":155,"categories":156,"keywords":161,"publishedAt":39},"01M6E37WZM8ZF36DRYQGZDGP7M","test-new-skill","https:\u002F\u002Fgithub.com\u002Fdimetron\u002Fpi-go\u002Fblob\u002Fmain\u002Finternal\u002Ftui\u002F.pi-go\u002Fskills\u002Ftest-new-skill\u002FSKILL.md",[157,160],{"categoryNo":158,"categoryName":159,"taxonomyType":77,"taxonomyTypeDesc":78},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":75,"categoryName":76,"taxonomyType":77,"taxonomyTypeDesc":78},[162,163,164,165],"test","new skill","test new skill","new",{"skillNo":167,"name":168,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":169,"categories":170,"keywords":171,"publishedAt":39},"01M6E37T9PQ6Q8NGVGFHR7QDFN","ponytail","https:\u002F\u002Fgithub.com\u002Fdimetron\u002Fpi-go\u002Fblob\u002Fmain\u002Finternal\u002Fextension\u002Fbundled_skills\u002Fponytail\u002FSKILL.md",[],[168]]