Skip to content

epic #185: Backlog Stubs Become GitHub Issues - #217

Merged
sameera merged 7 commits into
mainfrom
feat/backlog-stubs-as-issues
Aug 2, 2026
Merged

epic #185: Backlog Stubs Become GitHub Issues#217
sameera merged 7 commits into
mainfrom
feat/backlog-stubs-as-issues

Conversation

@sameera

@sameera sameera commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Implements the story sub-issues of #185, one commit per story in blocked_by order.

Each commit body carries its own Closes #<story> line, so merging this PR
into main closes the stories it implements. The epic itself closes through
/nxs.close, not by merge.

Draft opened by utils/implement-epic.sh; /nxs.analyze runs against it next.


Post-analyze follow-ups (2026-08-02)

/nxs.analyze reported 2 high, 1 medium, 1 low against c164dbf — no critical, no
invariant violation. All three of its AC divergences were record #192's own scope
edits reaching the code but not the issues. Resolved as follows.

HIGH — the manual still documented the retired file. A real defect, fixed in
9d42385: manual/assets.html slide 11, the asset table, the surface map and the
close-record slide now describe the backlog as a labelled issue query rather than
docs/features/<feature>/backlog.md. Closes the #189 AC5 / invariant 17 gap.

HIGH — #188 and #190 carried acceptance criteria the shipped design contradicts.
Planning-artifact gap, not a code defect; both issues amended in place rather than
closed, since both stories shipped:

  • A stub is planned by its own issue number, in place #188 retitled to "A stub is planned by its own issue number, in place" — the
    old title said closing the stub was the promotion, which invariant 4 forbids.
    AC4 now states the in-place contract (same issue populated, backlog label removed,
    nothing created, nothing closed); the not-planned close on an oversized stub is its
    own criterion (invariant 5); and the three slug-matching criteria collapse into one —
    any non-numeric input is a capability description (invariant 11).
  • The backlog is one cross-feature query, and triage excludes it #190 AC3 now points at the single features-index entry rather than a per-feature
    README, and a new criterion requires the negated filter on every epic-enumerating
    query, not only the default triage view.

Both carry a dated scope-edit note naming the record and its invariants, so the
divergence is legible rather than looking like drift.

MEDIUM — epic #185 success metric 3 still describes the closed-as-completed
lifecycle superseded by in-place promotion. Open; it is an epic-body edit, not a code
change. LOW#189's 22/12 counts vs the actual 24/13/3 — already corrected in the
record and explained in c164dbf.

Not repointed: .nexus/anchors/workspace-resolution.md still names the retired
stub-promotion glob. Anchors are regenerated by the distillation PR, and writing the
concept store on a feature branch is what /nxs.distill forbids. Recorded as a
decision stub in the queue scratch.

sameera and others added 7 commits August 1, 2026 18:59
Oversized scope now leaves GitHub issues rather than a committed
backlog.md. A stub is an epic identified but not yet planned: it carries
the repository's declared epic classification plus exactly one label
denoting the unplanned state (record invariants 1 and 2).

- delivery_config: resolve the unplanned label through the one shared
  chain (github.unplanned-label, default `backlog`); `label_exists` and
  the batch `ensure_labels` preflight.
- create_gh_issues: the canonical classification is a caller argument
  (--classification-label / --classification-type) defaulting to the
  story values, so /nxs.epic files stubs as epics through the same
  filer. Every label that will be applied is upserted before any issue
  is created; one that can be neither created nor found stops the run
  with nothing filed (invariants 3 and 19).
- /nxs.epic Phase 2b: write transient stub work-items and file them —
  parentless, ordering wired as native blocked_by, no project touched
  when none is configured, and no backlog.md written.

Promotion by issue number, the close-side writer, the migration and the
retirement of the files are the following stories.

Closes #186
…kpoint

/nxs.close no longer appends deferred scope to a committed backlog.md. It
authors transient stub work-items locally (Phase 5) and files them as open
issues in a new Phase 7.4 — the first step after the close checkpoint.

The phase position is forced from both sides: issue creation cannot be
undone, so it must follow consent; and the close record must name the
resulting issue numbers, so it must precede the Phase 7.6 commit that
pushes that record in --pr mode. Declining the checkpoint now leaves
GitHub untouched (record invariant 7).

- create_gh_issues: refuse, in the preflight, any work-item carrying the
  unplanned label together with a `parent:`. A stub filed beneath the epic
  being closed would deadlock the all-sub-issues-closed gate that stage
  hard-blocks on, and that gate deliberately has no exemptions by kind
  (invariant 6). The whole batch stops with nothing created.
- nxs.close: Phase 5 authors work-items and writes no backlog.md; the
  checkpoint discloses the filing as irreversible; Phase 7.4 files the
  batch and fills the numbers into the close record; the --pr commit,
  the close comment's durable pointers and the final report all name
  stub issues instead of a file path.
- close-record template: Deferred Scope carries issue numbers, not a
  backlog.md pointer.

Promotion by issue number, the cross-feature query and the migration are
the following stories.

Closes #187
Promotion is now "plan this epic", addressed by the stub's issue number.
The record's scope edit stands: closing the stub is not the promotion —
`/nxs.epic <n>` populates that same issue with the epic body, the
planning meta block and the epic classification, and takes the unplanned
label off. Nothing is created and nothing is closed, so the number the
scope was deferred under is the number it ships and closes under, and
every dependency edge and body mention written at decomposition stays
valid (invariant 4).

The flag selects the operation and the shape of the argument never does:
a bare number always means "plan this epic", `--from #<n>` always means
"load this already-planned epic". Slug lookup is retired with the file it
globbed — a stub's issue number is its only identifier.

- nxs_gh_create_epic: `--promote <n>` populates in place via `gh issue
  edit`. Legality is re-checked in the filer before any write — a target
  that no longer carries the unplanned label, or a number that does not
  resolve, is refused with nothing written, and the two are told apart
  (invariants 12/13).
- epic-resolve: an unplanned epic is refused by name, `epic-not-planned`,
  on every path — `--require-epic` or not. Resolving one would emit an
  epic with an empty story set, which downstream reads as "plans
  nothing" rather than "nobody has planned this" (invariant 14). The
  label comes from the shared publishing resolver, never hard-coded
  (invariant 18).
- /nxs.epic: promotion mode reads issue state only and never globs the
  docs tree; the feature container comes from the stub's meta block and
  is created on demand. A promoted stub that proves oversized is
  re-decomposed and closed as not planned, never as completed.

The migration and the cross-feature query are the remaining stories.

Closes #188
The pin recorded c51f750012af… while a fresh build hashes bddc67f6f416…
— stale since this epic started editing `.claude/`, and never re-pinned
by the story commits. Regenerated via the named remedy (pnpm
nexus:vendor-tools; pin updated in place, no artifact copied).

The old value was also machine-local. `listComponentFiles` walks the
managed subtrees with no exclusions, so the 17 gitignored
`__pycache__/*.pyc` files that the skills' python tests leave behind
were being hashed into the manifest: c51f750012af… and the fc01f39589…
this first regenerated to are both pins of a tree that no clean checkout
has. The value committed here is hashed with those directories removed,
so it is the one a fresh clone reproduces.

That fragility is not fixed here — it is outside this epic, and running
the skills' python tests before `nexus:vendor-tools` will re-break the
pin the same way until the walk skips `__pycache__`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ludes it

With one label and the feature held in the issue body, the whole backlog
across every feature is open issues carrying the unplanned label — no file
glob and no hand-maintained table — and removing it from any view costs one
negated filter.

The query is asked for, not spelled out: `delivery_config.py backlog-query`
resolves the label through the one shared chain and emits it in the three
shapes it is needed in — a `gh issue list` (targeted at wherever epics are
filed, since a stub is an epic), the `is:issue is:open label:<l>` fragment a
link carries, and the `-label:<l>` negation (invariant 18). A repository that
renames the label renames its queries with it.

- features index: `docs/features/README.md` is created and carries the
  backlog link — once, in one place. Per-feature nav indexes gain no backlog
  section: with the feature in the body, a per-feature view is a text search
  over issue bodies, and ten links that all mean the same thing.
- every epic query filters stubs out. A stub is an epic issue, so any query
  enumerating epics for planned work carries the negation — stated where
  /nxs.epic describes what it does, with the exclude form to hand. That is
  the accepted price of a stub keeping its number through promotion.
- stage reports: /nxs.epic's decomposition report and /nxs.close's final
  report both name the cross-feature query beside the numbers they just
  filed.
- sequencing.md: one line at its head names the query as the authoritative
  inventory. Its wave ordering and rationale are untouched — deciding that
  page's fate is out of scope.

The migration and the retirement of the committed backlogs are what remains.

Closes #190
The seven per-feature backlog.md files are gone. Every block they carried
as `proposed` is now an open `backlog`-labelled epic issue (#193#216),
filed in one batch through the existing filer, with the dependency graph
preserved.

Counts, against what planning assumed: **24** proposed blocks, not 22 —
two were appended to the PR-Driven backlog on 2026-07-30, after the epic
was sized. 13 promoted and 3 superseded blocks were not refiled
(invariant 15); git history is their provenance and refiling them would
add noise to the query this epic exists to make useful.

The dependency graph needed judgement, as the record said it would. Five
edges pointed out of the batch at work promoted under the old model and
are now literals — #38 (workspace manifest) ×2, #54 (multi-repo distill),
#139 (record sub-issue). One was stale: story-analyze-hub was blocked by
`hub-born-queue`, abandoned before implementation, and now points at the
epic that superseded it, #114. The rewrite is recorded in that issue's
body, not just in this message.

- create_gh_issues: a `blocked_by` entry may be a literal `#<n>`,
  resolved against the platform (the migration affordance). Only the
  sigil form — a bare number is indistinguishable from a batch ref, and
  an unresolvable literal fails the reference closed rather than dropping
  an ordering. Its `--dry-run` also stopped working when #186 made the
  classification a caller argument; it rendered `story` on a stub batch,
  which is precisely the rehearsal 24 irreversible creations needed.
- delivery_config: `resolve epic-label` returned empty where the library
  returns `epic`, because the CLI's generic path does not know the
  built-in. /nxs.epic Phase 2b hands that value to the filer, so stubs
  would have filed unclassified.
- multi-paragraph rationale carried over intact — the ten prose-heavy
  multi-repo entries, and the dated notes on the analyze/close chain.
- references repointed ahead of the deletion: sequencing.md names issue
  numbers beside the slugs it orders, /nxs.epic no longer describes the
  feature container as holding a backlog file, and the --pr acceptance
  harness seeds none into its throwaway repo.

Left alone deliberately: `libs/origin/v2/.nexus/decisions/`. Those
numbered logs are the record of decisions as they were made — including
the one that created backlog.md — and are superseded by record #192.
Rewriting them to match a later decision would falsify the trail.

The empty prime-workspace-instrumentation container went with its file,
per the record; it is recreated at that feature's first epic filing.

Closes #189
`/nxs.analyze` on #185 found the last committed references to
`docs/features/<feature>/backlog.md` still standing in `manual/`, which is
a live surface, not the frozen v2 archive. Invariant 17 puts the deletion
after every committed reference has been repointed, so this closes the gap
c164dbf left — #189 AC5.

Slide 11 is the substantive one. It described an append-only file with a
`proposed -> promoted` status field; it now describes what shipped — an
open epic issue carrying the single `backlog` label, planned in place by
`/nxs.epic <issue-number>`. Its "why" bullets gained the two properties
the file never had: the whole backlog is one query across every feature,
and the issue number survives promotion, so every dependency edge written
when the scope was deferred stays valid. Status became issue state.

Four smaller repoints: the asset table's "Feature backlog" row is now a
"Backlog stub" living at `label:backlog` rather than a path; the surface
map no longer lists backlogs under `docs/`, because that surface no longer
holds one; and the close-record slide plus its summary card say deferred
scope is filed as stub issues after the checkpoint.

`.nexus/anchors/workspace-resolution.md` still names the retired glob and
is left alone — anchors are regenerated by the distillation PR, and
writing the concept store on a feature branch is what /nxs.distill forbids.
Recorded in the queue scratch so close reads it as a decision, not a miss.

Story issues #188 and #190 were amended on the platform in the same pass:
record #192 edited their scope after they were filed, and three acceptance
criteria contradicted the shipped design. #188 said closing the stub was
the promotion — invariant 4 forbids exactly that — and #188/#190 carried
slug-matching and per-feature-README criteria the record retired. The code
follows the record; it was the issue text that was stale.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@sameera

sameera commented Aug 2, 2026

Copy link
Copy Markdown
Owner Author
Conformance: Backlog Stubs Become GitHub Issues (.nexus/tmp/epic-185)  ·  epic #185
Mode: full (record #192 @ 55493c77228b32ef5e33fdcbb5f03535c3d71b31d90245ba0215ece30a6b011e)
Surface: 35 files changed, 5 stories (0 closed / 5 open — PR #217 open, each commit carries Closes #<story>)

Per-story AC conformance:
  STORY #186 Decomposition stubs are filed as backlog issues: 6/6 met · 0 partial · 0 unmet · 0 contradicted
  STORY #187 Deferred scope at close becomes stub issues:     5/5 met · 0 partial · 0 unmet · 0 contradicted
  STORY #188 A stub is planned by its own issue number:       7/7 met · 0 partial · 0 unmet · 0 contradicted
  STORY #189 The committed backlogs are migrated:             5/5 met · 0 partial · 0 unmet · 0 contradicted
  STORY #190 The backlog is one cross-feature query:          5/5 met · 0 partial · 0 unmet · 0 contradicted

  Supersedes the 2026-08-01 receipt @ c164dbf, which recorded 3 AC divergences on #188/#190. Those
  were record #192's own scope edits reaching the code but not the issue text. Both issues have since
  been amended in place (#188 also retitled), so the resolver now materializes AC text the build
  satisfies. No code changed to close them — the code already followed the approved record.

Invariant violations:   none. Invariants 1–19 checked against the diff.
                        inv.1/2 verified live: 24 open stubs, every one carrying exactly `epic,backlog`.
                        inv.3/19 (ensure_labels upserts every declared label pre-creation, exits 1
                        naming the gap before any issue is created), inv.4 (populate_github_issue
                        edits in place — `issue edit --remove-label`; nothing created, nothing closed),
                        inv.5 (oversized promoted stub → comment naming successors + close
                        `--reason "not planned"`, nxs.epic.md:129-133), inv.6 verified live (epic #185's
                        sub-issue set is 5 stories + record #192; no stub present), inv.7 (Phase 2b
                        behind the right-size gate, Phase 7.4 after the checkpoint), inv.8 (reuses the
                        resume ledger), inv.9 (project_mode "none" → no lookup), inv.10/11/12/13
                        (promotion reads issue state only; legality refused pre-write naming `--from`),
                        inv.14 verified live (resolver on #216 exits `epic-not-planned` with the
                        diagnostic, not a missing-meta-block failure), inv.15/16 (24 proposed migrated,
                        13 promoted + 3 superseded not refiled; dates and full rationale preserved),
                        inv.17 (deletion lands last; the manual/assets.html exception is now closed —
                        see below), inv.18 (every label/classification/project/repo read through
                        delivery_config.py; the three query forms resolve through it).

Success metrics:
  1. Zero backlog.md under features/; every proposed stub an open backlog issue
     → measurable, MET (find returns nothing; 24 open `backlog` issues == 24 proposed blocks at base)
  2. Whole cross-feature backlog in one query
     → measurable, MET (`backlog-query --form list` → `gh issue list --state open --label backlog`)
  3. Lifecycle derivable from issue state alone — open / closed-completed / closed-not-planned
     → measurable, NOT MET AS WORDED — superseded by record #192 (medium finding below)
  4. /nxs.close creates no stub issue before its checkpoint
     → measurable, MET (Phase 7.4 is the first post-checkpoint step)
  5. Filing succeeds with no Project and no pre-existing backlog label
     → measurable, MET (label upsert + project_mode "none"; exercised by the 24-issue migration)
  6. Excluding stubs costs exactly one negated filter
     → measurable, MET (`backlog-query --form exclude` → `-label:backlog`)

Findings:
  MEDIUM   Success metric 3 is superseded and not met as worded. The epic body still reads
           "open, closed-as-completed, closed-as-not-planned". Under in-place promotion a promoted
           stub stays OPEN with the label removed, and closed-as-completed never occurs for a stub —
           only closed-as-not-planned, when it proves oversized (invariants 4 and 5). The stories
           were amended for this; the epic body was not. Measurable, but it describes a lifecycle
           the build deliberately does not build. Carried unchanged from the previous receipt.
  LOW      .nexus/anchors/workspace-resolution.md:23 still says /nxs.epic "records it in the queue
           entry, and searches the stub-promotion glob across backlogs under the resolved root" —
           both halves retired (by #114 and by invariant 10/11 respectively). Not counted against
           #189 AC5 or invariant 17: the file carries its own "DERIVED — regenerated by /nxs.distill
           on every drain touching this concept. Never hand-edit; stale anchors are rebuilt, not
           fixed" header, and /nxs.distill R1 owns the refresh. Named so the drain confirms this
           concept is in the touched set; the engineer's rationale is in the queue scratch.
  LOW      #189's ACs quote 22 proposed / 12 promoted; the tree at the base carried 24 / 13 / 3. The
           record already corrected 12→13; the 22→24 delta is two blocks appended after planning and
           is recorded in the engineer scratch. All 24 migrated; no promoted/superseded block refiled.

Resolved since the previous receipt (both were HIGH @ c164dbf):
  ✅ manual/assets.html no longer documents the retired backlog file. Fixed in 9d42385: slide 11 now
     describes an open epic issue carrying the `backlog` label and planned in place; its path line is
     the query, not `backlog.md`; the asset table row is "Backlog stub · label:backlog · open until
     planned in place"; the surface map no longer lists backlogs under docs/; the close-record slide
     and its summary card say deferred scope is filed as stub issues after the checkpoint. A git-grep
     sweep of the committed tree now returns no reference to a deleted backlog.md outside the frozen
     libs/origin/ archive and three prohibitions that forbid writing one. #189 AC5 and invariant 17
     are clean.
  ✅ #188 and #190 amended to match the approved record. #188 retitled ("…is promoted by issue number,
     and closing it is the promotion" → "A stub is planned by its own issue number, in place"); AC4
     now states the in-place contract; the not-planned close is its own criterion; the three
     slug-matching criteria collapse into one (any non-numeric input is intent). #190 AC3 points at
     the single features-index entry; a new criterion requires the negated filter on every
     epic-enumerating query. Both carry a dated scope-edit note naming record #192 and its invariants.

Scope drift (informational, none breaks an invariant):
  · resolve_literal_ref — `#<n>` dependency references resolved against the platform. No story AC asks
    for it; authorized by the record's literal-reference decision (migration affordance).
  · ensure_labels upserts EVERY frontmatter-declared label, not just the classification label, so
    existing story batches now also upsert their area labels. Broader than #186 AC2; supported by
    invariant 3.
  · --classification-label / --classification-type on the shared filer — record decision; no story AC
    states it. Default preserves today's story behavior.
  · docs/delivery/sequencing.md gained issue numbers throughout its wave tables, beyond the record's
    "one line at the head of the table". Its ordering and rationale are untouched, so the epic's
    out-of-scope clause holds.
  · libs/origin/v2/.nexus/decisions/* still name backlog.md — deliberately left, per the engineer's
    stub and nxs.distill.md's "never written" rule for that frozen archive. Not counted against #189 AC5.
  · pr-acceptance provision.ts no longer seeds a backlog.md into the throwaway repo.

Severity: ⛔ critical 0 · ⚠️ high 0 · medium 1 · low 2
epic: "#185"
pr: 217
date: 2026-08-02
head: 9d42385a3585858bf599987598a214d4daa37968
mode: full
record: "#192"
record_hash: 55493c77228b32ef5e33fdcbb5f03535c3d71b31d90245ba0215ece30a6b011e
findings: { critical: 0, high: 0, medium: 1, low: 2 }

@sameera

sameera commented Aug 2, 2026

Copy link
Copy Markdown
Owner Author
Conformance: Backlog Stubs Become GitHub Issues (.nexus/tmp/epic-185)  ·  epic #185
Mode: full (record #192 @ 55493c77228b32ef5e33fdcbb5f03535c3d71b31d90245ba0215ece30a6b011e)
Surface: 35 files changed, 5 stories (0 closed / 5 open — each commit carries a `Closes #<story>` trailer; they close on merge, which is correct for a pre-merge analyze)

Per-story AC conformance:
  #186 Decomposition stubs are filed as backlog issues: 6/6 met · 0 partial · 0 unmet · 0 contradicted
  #187 Deferred scope at close becomes stub issues, filed after the checkpoint: 5/5 met · 0 partial · 0 unmet · 0 contradicted
  #188 A stub is planned by its own issue number, in place: 7/7 met · 0 partial · 0 unmet · 0 contradicted
  #189 The committed backlogs are migrated and the files retired: 4/5 met · 1 partial · 0 unmet · 0 contradicted
  #190 The backlog is one cross-feature query, and triage excludes it: 5/5 met · 0 partial · 0 unmet · 0 contradicted

Invariant violations:   none — all 19 hold. Verified live where the platform is the evidence:
                        #193–#216 each carry exactly `epic` + `backlog` (1, 2); none has a parent (6);
                        the four literal edges (#38 ×2, #54, #139) and the rewritten stale edge
                        (#211 → #114) are wired (per the migration affordance); no project item (9);
                        no slug recorded in any stub body (11). Invariant 17 is satisfied at head,
                        not per commit — the manual repoint landed in 9d42385, one commit after the
                        deletion in c164dbf; the PR merges as one change set, so the ordering defect
                        does not survive the merge. Two prose residuals remain (medium, below).

Success metrics:         1. Zero backlog.md / every proposed stub filed → measurable (`find` + query), moved: 0 files remain, 24/24 filed.
                         2. Backlog is one query → measurable, moved: `is:issue is:open label:backlog` returns 24 and nothing else.
                         3. Lifecycle from issue state alone → measurable, moved: the epic body's metric was itself corrected to the in-place lifecycle; the code implements it.
                         4. /nxs.close creates no stub before checkpoint → measurable (phase order), moved: authoring is Phase 5, filing is Phase 7.4, first step after consent.
                         5. Files with no project and no pre-existing label → measurable, moved: `ensure_labels` upserts before any create and fails closed; `project: none` touches nothing.
                         6. Exclusion costs one negated filter → measurable, moved: `backlog-query --form exclude` → `-label:backlog`.

Scope drift:             • cb59869 re-pins the `claude-components` bundle fingerprint. No story asked
                           for it — that work is backlog stub #198. It is also inert as landed: two
                           later commits (d8fd18a, c164dbf) changed `.claude/`, so the pin is stale
                           again at head (fresh `be1a0735…` vs pinned `e038bd3f…`). Not a regression
                           — base was already stale (`5278df8f…` vs `c51f7500…`) — but the commit
                           buys nothing and `parity.spec.ts` still fails.
                         • The filer's guard against a parented stub (`create_gh_issues.py`, whole
                           batch refused before any create) goes beyond #187's ACs, which only
                           require that no stub *appears* in the sub-issue set. Enforcing invariant 6
                           at the writer rather than promising it in the command doc is a strict
                           improvement; noted, not a concern.
                         • 24 stubs migrated where the ACs say 22 — over-delivery (two blocks were
                           appended to the PR-Driven backlog on 2026-07-30, after sizing). See LOW.

Severity: ⛔ critical 0 · ⚠️ high 0 · medium 1 · low 3

MEDIUM — two committed documents still point at the retired backlog by slug (#189 AC5, invariants 17 + 11)

9d42385 swept manual/, which was the substantive gap. Two prose references survive:

Both name a stub by a slug that nothing resolves any more — invariant 11 made the issue number a
stub's only identifier and /nxs.epic no longer does slug lookup at all (#188 AC6), so a reader
following either pointer lands nowhere. Fix is two edits: swap each slug for its issue number.

LOW — .nexus/anchors/workspace-resolution.md:23 still describes the retired glob

The line reads "…searches the stub-promotion glob across backlogs under the resolved root," which
67a90b5 replaced with issue-state resolution. Left deliberately, and the reasoning is sound and
recorded in the queue scratch: anchors are derived state, /nxs.distill regenerates them and its own
rule is "never hand-edit; stale anchors are rebuilt, not fixed," and writing the concept store on a
feature branch is forbidden. The caveat worth naming: distill's R1 refresh covers only concept pages
the distillation PR touches, so this self-heals only if workspace-resolution is among them.
Worth confirming at the drain rather than assuming.

LOW — #189's AC counts are stale against what shipped

AC1 says 22 proposed blocks, AC2 says 12 promoted. What shipped: 24 proposed (two appended after
the epic was sized), 13 promoted, 3 superseded. Record #192 corrected 12 → 13; nothing corrected
22 → 24. Over-delivery with no code impact — the ACs' intent (every proposed block filed, no
promoted or superseded block refiled) is met exactly. Planning-artifact drift only.

LOW — the bundle re-pin in cb59869 does not hold at head

See scope drift above. Either move the re-pin to the tip of the branch or drop it and leave the work
to #198, which owns it. As landed the commit is a no-op that reads like the pin was fixed.

epic: "#185"
pr: 217
date: 2026-08-02
head: 9d42385a3585858bf599987598a214d4daa37968
mode: full
record: "#192"
record_hash: 55493c77228b32ef5e33fdcbb5f03535c3d71b31d90245ba0215ece30a6b011e
findings: { critical: 0, high: 0, medium: 1, low: 3 }

@sameera
sameera marked this pull request as ready for review August 2, 2026 12:08
@sameera
sameera merged commit c927afa into main Aug 2, 2026
@sameera
sameera deleted the feat/backlog-stubs-as-issues branch August 2, 2026 12:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant