UAT scratch (Scenario 4): coexistence /dev:requirements run — disposable #53

Closed
opened 2026-08-16 12:27:50 +00:00 by jbr870 · 2 comments
Owner

UAT SCRATCH — Scenario 4 of the #50 plugin-migration UAT. Disposable test data; do not triage.
This issue was reused as the target of a coexistence /dev:requirements run from the plugin form
(farm intact). The PREQ below is a vehicle for exercising the skill, not queued work.

PREQ: Feature-issue digest view

Created: 2026-08-16

Problem

Anyone reading a feature issue struggles to tell what is currently true when the issue has
accumulated a long thread of records. Phase Outcomes, deliverables, decisions and resolutions are
interleaved in posting order, and later records supersede earlier ones — so the reader must replay
the whole thread and apply the lookup rule by hand to answer even basic questions.

Users:

  • Primary: The orchestrator picking a feature back up after a gap — needs "where is this, and
    what is it waiting on?" before doing anything else.
  • Secondary: A skill's gate mid-run (the decisions-settled check, /dev:resolve's discovery)
    needing the same answer programmatically rather than by eye.

Current state: Scroll the issue thread and reconstruct the current state mentally, or call the
per-record read helpers one at a time. Both are manual, and both get slower and less reliable the
longer the feature has run.

Proposed Solution

A read-only view over a single feature issue. It resolves that issue's records once into one
canonical current state, then renders that same state two ways: a human-readable digest by
default, and the identical resolved state in machine-readable form on request.

Both renderings come from one resolution pass, so a human reading the digest and a gate reading
the machine form cannot disagree about what is current.

What the view reports — exactly three record types, and no others:

  1. The feature's current phase.
  2. Its deliverables, at their current values.
  3. Its decisions, split into still-open and resolved.

Anything the view could not parse is reported as an anomaly alongside the three (see AC9); it is
never silently dropped.

Scope: Standard — serves both consumers the problem named, without touching existing consumers.
The Minimal option (digest only) would leave the gate consumer unserved; the Full option
(refactoring existing gates onto the new resolver) was declined because it puts new code in the
pipeline's decision gates rather than in a read-only view. Consequently the machine rendering's
deliverable is availability and correctness — adopting it in an existing gate is a separate
feature (see Out of Scope).

User Stories

  • As an orchestrator returning to a feature after a gap, I want one view of the phase, deliverables
    and decisions that are currently true, so that I can tell where it stands without replaying the
    comment thread.
  • As an orchestrator, I want the decisions that are still open named with their IDs, so that I can
    act on them directly instead of hunting for which ones were already answered.
  • As a skill's gate running mid-pipeline, I want that same resolved state available in
    machine-readable form, so that when a gate is later wired to it, its decision matches what a human
    reading the digest would conclude. (This feature delivers the machine form; wiring a gate to it is
    out of scope.)

Acceptance Criteria

  • AC1 Given a feature issue carrying at least one Phase Outcome, when the digest is
    requested, then it reports the feature's current phase as the next_state of the most recent
    Phase Outcome.
  • AC2 Given an issue where the same deliverable kind was posted more than once, when the
    digest is requested, then only the most recent value is presented as current and the
    superseded one is not.
  • AC3 Given an issue carrying decisions, when the digest is requested, then every decision
    with no resolution is listed as open together with its decision ID.
  • AC4 Given a decision that was later resolved, when the digest is requested, then it is
    reported as resolved with the option that was chosen, and does not appear in the open list.
  • AC5 Given both renderings are produced from a single invocation for one issue, when they
    are compared, then they report the same state in full — same current phase, same current
    deliverables, same open decisions with their IDs, same resolved decisions with their chosen
    options, and the same reported anomalies. Any difference other than presentation format is a
    failure.
  • AC6 Given a feature issue with no Phase Outcome posted yet, when the digest is requested,
    then it reports that the feature has not started a phase; and given an issue carrying none of
    the three reported record types, then every reported section is still present and explicitly
    shown as empty, never omitted.
  • AC7 Given an issue number that does not exist, when the digest is requested, then it
    reports that the issue was not found and produces no digest.
  • AC8 Given the issue cannot be read — the forge is unreachable, access is denied, or a read
    fails part-way through resolution — when the digest is requested, then the view reports a read
    failure distinctly from "issue not found", never presents a partial digest as if it were
    complete, and signals the failure in whichever rendering was requested.
  • AC9 Given a record that cannot be parsed, or a resolution naming a decision ID that was
    never raised, when the digest is requested, then that record is reported as an anomaly rather
    than silently omitted.
  • AC10 Given the digest has been requested for an issue, when that issue is inspected
    afterwards, then no comment, label, or body content on it has been added or changed.

Out of Scope

  • Mutating anything. The view is strictly read-only; it never resolves a decision, advances a
    phase, or posts a record.
  • Wiring any existing consumer onto the machine rendering. The deliverable here is that the
    machine form exists and is correct. Adopting it in the decisions-settled gate or /dev:resolve's
    discovery is a separate feature — the "Full" scope option was explicitly declined.
  • Digesting more than one issue at a time. Single-issue only; no cross-feature roll-up, board,
    or queue view.
  • Redefining resolution semantics. The view reports what the forge contract's lookup rule
    already dictates about supersession; it does not introduce a second notion of "current". AC2–AC4
    are restatements for readability, not definitions — see Dependencies.
  • Reporting record types beyond the three named in Proposed Solution.

Dependencies

  • The forge contract's lookup rule (forge-contract.md §9) — the definition of supersession this
    view reports against. §9 is authoritative on any divergence: AC2, AC3 and AC4 restate its
    behaviour for readability, and where the restatement and §9 differ — an edited comment, a decision
    resolved more than once, any tie in ordering — §9 governs and the view follows it.
  • The active forge adapter's read primitives. No adapter restriction was declared, so the view must
    work wherever the suite works, via the normal adapter dispatch — not against one adapter's
    storage shape.
  • External systems of record: none. The view reads only records the suite itself wrote to the
    feature issue.

Timeline

Milestone Date Notes
Requirements complete 2026-08-16
Development complete
QA complete
UAT approved

Notes

  • Constraints: none declared — no deadline, no adapter restriction, no known limitation.
    Backlog-shaped.
  • Open questions: none outstanding.
  • Key decisions:
    • Both consumers (human reader and skill gate) are in scope, resolved from a single resolution
      pass so the two renderings cannot disagree.
    • Scope Standard chosen over Minimal (would serve only the human) and Full (would place new
      code in the pipeline's decision gates).
    • From the Tier 2 adversarial panel (ambiguity / completeness / consistency): AC5 requires
      exhaustive parity rather than a three-field spot-check; §9 governs over AC2–AC4 on conflict;
      error behaviour is specified as one class (AC8) covering the machine form, read failure and
      partial reads; the machine rendering's deliverable is availability, not adoption; "current
      phase" is pinned to next_state; the reported record types are enumerated and the empty issue
      renders empty sections rather than omitting them; unparseable and dangling records are surfaced
      as anomalies.
    • Dispositioned without amendment: the invocation surface (flag vs separate command) is a design
      choice deferred to /dev:technical-plan.
  • Observability: the project declares observability: mode: none, so the applicability test
    yields no intersection and this PREQ carries no observability or audit criteria.
> **UAT SCRATCH — Scenario 4 of the #50 plugin-migration UAT. Disposable test data; do not triage.** > This issue was reused as the target of a coexistence `/dev:requirements` run from the plugin form > (farm intact). The PREQ below is a vehicle for exercising the skill, not queued work. # PREQ: Feature-issue digest view **Created:** 2026-08-16 ## Problem Anyone reading a feature issue struggles to tell what is **currently** true when the issue has accumulated a long thread of records. Phase Outcomes, deliverables, decisions and resolutions are interleaved in posting order, and later records supersede earlier ones — so the reader must replay the whole thread and apply the lookup rule by hand to answer even basic questions. **Users:** - **Primary:** The orchestrator picking a feature back up after a gap — needs "where is this, and what is it waiting on?" before doing anything else. - **Secondary:** A skill's gate mid-run (the decisions-settled check, `/dev:resolve`'s discovery) needing the same answer programmatically rather than by eye. **Current state:** Scroll the issue thread and reconstruct the current state mentally, or call the per-record read helpers one at a time. Both are manual, and both get slower and less reliable the longer the feature has run. ## Proposed Solution A **read-only** view over a single feature issue. It resolves that issue's records once into one canonical *current state*, then renders that same state two ways: a human-readable digest by default, and the identical resolved state in machine-readable form on request. Both renderings come from **one** resolution pass, so a human reading the digest and a gate reading the machine form cannot disagree about what is current. **What the view reports** — exactly three record types, and no others: 1. The feature's current phase. 2. Its deliverables, at their current values. 3. Its decisions, split into still-open and resolved. Anything the view could not parse is reported as an anomaly alongside the three (see AC9); it is never silently dropped. **Scope:** Standard — serves both consumers the problem named, without touching existing consumers. The Minimal option (digest only) would leave the gate consumer unserved; the Full option (refactoring existing gates onto the new resolver) was declined because it puts new code in the pipeline's decision gates rather than in a read-only view. Consequently the machine rendering's deliverable is **availability and correctness** — adopting it in an existing gate is a separate feature (see Out of Scope). ## User Stories - As an orchestrator returning to a feature after a gap, I want one view of the phase, deliverables and decisions that are currently true, so that I can tell where it stands without replaying the comment thread. - As an orchestrator, I want the decisions that are still open named with their IDs, so that I can act on them directly instead of hunting for which ones were already answered. - As a skill's gate running mid-pipeline, I want that same resolved state available in machine-readable form, so that when a gate is later wired to it, its decision matches what a human reading the digest would conclude. (This feature delivers the machine form; wiring a gate to it is out of scope.) ## Acceptance Criteria - [ ] **AC1** Given a feature issue carrying at least one Phase Outcome, when the digest is requested, then it reports the feature's current phase as the `next_state` of the most recent Phase Outcome. - [ ] **AC2** Given an issue where the same deliverable kind was posted more than once, when the digest is requested, then only the most recent value is presented as current and the superseded one is not. - [ ] **AC3** Given an issue carrying decisions, when the digest is requested, then every decision with no resolution is listed as open together with its decision ID. - [ ] **AC4** Given a decision that was later resolved, when the digest is requested, then it is reported as resolved with the option that was chosen, and does not appear in the open list. - [ ] **AC5** Given both renderings are produced from a single invocation for one issue, when they are compared, then they report the same state **in full** — same current phase, same current deliverables, same open decisions with their IDs, same resolved decisions with their chosen options, and the same reported anomalies. Any difference other than presentation format is a failure. - [ ] **AC6** Given a feature issue with no Phase Outcome posted yet, when the digest is requested, then it reports that the feature has not started a phase; and given an issue carrying none of the three reported record types, then every reported section is still present and explicitly shown as empty, never omitted. - [ ] **AC7** Given an issue number that does not exist, when the digest is requested, then it reports that the issue was not found and produces no digest. - [ ] **AC8** Given the issue cannot be read — the forge is unreachable, access is denied, or a read fails part-way through resolution — when the digest is requested, then the view reports a read failure *distinctly from* "issue not found", never presents a partial digest as if it were complete, and signals the failure in whichever rendering was requested. - [ ] **AC9** Given a record that cannot be parsed, or a resolution naming a decision ID that was never raised, when the digest is requested, then that record is reported as an anomaly rather than silently omitted. - [ ] **AC10** Given the digest has been requested for an issue, when that issue is inspected afterwards, then no comment, label, or body content on it has been added or changed. ## Out of Scope - **Mutating anything.** The view is strictly read-only; it never resolves a decision, advances a phase, or posts a record. - **Wiring any existing consumer onto the machine rendering.** The deliverable here is that the machine form exists and is correct. Adopting it in the decisions-settled gate or `/dev:resolve`'s discovery is a separate feature — the "Full" scope option was explicitly declined. - **Digesting more than one issue** at a time. Single-issue only; no cross-feature roll-up, board, or queue view. - **Redefining resolution semantics.** The view reports what the forge contract's lookup rule already dictates about supersession; it does not introduce a second notion of "current". AC2–AC4 are restatements for readability, not definitions — see Dependencies. - **Reporting record types beyond the three named** in Proposed Solution. ## Dependencies - The forge contract's lookup rule (`forge-contract.md` §9) — the definition of supersession this view reports against. **§9 is authoritative on any divergence:** AC2, AC3 and AC4 restate its behaviour for readability, and where the restatement and §9 differ — an edited comment, a decision resolved more than once, any tie in ordering — §9 governs and the view follows it. - The active forge adapter's read primitives. No adapter restriction was declared, so the view must work wherever the suite works, via the normal adapter dispatch — not against one adapter's storage shape. - **External systems of record:** none. The view reads only records the suite itself wrote to the feature issue. ## Timeline | Milestone | Date | Notes | |-----------|------|-------| | Requirements complete | 2026-08-16 | | | Development complete | | | | QA complete | | | | UAT approved | | | ## Notes - **Constraints:** none declared — no deadline, no adapter restriction, no known limitation. Backlog-shaped. - **Open questions:** none outstanding. - **Key decisions:** - Both consumers (human reader and skill gate) are in scope, resolved from a single resolution pass so the two renderings cannot disagree. - Scope **Standard** chosen over Minimal (would serve only the human) and Full (would place new code in the pipeline's decision gates). - *From the Tier 2 adversarial panel (ambiguity / completeness / consistency):* AC5 requires exhaustive parity rather than a three-field spot-check; §9 governs over AC2–AC4 on conflict; error behaviour is specified as one class (AC8) covering the machine form, read failure and partial reads; the machine rendering's deliverable is availability, not adoption; "current phase" is pinned to `next_state`; the reported record types are enumerated and the empty issue renders empty sections rather than omitting them; unparseable and dangling records are surfaced as anomalies. - *Dispositioned without amendment:* the invocation surface (flag vs separate command) is a design choice deferred to `/dev:technical-plan`. - **Observability:** the project declares `observability: mode: none`, so the applicability test yields no intersection and this PREQ carries no observability or audit criteria.
Author
Owner

Test Plan: issue-digest-view

Scenarios derived from the PREQ alone, blind to any design. Lanes are deliberately absent — an
absent lane means e2e-browser; /dev:technical-plan 2.6b assigns the real lanes once the design
exists.

Prerequisites

The scenarios need states of a feature issue, not an environment. Concrete environment details
(instance, credentials, invocation surface) belong to the UAT card generated at the end of QA.

  • A working forge connection for the project's declared adapter, and the ability to read a
    feature issue through it.
  • The ability to make the forge temporarily unreachable, and the ability to present credentials
    that cannot read a given issue (needed by Scenarios 9 and 10).

Required Test Data

Six feature issues in distinct states:

  • Issue A — rich history. At least two Phase Outcomes (so one is superseded); at least one
    deliverable kind posted twice with different values; at least two decisions, one still
    open and one that was later resolved with a recorded chosen option.
  • Issue B — started but bare. Exactly one Phase Outcome, no deliverables, no decisions.
  • Issue C — wholly empty. An issue with none of the three reported record types: no Phase
    Outcome, no deliverable, no decision.
  • Issue D — malformed record. Carries a comment that resembles a record but cannot be
    parsed.
  • Issue E — dangling resolution. Carries a resolution naming a decision ID that was never
    raised on that issue.
  • An issue number that does not exist on the project (Scenario 8).

Test Scenarios

Scenario 1: Current phase is reported

Acceptance criterion: AC1 — Given a feature issue carrying at least one Phase Outcome, when the
digest is requested, then it reports the feature's current phase as the next_state of the most
recent Phase Outcome.

  1. Note, by reading Issue A directly, which Phase Outcome is the most recent and what its
    next_state says.
  2. Request the digest for Issue A.
  3. Verify: the digest names a current phase, and it is the value you noted in step 1 — not the phase
    that outcome reports as completed, and not the next_state of any earlier outcome.

Expected outcome: A reader learns where the feature is now from the digest alone, without
opening the issue.

Scenario 2: A superseded deliverable is not presented as current

Acceptance criterion: AC2 — only the most recent value of a deliverable kind is presented as
current, and the superseded one is not.

  1. Note the two values Issue A carries for the twice-posted deliverable kind, and which was posted
    later.
  2. Request the digest for Issue A.
  3. Verify: the later value appears as that kind's current value.
  4. Verify: the earlier value does not appear anywhere the digest presents as current state.

Expected outcome: The digest shows one current value per deliverable kind, and it is the newest.

Scenario 3: Open decisions are listed with their IDs

Acceptance criterion: AC3 — every decision with no resolution is listed as open together with
its decision ID.

  1. Note the ID of Issue A's unresolved decision.
  2. Request the digest for Issue A.
  3. Verify: that decision appears in a list of open decisions.
  4. Verify: its decision ID is shown, in a form you could quote back when acting on it.

Expected outcome: The reader can act on an open decision straight from the digest, without
searching the thread for its ID.

Scenario 4: A resolved decision shows its chosen option and leaves the open list

Acceptance criterion: AC4 — a resolved decision is reported as resolved with the option that was
chosen, and does not appear in the open list.

  1. Note Issue A's resolved decision and which option was chosen.
  2. Request the digest for Issue A.
  3. Verify: that decision is reported as resolved, and the option shown is the one that was chosen.
  4. Verify: it does not appear in the open-decision list.

Expected outcome: Open and settled decisions are unambiguously separated.

Scenario 5: The two renderings agree in full

Acceptance criterion: AC5 — both renderings, produced from a single invocation for one issue,
report the same state in full; any difference other than presentation format is a failure.

  1. Request both renderings for Issue A from a single invocation.
  2. Compare them item by item on: the current phase; the set of current deliverables and their
    values; the set of open decisions and their IDs; the set of resolved decisions and their chosen
    options; and any reported anomalies.
  3. Verify: every one of those matches. The only differences are how the information is laid out.

Expected outcome: A human reading the digest and a consumer reading the machine form reach
identical conclusions about what is current.

Scenario 6: A feature that has not started a phase

Acceptance criterion: AC6 (first half) — an issue with no Phase Outcome reports that the feature
has not started a phase.

  1. Request the digest for an issue carrying no Phase Outcome (Issue C, or Issue B with its single
    outcome removed).
  2. Verify: the digest states the feature has not started a phase.
  3. Verify: it does not fail, and it does not show a blank or unknown phase that a reader could
    mistake for a real one.

Expected outcome: "Not started" is reported as a real state, not as an error or a gap.

Scenario 7: A wholly empty issue shows empty sections, not missing ones

Acceptance criterion: AC6 (second half) — for an issue carrying none of the three reported
record types, every reported section is still present and explicitly shown as empty.

  1. Request the digest for Issue C.
  2. Verify: sections for phase, deliverables and decisions are all present.
  3. Verify: each is explicitly marked as empty — a reader can tell "there are none" apart from "this
    was not reported".

Expected outcome: Emptiness is stated, never implied by omission.

Scenario 8: A nonexistent issue

Acceptance criterion: AC7 — the view reports that the issue was not found and produces no
digest.

  1. Request the digest for an issue number that does not exist on the project.
  2. Verify: the view reports that the issue was not found.
  3. Verify: no digest content is produced — no phase, no deliverables, no decisions, empty or
    otherwise.

Expected outcome: A wrong issue number is unmistakable and produces nothing that could be read
as a real digest.

Scenario 9: A read failure is distinguished from "not found"

Acceptance criterion: AC8 — the view reports a read failure distinctly from "issue not found".

  1. Make the forge unreachable.
  2. Request the digest for Issue A — an issue you know exists.
  3. Verify: the view reports that it could not read the issue.
  4. Verify: the wording or signal differs from Scenario 8's "not found" — a reader (and a
    programmatic consumer) can tell "this issue does not exist" from "I could not reach the forge".
  5. Restore the connection and repeat for the machine rendering.
  6. Verify: the machine rendering signals the same failure rather than returning a digest.

Expected outcome: The two failure causes are never conflated — one means the issue is wrong, the
other means the environment is.

Scenario 10: Access denied

Acceptance criterion: AC8 — read failure covers access denial as well as unreachability.

  1. Present credentials that cannot read Issue A.
  2. Request the digest for Issue A.
  3. Verify: the view reports a read failure, not "issue not found" and not an empty digest.

Expected outcome: An issue you are not allowed to read never masquerades as an issue with no
records.

Scenario 11: A partial read is never presented as complete

Acceptance criterion: AC8 — the view never presents a partial digest as if it were complete.

  1. Interrupt the connection part-way through a request for Issue A, so some records have been read
    and others have not.
  2. Verify: the view either reports a read failure, or presents its output explicitly marked as
    incomplete.
  3. Verify: it does not emit a normal-looking digest that silently omits the records it never read.

Expected outcome: An incomplete answer is always labelled as one — the reader is never given a
short digest they would take for the whole picture.

Scenario 12: An unparseable record is surfaced

Acceptance criterion: AC9 — a record that cannot be parsed is reported as an anomaly rather than
silently omitted.

  1. Request the digest for Issue D.
  2. Verify: the digest reports an anomaly identifying that there is a record it could not understand,
    and points to it well enough to go find it.
  3. Verify: the rest of the digest still reports the records it could read.

Expected outcome: A corrupt record is visible in the very view whose job is "what is current".

Scenario 13: A resolution naming an unknown decision is surfaced

Acceptance criterion: AC9 — a resolution naming a decision ID that was never raised is reported
as an anomaly.

  1. Request the digest for Issue E.
  2. Verify: the digest reports an anomaly naming the dangling resolution and the decision ID it
    refers to.
  3. Verify: the dangling resolution does not silently create a decision entry, and does not silently
    disappear.

Expected outcome: A record that cannot be attached to anything is reported, not dropped.

Scenario 14: The view changes nothing

Acceptance criterion: AC10 — after requesting the digest, no comment, label, or body content on
the issue has been added or changed.

  1. Record Issue A's full state: its body, its comments, and its labels.
  2. Request the digest for Issue A, in both renderings, and repeat several times.
  3. Compare Issue A's body, comments and labels against what you recorded.
  4. Verify: nothing was added, removed or modified.

Expected outcome: The view is safe to run at any point in a feature's life, including mid-run.

Traceability

Forward — every acceptance criterion has at least one scenario:

AC Scenarios
AC1 1
AC2 2
AC3 3
AC4 4
AC5 5
AC6 6, 7
AC7 8
AC8 9, 10, 11
AC9 12, 13
AC10 14

Backward — every scenario names its parent criterion above; there are no orphans.

Notes

  • Scenarios 9, 10 and 11 need the forge manipulated (unreachable, denied, interrupted). They are
    requirement-derived, not design-derived: AC8 states the behaviour, and how it is exercised is for
    /dev:technical-plan to lane.
  • The invocation surface — how the digest and the machine rendering are asked for — is deliberately
    not named. The PREQ does not decide it; naming it here would be testing a guessed design.
  • Scenario numbers are referenced by downstream findings. Keep existing numbers stable and append
    only.
<!-- test-plan:v1 issue=53 skill=requirements --> # Test Plan: issue-digest-view Scenarios derived from the PREQ alone, blind to any design. Lanes are deliberately absent — an absent lane means `e2e-browser`; `/dev:technical-plan` 2.6b assigns the real lanes once the design exists. ## Prerequisites The scenarios need *states of a feature issue*, not an environment. Concrete environment details (instance, credentials, invocation surface) belong to the UAT card generated at the end of QA. - [ ] A working forge connection for the project's declared adapter, and the ability to read a feature issue through it. - [ ] The ability to make the forge temporarily unreachable, and the ability to present credentials that cannot read a given issue (needed by Scenarios 9 and 10). ### Required Test Data Six feature issues in distinct states: - [ ] **Issue A — rich history.** At least two Phase Outcomes (so one is superseded); at least one deliverable kind posted **twice** with different values; at least two decisions, one still open and one that was later resolved with a recorded chosen option. - [ ] **Issue B — started but bare.** Exactly one Phase Outcome, no deliverables, no decisions. - [ ] **Issue C — wholly empty.** An issue with none of the three reported record types: no Phase Outcome, no deliverable, no decision. - [ ] **Issue D — malformed record.** Carries a comment that resembles a record but cannot be parsed. - [ ] **Issue E — dangling resolution.** Carries a resolution naming a decision ID that was never raised on that issue. - [ ] **An issue number that does not exist** on the project (Scenario 8). ## Test Scenarios ### Scenario 1: Current phase is reported **Acceptance criterion:** AC1 — Given a feature issue carrying at least one Phase Outcome, when the digest is requested, then it reports the feature's current phase as the `next_state` of the most recent Phase Outcome. 1. Note, by reading Issue A directly, which Phase Outcome is the most recent and what its `next_state` says. 2. Request the digest for Issue A. 3. Verify: the digest names a current phase, and it is the value you noted in step 1 — not the phase that outcome reports as completed, and not the `next_state` of any earlier outcome. **Expected outcome:** A reader learns where the feature is now from the digest alone, without opening the issue. ### Scenario 2: A superseded deliverable is not presented as current **Acceptance criterion:** AC2 — only the most recent value of a deliverable kind is presented as current, and the superseded one is not. 1. Note the two values Issue A carries for the twice-posted deliverable kind, and which was posted later. 2. Request the digest for Issue A. 3. Verify: the later value appears as that kind's current value. 4. Verify: the earlier value does not appear anywhere the digest presents as current state. **Expected outcome:** The digest shows one current value per deliverable kind, and it is the newest. ### Scenario 3: Open decisions are listed with their IDs **Acceptance criterion:** AC3 — every decision with no resolution is listed as open together with its decision ID. 1. Note the ID of Issue A's unresolved decision. 2. Request the digest for Issue A. 3. Verify: that decision appears in a list of open decisions. 4. Verify: its decision ID is shown, in a form you could quote back when acting on it. **Expected outcome:** The reader can act on an open decision straight from the digest, without searching the thread for its ID. ### Scenario 4: A resolved decision shows its chosen option and leaves the open list **Acceptance criterion:** AC4 — a resolved decision is reported as resolved with the option that was chosen, and does not appear in the open list. 1. Note Issue A's resolved decision and which option was chosen. 2. Request the digest for Issue A. 3. Verify: that decision is reported as resolved, and the option shown is the one that was chosen. 4. Verify: it does **not** appear in the open-decision list. **Expected outcome:** Open and settled decisions are unambiguously separated. ### Scenario 5: The two renderings agree in full **Acceptance criterion:** AC5 — both renderings, produced from a single invocation for one issue, report the same state in full; any difference other than presentation format is a failure. 1. Request both renderings for Issue A from a single invocation. 2. Compare them item by item on: the current phase; the set of current deliverables and their values; the set of open decisions and their IDs; the set of resolved decisions and their chosen options; and any reported anomalies. 3. Verify: every one of those matches. The only differences are how the information is laid out. **Expected outcome:** A human reading the digest and a consumer reading the machine form reach identical conclusions about what is current. ### Scenario 6: A feature that has not started a phase **Acceptance criterion:** AC6 (first half) — an issue with no Phase Outcome reports that the feature has not started a phase. 1. Request the digest for an issue carrying no Phase Outcome (Issue C, or Issue B with its single outcome removed). 2. Verify: the digest states the feature has not started a phase. 3. Verify: it does not fail, and it does not show a blank or unknown phase that a reader could mistake for a real one. **Expected outcome:** "Not started" is reported as a real state, not as an error or a gap. ### Scenario 7: A wholly empty issue shows empty sections, not missing ones **Acceptance criterion:** AC6 (second half) — for an issue carrying none of the three reported record types, every reported section is still present and explicitly shown as empty. 1. Request the digest for Issue C. 2. Verify: sections for phase, deliverables and decisions are all present. 3. Verify: each is explicitly marked as empty — a reader can tell "there are none" apart from "this was not reported". **Expected outcome:** Emptiness is stated, never implied by omission. ### Scenario 8: A nonexistent issue **Acceptance criterion:** AC7 — the view reports that the issue was not found and produces no digest. 1. Request the digest for an issue number that does not exist on the project. 2. Verify: the view reports that the issue was not found. 3. Verify: no digest content is produced — no phase, no deliverables, no decisions, empty or otherwise. **Expected outcome:** A wrong issue number is unmistakable and produces nothing that could be read as a real digest. ### Scenario 9: A read failure is distinguished from "not found" **Acceptance criterion:** AC8 — the view reports a read failure distinctly from "issue not found". 1. Make the forge unreachable. 2. Request the digest for Issue A — an issue you know exists. 3. Verify: the view reports that it could not read the issue. 4. Verify: the wording or signal differs from Scenario 8's "not found" — a reader (and a programmatic consumer) can tell "this issue does not exist" from "I could not reach the forge". 5. Restore the connection and repeat for the machine rendering. 6. Verify: the machine rendering signals the same failure rather than returning a digest. **Expected outcome:** The two failure causes are never conflated — one means the issue is wrong, the other means the environment is. ### Scenario 10: Access denied **Acceptance criterion:** AC8 — read failure covers access denial as well as unreachability. 1. Present credentials that cannot read Issue A. 2. Request the digest for Issue A. 3. Verify: the view reports a read failure, not "issue not found" and not an empty digest. **Expected outcome:** An issue you are not allowed to read never masquerades as an issue with no records. ### Scenario 11: A partial read is never presented as complete **Acceptance criterion:** AC8 — the view never presents a partial digest as if it were complete. 1. Interrupt the connection part-way through a request for Issue A, so some records have been read and others have not. 2. Verify: the view either reports a read failure, or presents its output explicitly marked as incomplete. 3. Verify: it does not emit a normal-looking digest that silently omits the records it never read. **Expected outcome:** An incomplete answer is always labelled as one — the reader is never given a short digest they would take for the whole picture. ### Scenario 12: An unparseable record is surfaced **Acceptance criterion:** AC9 — a record that cannot be parsed is reported as an anomaly rather than silently omitted. 1. Request the digest for Issue D. 2. Verify: the digest reports an anomaly identifying that there is a record it could not understand, and points to it well enough to go find it. 3. Verify: the rest of the digest still reports the records it could read. **Expected outcome:** A corrupt record is visible in the very view whose job is "what is current". ### Scenario 13: A resolution naming an unknown decision is surfaced **Acceptance criterion:** AC9 — a resolution naming a decision ID that was never raised is reported as an anomaly. 1. Request the digest for Issue E. 2. Verify: the digest reports an anomaly naming the dangling resolution and the decision ID it refers to. 3. Verify: the dangling resolution does not silently create a decision entry, and does not silently disappear. **Expected outcome:** A record that cannot be attached to anything is reported, not dropped. ### Scenario 14: The view changes nothing **Acceptance criterion:** AC10 — after requesting the digest, no comment, label, or body content on the issue has been added or changed. 1. Record Issue A's full state: its body, its comments, and its labels. 2. Request the digest for Issue A, in both renderings, and repeat several times. 3. Compare Issue A's body, comments and labels against what you recorded. 4. Verify: nothing was added, removed or modified. **Expected outcome:** The view is safe to run at any point in a feature's life, including mid-run. ## Traceability **Forward** — every acceptance criterion has at least one scenario: | AC | Scenarios | |---|---| | AC1 | 1 | | AC2 | 2 | | AC3 | 3 | | AC4 | 4 | | AC5 | 5 | | AC6 | 6, 7 | | AC7 | 8 | | AC8 | 9, 10, 11 | | AC9 | 12, 13 | | AC10 | 14 | **Backward** — every scenario names its parent criterion above; there are no orphans. ## Notes - Scenarios 9, 10 and 11 need the forge manipulated (unreachable, denied, interrupted). They are requirement-derived, not design-derived: AC8 states the behaviour, and how it is exercised is for `/dev:technical-plan` to lane. - The invocation surface — how the digest and the machine rendering are asked for — is deliberately not named. The PREQ does not decide it; naming it here would be testing a guessed design. - Scenario numbers are referenced by downstream findings. Keep existing numbers stable and append only.
Author
Owner
{
  "next_state": "planning",
  "produced": [
    {
      "kind": "preq",
      "ref": "issue-body",
      "summary": "PREQ for issue-digest-view (UAT scratch, Scenario 4)"
    },
    {
      "kind": "test-plan",
      "ref": "comment:1055",
      "summary": "14 validation cases covering 10/10 acceptance criteria"
    }
  ],
  "findings": [
    {
      "category": "out-of-scope",
      "summary": "Mutating anything on the issue",
      "reasoning": "The view is strictly read-only by design; a digest that can write is a different feature with a different risk profile.",
      "id": "F-PO-53-1-1"
    },
    {
      "category": "in-scope-deferrable",
      "summary": "Wiring an existing consumer (decisions-settled gate, /dev:resolve discovery) onto the new resolver",
      "reasoning": "Known follow-up. The Full scope option was declined so new code stays out of the pipeline gates; the panel confirmed this leaves the machine rendering unadopted, and the PREQ now says availability is the deliverable.",
      "id": "F-PO-53-1-2"
    },
    {
      "category": "out-of-scope",
      "summary": "Digesting more than one issue at a time (roll-up, board, queue view)",
      "reasoning": "The stated problem is reading one feature issue; multi-issue views are a separate problem with separate users.",
      "id": "F-PO-53-1-3"
    },
    {
      "category": "out-of-scope",
      "summary": "Redefining resolution semantics",
      "reasoning": "forge-contract §9 already defines supersession and is authoritative on conflict; a second definition would fork the contract.",
      "id": "F-PO-53-1-4"
    },
    {
      "category": "out-of-scope",
      "summary": "Reporting record types beyond phase, deliverables and decisions",
      "reasoning": "Enumerated at the panel's request so the user story stops promising more than the criteria deliver.",
      "id": "F-PO-53-1-5"
    }
  ],
  "pending_decisions": []
}
<!-- phase-outcome:v1 id=PO-53-1 skill=requirements --> ```json { "next_state": "planning", "produced": [ { "kind": "preq", "ref": "issue-body", "summary": "PREQ for issue-digest-view (UAT scratch, Scenario 4)" }, { "kind": "test-plan", "ref": "comment:1055", "summary": "14 validation cases covering 10/10 acceptance criteria" } ], "findings": [ { "category": "out-of-scope", "summary": "Mutating anything on the issue", "reasoning": "The view is strictly read-only by design; a digest that can write is a different feature with a different risk profile.", "id": "F-PO-53-1-1" }, { "category": "in-scope-deferrable", "summary": "Wiring an existing consumer (decisions-settled gate, /dev:resolve discovery) onto the new resolver", "reasoning": "Known follow-up. The Full scope option was declined so new code stays out of the pipeline gates; the panel confirmed this leaves the machine rendering unadopted, and the PREQ now says availability is the deliverable.", "id": "F-PO-53-1-2" }, { "category": "out-of-scope", "summary": "Digesting more than one issue at a time (roll-up, board, queue view)", "reasoning": "The stated problem is reading one feature issue; multi-issue views are a separate problem with separate users.", "id": "F-PO-53-1-3" }, { "category": "out-of-scope", "summary": "Redefining resolution semantics", "reasoning": "forge-contract §9 already defines supersession and is authoritative on conflict; a second definition would fork the contract.", "id": "F-PO-53-1-4" }, { "category": "out-of-scope", "summary": "Reporting record types beyond phase, deliverables and decisions", "reasoning": "Enumerated at the panel's request so the user story stops promising more than the criteria deliver.", "id": "F-PO-53-1-5" } ], "pending_decisions": [] } ```
Sign in to join this conversation.
No description provided.