Skip to content

fix(planning): interview page wrap-up friction: stale closed question, id count confusion, ops re-apply, restate cap #5893

Closed
5 of 5 issues completed

Description

@kyle-sexton

Follow-up to #5795 and #5796, from the final round and wrap-up of the same /planning:interview page session (2026-10-02, 128 question ids, 49 live, 79 withdrawn). The user's words: "The UI is bugged. Question 128 still shows up, and I don't know why it's 128. Have we had 128 questions? I just want everything confirmed. I want this to be done."

Paths are relative to plugins/planning/.

1. A closed question still shows to the user as needing attention

Q128 was accepted (seq 228) and all three commitments ticked (seq 229-231); round.sh status reports its round "14 of 14 closed", and the register gate exits 0. The user still saw Q128 on the page as outstanding. Likely the same stale-tab path as #5710 (an open tab does not pick up a revise), since Q128's title and short were revised after the accept. Expected: a question that is closed on the server never shows as outstanding in an open tab.

2. Question ids read as a question count

Ids run on one session counter, so superseding Q5-Q30 three times (Q35-Q60, Q61-Q86, Q88-Q114) put the last question at Q128 while only 49 were ever live. Nothing on the page says so; the user read Q128 as "128 questions". Expected: the header or Rounds view shows live versus archived counts beside the ids, or ids are not the user's progress signal.

3. A failed ops.json write re-applies the previous batch

wake.sh applies whatever ops.json holds. When the session's Write of a new batch fails, the old batch is applied again; on 2026-10-02 this posted 18 replies twice, and no op deletes a reply. Expected: apply refuses a batch it already applied (a batch id or content hash), or wake.sh clears ops.json after a successful apply.

4. The restatement cap cannot hold the recap the skill requires

context/surface.md (Confirmation gate) requires one recap line per Q<N> in decisions, generated from export-ledger. With 128 ids that recap is 43,897 characters; apply refuses any section over 20,000 (restate section decisions is 43897 characters; the cap is 20000). The session had to collapse withdrawn rows and truncate answers by hand. Expected: the skill states a compact recap form (withdrawn rows collapsed, answers truncated) or export-ledger emits one that fits the cap.

5. A plain accept cannot answer a recommendation that also asks the user something

Q123's recommendation ended "Also tell me which rung you intend". The user pressed Accept with no note, which settles the headline but not the embedded question, so the session had to add Q128. Expected: the skill forbids an embedded question in a recommendation (ask it as its own question), or add warns on one.

6. Unhandled-event replay and lease handover after /clear

After /clear, the new session had to release the old session's lease by hand (round.sh lease --release) and re-arm; the old watcher's background task then failed with exit 3 in the new conversation, which reads as an error. Expected: the handover is one documented command, and the displaced watcher's exit is reported as a handover, not a failure.

Activity

  1. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 2, 2026
  2. kyle-sexton commented on Oct 4, 2026

    @kyle-sexton
    MemberAuthor

    This was generated by AI during triage.

    Routing: human-gated, needs-human, status: needs-decision, work-class: scoped, priority: medium (assessed default). This bundles six separate problems. Four of them carry an open design fork, and one is not verified against current code. It should be split with /work-items:decompose once the forks below are settled. Each slice then fits C3 on its own.

    Verification per item:

    1. Closed question still shows as outstanding. Not verified against current code. fix(planning): refuse a colliding recommendation and push same-tick question changes #5732 ("push same-tick question changes", the fix for the stale-tab half of planning interview page: revised recommendations not shown live, and alternatives not refreshed when the recommendation changes #5710) may already cover a revise after an accept. It needs a reproduction on the current page first.
    2. Ids read as a question count. Consistent with the design. Ids come from one session counter, and the meter counts only live questions. The meter's hover title gives the archived count, but the visible text does not. Basis: verified, plugins/planning/surface/index.html:853-854.
    3. A failed ops.json write re-applies the previous batch. Consistent with the code: wake.sh runs apply --file <data_dir>/ops.json unconditionally, and I found no batch id or hash check in apply. Basis: verified, plugins/planning/surface/wake.sh:13, round.py cmd_apply. Not reproduced.
    4. Restatement cap versus a full recap. Consistent: every restate section is capped at 20,000 characters. Basis: verified, round.py:102, 1169. The confirmation gate asks for one recap line per question. It is not checked how export-ledger sizes that recap today.
    5. An accept cannot answer a question embedded in the recommendation. This is a protocol gap, not a code defect.
    6. Lease handover after /clear. Not verified. round.sh lease --release exists. No single handover command was found.

    Where I looked: wake.sh, round.py (cmd_apply, caps, lease), the page meter, context/surface.md (Confirmation gate, ops table), closed #5710/#5732, docs/out-of-scope/ (nothing matches).

    Cluster check: this is not a carrier for any other item. #5795 and #5796 (sibling worker) are the same session's page audits, but cover different gaps. Item 1 may overlap #5710 (closed).

    Agent Brief

    Type: Bug
    Summary: Fix six wrap-up frictions on the interview page and its CLI, after the owner settles the forks below and the item is split into slices.

    Open decisions (owner):

    1. Item 2: show live and archived counts beside the ids (header or Rounds view), or stop using ids as a progress signal (for example, a per-session display number). Recommended: show the counts. It is display-only and reversible.
    2. Item 3: make apply refuse a batch it already applied (a batch id or content hash stored with the data), or have wake.sh clear ops.json after a successful apply. Recommended: refuse by content hash. It also catches a manual re-run, and a failed write still leaves the old file in place.
    3. Item 4: state a compact recap form in the skill (withdrawn rows collapsed, answers truncated), or have export-ledger emit one that fits the cap. Recommended: have the exporter emit it, so no session has to trim by hand.
    4. Item 5: forbid an embedded question in a recommendation (ask it as its own question), or have add warn on one. Recommended: forbid it in the skill text and have add warn. Refusing outright on text heuristics would misfire.
    5. Item 6: what one command performs the lease handover after /clear, and how the displaced watcher reports its exit.

    Current behavior: as in the issue body, items 1 to 6.

    Desired behavior:

    • A question closed on the server never shows as outstanding in an open tab.
    • The user can tell ids from the number of questions.
    • A batch of ops is never applied twice.
    • The confirmation recap fits the restatement cap without hand-trimming.
    • A recommendation never hides a second question.
    • Taking over an interview after /clear is one documented command, and the old watcher's exit reads as a handover, not an error.

    Acceptance criteria (per slice once decomposed):

    Out of scope:

  3. added
    priority: mediumReal value, no hard deadline; normal backlog flow.
    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.
    status: needs-decisionAwaiting a human or maintainer judgment call.
    work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.
    and removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 4, 2026
  4. kyle-sexton commented on Oct 13, 2026

    @kyle-sexton
    MemberAuthor

    Decision recorded. The owner approved applying independently verified recommendations on 2026-10-12.

    Six wrap-up frictions from the same interview session: a closed question still showing, ids read as a count, ops.json re-applied after a failed write, the restate cap below the required recap, embedded questions in recommendations, and lease handover after /clear. wake.sh and the 20,000-character cap are unchanged on main.

    Verification notes:

    • Q3 (stop a stale ops.json being applied twice) is already fixed. fix(planning): interview page answer controls, withheld questions, and apply idempotence #7280 (merged 2026-10-12) makes cmd_apply rename ops.json to ops.json.applying under the lock and delete it after a successful write, so a failed later Write finds no file and prints 'nothing to apply' (origin/main round.py:1386-1412). The record's basis (no batch hash, wake.sh applies unconditionally) is out of date.
    • Q2 basis line drifted: the meter's archived-count hover is now at index.html:870, not 853-854. Its content is unchanged.

    Verified by an independent fresh-context check (refuted, risk low): gh issue view 5893: triage only; origin/main wake.sh:13, round.py:102 (TEXT_CAP), 32 and 1940 (lease --release only), 1386-1412 (cmd_apply); index.html:870 meter title; PR #7280 body

    Admission to an agent lane stays with the work-class rules and owner ratification.

  5. added theissue type on Oct 15, 2026
  6. kyle-sexton commented on Oct 17, 2026

    @kyle-sexton
    MemberAuthor

    Owner decision 2026-10-17: refresh the remaining-work list (part already shipped in #7278/#7280) and decompose into child issues; the owner ratifies the children.

  7. kyle-sexton commented on Oct 17, 2026

    @kyle-sexton
    MemberAuthor

    Remaining-work refresh and decomposition per the owner decision of 2026-10-17. Checked against origin/main at fd71a30a05 and the body of #7280.

    Done (no child): item 3, a failed ops.json write re-applying the previous batch. #7280 (DX-1) makes apply claim the file by renaming it under the sidecar lock and remove it after a successful write; a later run prints nothing to apply.

    Remaining, as 5 child issues (sub-issues of this one, all needs-human for owner ratification; none is admitted):

    Item Child
    1, closed question shown as outstanding (reproduce first; may be covered by #5732) #7757
    2, live and archived counts beside ids #7758
    4, compact recap from export-ledger within the cap #7759
    5, no question embedded in a recommendation; add warns #7760
    6, one-command lease handover after /clear #7761

    No dependency edges. This issue stays open as the parent.

  8. kyle-sexton commented on Oct 24, 2026

    @kyle-sexton
    MemberAuthor

    Closed by the owner's HITL session under 2C/Q87 (2026-10-24), with a second agent's independent agreement. Item 3 shipped in #7280; #7758-#7761 closed by merged PRs #8092, #7801, #8142, #7798; open #7757 carries item 1. To reopen: reopen this issue and say what is still missing.

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

    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.priority: mediumReal value, no hard deadline; normal backlog flow.work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions