Summary
ce-work reads completion out of git. That works until a unit's deliverable lives somewhere else: a setting in a third-party console, a DNS record, a CMS object, rows applied to a live system. No diff, no commit, nothing for either completion mechanism to attach to. The unit reads as not-started on every pass after the first, and a resumed session has no way to separate it from one nobody ever touched. If the external side effect is not idempotent, the loop re-applies it.
I don't want a status system out of this. #1349 asked for one and the answer it got was fair. What follows corrects one condition.
The existing condition does not cover this case
AGENTS.md is clear that a case an existing condition already decides is not a finding, so here is why this one isn't. The idempotency pass reads (skills/ce-work/references/implementation-loop.md:13):
If the unit's work is already present and matches the plan's intent (files exist with the expected capability, or the unit's Verification criteria are already satisfied by the current code), the work has likely shipped on a prior branch or session.
Two branches, and "by the current code" scopes both of them to the working tree. A unit with no tree footprint can satisfy its Verification criteria completely out in the world and the second branch still evaluates false, because the criteria are not satisfied by code. The condition doesn't decide the case. It resolves it wrong, quietly.
Mechanism two is the U-ID appended to commit subjects (skills/ce-commit/SKILL.md:40, PR #1379). Sound design, and about as cheap as a mitigation gets, but it needs a commit to attach to and the unit produces none.
The repo already documents this pattern
docs/solutions/skill-design/watch-loops-need-a-blocked-external-terminal-state.md states the general form:
don't let a single endpoint's completeness assumption become your loop's completeness assumption.
And under When to Apply:
check whether "blocked on a third party, unbounded timeline, no one in this loop can act" is already collapsing into an existing bucket ... rather than getting its own condition
That Learning covers ce-babysit-pr and statusCheckRollup, so it doesn't answer this. Git is the single source whose completeness assumption became ce-work's, and "output isn't in the tree" collapses into "unit isn't done."
execution: sits at plan level
execution is plan frontmatter, code or knowledge-work (skills/ce-plan/references/plan-sections.md:426-428). A plan picks one. A code plan then routinely mixes units: six landing in the repo, one configuring a service. The plan is right to be execution: code. Unit seven has nowhere to say it behaves like the other mode.
The unit schema leaves no room for it either. Files is specified as "repo-relative file paths to create, modify, or test (never absolute paths)" (skills/ce-plan/references/structure.md:93).
To be plain about scope: I'm not asking ce-work to perform out-of-repo work or to take on deployment. Users write these units into code plans today and ce-work executes them today. The gap is what happens to their status afterward.
Prior art
The plan body stays closed as a status surface. workspace-setup.md:11, structure.md:85, and the readiness-value rule at input-triage.md:45 all hold, and nothing here asks to reopen any of them.
Ask
Either one works. The second on its own would help.
1. Fix the condition. Test whether the unit's Verification criteria are satisfied, rather than whether they are satisfied by the current code, and give the pass somewhere safe to land when it can't tell: ask, instead of assuming not-started and re-running the work. Whether a unit needs an optional field to declare its output external is a mechanism question I'd leave to you (plan-sections.md:437 notes new fields are fine while existing names stay stable).
2. Docs only. A line in ce-work's references saying a unit that produces out-of-repo state has no derivable status and belongs in a tracker outside the plan. Two sentences. A fresh session would at least know to look elsewhere.
Per CONTRIBUTING's issue-first gate, happy to open a PR for either if the direction is welcome.
Summary
ce-workreads completion out of git. That works until a unit's deliverable lives somewhere else: a setting in a third-party console, a DNS record, a CMS object, rows applied to a live system. No diff, no commit, nothing for either completion mechanism to attach to. The unit reads as not-started on every pass after the first, and a resumed session has no way to separate it from one nobody ever touched. If the external side effect is not idempotent, the loop re-applies it.I don't want a status system out of this. #1349 asked for one and the answer it got was fair. What follows corrects one condition.
The existing condition does not cover this case
AGENTS.mdis clear that a case an existing condition already decides is not a finding, so here is why this one isn't. The idempotency pass reads (skills/ce-work/references/implementation-loop.md:13):Two branches, and "by the current code" scopes both of them to the working tree. A unit with no tree footprint can satisfy its
Verificationcriteria completely out in the world and the second branch still evaluates false, because the criteria are not satisfied by code. The condition doesn't decide the case. It resolves it wrong, quietly.Mechanism two is the U-ID appended to commit subjects (
skills/ce-commit/SKILL.md:40, PR #1379). Sound design, and about as cheap as a mitigation gets, but it needs a commit to attach to and the unit produces none.The repo already documents this pattern
docs/solutions/skill-design/watch-loops-need-a-blocked-external-terminal-state.mdstates the general form:And under When to Apply:
That Learning covers
ce-babysit-prandstatusCheckRollup, so it doesn't answer this. Git is the single source whose completeness assumption becamece-work's, and "output isn't in the tree" collapses into "unit isn't done."execution:sits at plan levelexecutionis plan frontmatter,codeorknowledge-work(skills/ce-plan/references/plan-sections.md:426-428). A plan picks one. Acodeplan then routinely mixes units: six landing in the repo, one configuring a service. The plan is right to beexecution: code. Unit seven has nowhere to say it behaves like the other mode.The unit schema leaves no room for it either.
Filesis specified as "repo-relative file paths to create, modify, or test (never absolute paths)" (skills/ce-plan/references/structure.md:93).To be plain about scope: I'm not asking
ce-workto perform out-of-repo work or to take on deployment. Users write these units intocodeplans today andce-workexecutes them today. The gap is what happens to their status afterward.Prior art
plan-status— derived progress + spec-drift view for unified plans #1349: derived sidecar, per-unit verdicts, Drift Ledger,--checkmerge gate. Closed as too heavyweight. None of it appears below. The ask adds no sidecar, no script, and no merge gate.task_plan.md, and explicit that the plan doc stays the single authority. Different ask. Noting it so this doesn't read as reopening it.The plan body stays closed as a status surface.
workspace-setup.md:11,structure.md:85, and the readiness-value rule atinput-triage.md:45all hold, and nothing here asks to reopen any of them.Ask
Either one works. The second on its own would help.
1. Fix the condition. Test whether the unit's
Verificationcriteria are satisfied, rather than whether they are satisfied by the current code, and give the pass somewhere safe to land when it can't tell: ask, instead of assuming not-started and re-running the work. Whether a unit needs an optional field to declare its output external is a mechanism question I'd leave to you (plan-sections.md:437notes new fields are fine while existing names stay stable).2. Docs only. A line in
ce-work's references saying a unit that produces out-of-repo state has no derivable status and belongs in a tracker outside the plan. Two sentences. A fresh session would at least know to look elsewhere.Per CONTRIBUTING's issue-first gate, happy to open a PR for either if the direction is welcome.