Skip to content

planning/interview: template's own "Open-question register" heading shadows the live register, making the Step 3 gate ungradeable #4073

Description

@kyle-sexton

Symptom

/planning:interview Step 3's mandatory register gate (scripts/check-open-questions.sh) exits 2 (ungradeable) on a correctly filled ledger:

error: the register section holds no question rows in: .work/<topic>/interview-checklist.md
registered=0 open=0 deferred=0 blocked=0 withdrawn=0 answered=0 brief=unchecked status=ungradeable
exit=2

The ledger had seven correctly shaped rows. Exit 2 halts per the skill's own contract, so the interview cannot lock its contract until the operator diagnoses a plugin-internal problem mid-session.

Root cause

extract_section() returns the body of the first heading matching the pattern and stops at the next heading of any level. skills/interview/templates/checklist.md ships its own instructional section titled exactly ## Open-question register, and the skill instructs the operator to copy that template into the memory slice and maintain the live register inside it. Every copied ledger therefore holds two headings with that name. The gate binds to the instructional one, whose fenced example rows do not parse as register rows, and reports registered=0.

Two further defects found while fixing it:

  • The template's register section carries a fenced bash block whose # Step 3, ... comment line matched the heading regex and terminated the section, hiding any row written after it.
  • The row loop skipped every row after an unterminated fence as documentation, so an open row behind a stray fence graded clean (exit 0).

Reproduction

  1. Run /planning:interview on any topic with two or more open questions.
  2. Copy skills/interview/templates/checklist.md to <memory_dir>/<topic>/interview-checklist.md as instructed.
  3. Append a ## Open-question register section with valid rows.
  4. bash scripts/check-open-questions.sh --ledger <that file> exits 2 with registered=0.

Fix

PR #4065: duplicate matching headings make the gate exit 2 naming every candidate line rather than silently binding first or last; heading detection and section extraction are fence-aware; an unterminated fence exits 2; diagnostics name the bound heading and its line number.

Deferred: marking the live register with a structural sentinel pair so identification does not depend on a heading that documentation naturally repeats. That changes the template and skill contract, not only the script.

Origin: handoff-inbox item 20260907-104819-planning-interview-register-gate-heading-shadowing, observed at planning 0.39.0 during a live interview run.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions