pub fn phase_has_human_only_checkpoint(
project_root: &Path,
phase: PhaseId,
) -> boolExpand description
Return true if any plan declared for phase DECLARES a checkpoint task
that GSD will not auto-approve in any mode.
The match is anchored to a task element’s own opening tag, and that is
the whole difference between this function and
phase_has_blocking_human_checkpoint above: a marker qualifies only on a
line that also opens a <task. A plan that merely discusses a marker — in
a findings section, in a table, in a fenced example — has not declared one.
The concrete failures the anchoring prevents (F-14) were measured against
this repository’s own plan files, not assumed: 34-04-PLAN.md:245 and
33-02-PLAN.md:109 each quote gate="blocking-human" inside a sentence
while declaring no such task. Under an unanchored whole-file contains,
preflight.rs’s unattended-launch check reads phases 33 and 34 as carrying a
checkpoint no mode can approve and refuses an overnight run that was fine. A
false refusal has no in-product recovery (D-09), so a false positive here is
not a cosmetic defect. (F-14 itself names 35.1-03-PLAN.md as the instance;
that file describes the markers only in English and never writes either
literal, so it would not match an unanchored scan either. The finding stands;
the example it cited does not.)
Known limit, pinned by human_only_checkpoint_still_matches_a_task_tag_ inside_a_fenced_example: the anchor is line-level and has no notion of
markdown fences, so a plan documenting a COMPLETE example <task ...> tag
inside a fenced block still matches. No plan file in this repository has that
shape today.
phase_has_blocking_human_checkpoint is deliberately left alone, and the
pair is not an accident. That function serves the plan-28-03 auto-decide
route, where a looser, over-inclusive match fails SAFE — it routes more
checkpoints to a human. Here an over-inclusive match fails toward refusing a
launch. Different consequence, different predicate; widening the older one to
serve both would silently change the behaviour its seven tests pin.
Returns false for a phase with no plan files at all. That is NOT the same
fact as “plans exist and declare no such checkpoint”, and a caller that needs
to tell them apart asks phase_plan_files separately rather than reading a
third state out of one bit.
The CALLER owns root resolution, exactly as for
phase_has_blocking_human_checkpoint: in worktree mode the phase’s plans
live on the feature branch inside the worktree and are absent from the main
checkout (999.76).