Portfolixir carries two structures that both claim to organise the work, and has done since June:
epics.md E1–E19 — nineteen epics with an Epic List, Epic Detail
sections and, for four of them, ##### Story rows. It also carries the
Requirements Inventory (FR/NFR/UX-DR) and the FR Coverage Map.#416 (data), #417 (portfolio structure),
#418 (analytics), #419 (LLM/MCP), #420 (engineering quality), #470
(transactions/imports UX), #356 (UX and accessibility), with #321 as a
roadmap index and #320/#340 as parking lots.The tension has been recorded as a finding at every reconciliation since 2026-07-25, most recently as F2 (2026-08-12) and F7 (2026-08-17), each time noting that the structural decision is the owner’s and still open. Recording it five times has not resolved it, and the drift is no longer theoretical.
epics.md breaks down 19 stories across 4 of its 19 epics. E19 has 7,
E6 has 5, E17 has 4, E18 has 3. Fifteen epics have none. Five epics
marked in-progress have zero stories, which sprint_plan.py status
reports as five separate risks.#700 reports parent: #417, #701–#704 and #707
report #356, #705 reports #419, #706 reports #420. This is
evidence about where the agent files data, not about authority — see
“Who reads what”, which is the correction that produced this ADR’s second
version.sprint_plan.py validate returns valid: false with five unrecognized keys
(6-dx-1-… through 6-c-1-…): the E6 batch used a story-key shape the
generator cannot parse. The file has been invalid since that batch and no
gate caught it.sprint_plan.py status recommends building
19-7-forward-projection-and-tax-bucket — the one story deliberately
deferred behind its own decision gate. It is not a bug in the script; it is
the correct answer to a question asked of a document that no longer
describes the work.sprint-plan-*.md lane documents, which no ADR describes and no gate
checks. The artifact that actually governs execution is the one with no
recorded status.The drift is therefore not a tidiness problem. A planning document that answers “what should I build next” with a gated story, and a tracking file that fails its own validator, are load-bearing artifacts giving wrong answers — and this project’s gates are load-bearing precisely because the owner does not read code.
The first version of this decision argued that the tracker set should own the work breakdown because the work is already there. The owner’s response (2026-08-17) disposed of that argument in one sentence: “I don’t look in there.”
That is not a preference to be accommodated, it is a fact that changes what the evidence above means. Parentage being live in the API says where an agent files things. It says nothing about authority, and the first version treated the two as the same claim.
The consequence is a process defect, not a labelling problem. ADR-0038’s feedback loop ends with “thin issues after owner confirmation” — issues being the terminal artifact of a loop whose point is to inform the owner, delivered into a channel the owner does not read. Four triage rounds have now run through it. Filing an issue is an act of agent bookkeeping and must stop being counted as an act of owner communication.
So the readership, stated plainly, because the rest of this decision follows from it:
| Reader | Reads |
|---|---|
| the owner | ADRs (decisions needing sign-off); the sprint lane plan (what a batch will do); the reviewer briefing on the PR (what a batch did) |
| the agent | everything, and the tracker set as its work ledger |
| third parties | the public issue tracker — the only channel that can catch them |
Sprint 7 cannot be planned cleanly on top of it. Every one of the thirteen
candidate issues is a GitHub issue with no epics.md story row, so generating
tracking would add nothing and leave the same wrong recommendation standing.
The choice was going to be forced by the next batch regardless.
A — Dissolve epics.md E1–E19 into the tracker set. Delete the Epic List
and Epic Detail; the trackers become the only structure. Rejected: it throws
away the Requirements Inventory and FR Coverage Map, which are the parts that
demonstrably work — the FR map is what every reconciliation actually reads, and
it is where the two-way coverage rule and the scope ladder are enforced.
Deleting the epic sections is right; deleting the document is not.
A2 — Abolish issues for internal work; keep them only for external reports. Raised by the owner on the strength of not reading them. Rejected, but it supplies §2’s reasoning: the owner is right that issues are not an owner artifact, and wrong that this makes them disposable. Removing them costs the closing-keyword mechanism and the cross-reference surface while saving the owner nothing, since the saving would be in a channel they already ignore. The half of the proposal that survives — issues are the external intake channel — is adopted as one of the three reasons to keep them.
B — Dissolve the trackers into epics.md. Give all 40 open issues story
rows. Rejected: it is large mechanical work whose output would immediately
re-drift, because issues are filed on GitHub and would have to be mirrored by
hand forever. It also inverts the issue convention: AGENTS.md says issues are
thin pointers and the ADR/epics document is authoritative for specs — not
that the document must restate the backlog.
C — Split the two jobs, and name the execution artifact. epics.md keeps
the requirement registry; the tracker set owns the work breakdown; the sprint
lane plan becomes a named, described artifact. Recommended — see below.
D — Keep both and keep recording the finding. Rejected: this is the status quo, and five recordings across seven weeks are sufficient evidence that it does not converge.
epics.md is the requirement registry, and stops being a work breakdownIt keeps — and remains authoritative for — the Requirements Inventory (FR/NFR/UX-DR), the FR Coverage Map, the scope ladder boundaries, and the dated Implementation Status reconciliations. These are the sections every review actually reads.
It loses the Epic Detail sections and the ##### Story rows. What is worth
keeping from them — each epic’s intent paragraph — is condensed into a short
tracker index that stays in epics.md, one line per epic: its name, its
tracker issue where one exists, and its intent in a sentence.
The first draft moved those paragraphs into the tracker issue bodies instead. The agentic review of 2026-08-17 killed that, on two counts:
AGENTS.md forbids it. “The authoritative spec lives in the ADR/epics
document, never in the issue body.” Moving epic intent into issues would
have made fifteen of nineteen epics’ only recorded intent live in the one
place the project declares non-authoritative — while §2 of this same ADR says
the thin-pointer convention is unchanged. Two sentences of one decision
contradicting each other.A tracker index inside the registry keeps the intent authoritative, gives the trackerless epics a home, and is still not a work breakdown — which is the thing this decision set out to remove.
A unit of work is an issue; its parent is a tracker. That is already true in
the data and merely stops being contradicted. The issue convention is
unchanged: thin pointers, with the spec in the ADR or in epics.md.
It is kept deliberately, and not because the owner reads it. Three things make it worth more than the in-repo alternative, none of which is owner-facing:
Closes #712 in a PR body closes the issue at the
merge, which is the mechanism AGENTS.md relies on. Replacing issues with a
file means closing by hand — strictly more bookkeeping, not less.What it is not: a way to inform the owner. Issue numbers are agent addresses. Where the owner needs to know a thing, it goes in an ADR, the lane plan, the triage document or the briefing — never cited as an issue number and left there.
External reports get a route, or the channel terminates nowhere. Keeping the tracker as the public intake channel while the owner does not read it would reproduce exactly the defect diagnosed above. So: a third-party report is triaged by the agent into the next triage document or the next lane plan’s candidates — artifacts the owner does read. Without that step, “external intake” is a reason to keep a mailbox nobody opens.
Requirement-to-work traceability lives in one place — the FR Coverage Map’s issue column, which already carries it.
Four, and the list is closed. The fourth was missing from this ADR’s second version, which closed the list at three while its own Consequences section described eight rounds of the owner using the fourth — the agentic review caught it:
The triage / analysis document — the artifact ADR-0038’s loop actually runs on. The owner reviews it and confirms or corrects routing; only then are issues filed. Naming it here is a correction to this ADR’s list, not an amendment to ADR-0038.
The still-unanswered Round 7 proposal (a gate-closure rule for ADR-0026) is the lever on the first of these, and is deliberately left to the owner.
sprint-plan-<date>-sprint<N>.md gains recorded status: lanes, the issues in
each, sequencing constraints, risk-tier markings, and the open questions the
batch must answer. It is what Sprints 3–6 already used; this only makes it
describable and reviewable.
sprint-status.yaml is retired as a story trackerThis is the honest cost of the decision and is stated rather than buried:
bmad-sprint-planning’s generate path stops being applicable to this
project, because it derives story rows from epics.md sections that will no
longer exist.
What replaces each thing it provided:
| Provided by the tracking file | Replacement |
|---|---|
| story status | GitHub issue state, verified against merge commits on main |
| epic status | tracker issue state |
| the close-out / reconciliation log | kept — this is the part with real value |
| next-action recommendation | the sprint lane plan |
| retrospective-completion ledger | kept in place — see below |
The file is therefore not deleted, and — corrected by the agentic review of
2026-08-17 — its development_status block is not deleted either. The
first draft of this ADR said it went, along with the five invalid keys. That
would have broken three things this decision has no intention of breaking:
validate would fail permanently, not pass. sprint_plan.py:619 lists
development_status among the required top-level keys, so removing it
trades five “unrecognized key” problems for one “missing required key” — and
this ADR cites validator output as evidence, so leaving the file permanently
invalid would undercut its own argument.cmd_status fails on an empty development_status before
reading anything else.epic-17-retrospective: done and its siblings live inside that block.
They are neither story rows nor epic rows, so no row of the table above
replaces them, and ADR-0026 step 5 makes the retrospective mandatory. Sprint
7’s own close-out would have been the first casualty.What actually goes: the ##### Story-derived rows — the five schema-invalid
6-dx-* / 6-c-1 keys and the story keys for E17/E18/E19. What stays: the
epic-N and epic-N-retrospective keys, both recognized by the script’s own
classify_key, both surviving validate. Neither is a story breakdown, which
is what this decision set out to remove.
#321 closesIts “working agreement” section is preserved first — the 2026-08-04
reconciliation requires only that it survive “somewhere”, and the origin note of
2026-07-31 offered AGENTS.md or the epics document as alternatives. Since
this decision deletes the epic sections, AGENTS.md is the surviving
destination; that is a consequence of this ADR, not a pre-existing condition, and
the first draft overstated it as one. #321 is then closed by hand with the
reason, not by a keyword — it is invalidated rather than implemented.
epic-N keys — it would not have under the
first draft.bmad-retrospective and bmad-story-automator read story rows. The first
draft flagged this as follow-up; the review showed the follow-up falls due
inside the migrating batch, since ADR-0026 step 5 makes Sprint 7’s own
retrospective mandatory and bmad-retrospective stops when epic detection
returns nothing. §4’s retention of the epic-N and epic-N-retrospective
keys is what keeps that working. Story-level detection still degrades, and
that is accepted: the epic is the unit these skills need here.docs/ carries dangling references once the epic sections go: ADR-0027
(E16), ADR-0028 (E17), ADR-0029 (E18, section H), ADR-0031 (E19) and
docs/development/pr-review-checklist.md all point into epics.md. ADRs are
the artifact class the owner actually reads, so the migration sweeps and
repoints them rather than leaving four Accepted decisions with broken
pointers.#708–
#712 derive from ADRs and may deserve them. That is a requirement-registry
question, decidable after this one and independent of it.