-
Notifications
You must be signed in to change notification settings - Fork 0
Plan artifact pages
Current — the latest status report. Reports freeze once published; corrections appear in later reports.
The IA & content model epic (docs/plans/2026-07-22-ia-content-model.md, epic
#93, 8/9 done) gave wiki documents a stable wiki_key, truth_state,
sidecar metadata, and a typed-edge traceability graph — but only for docs
(plans/roadmap/status/design/adr/guide). Work items, PRs, and releases exist
only as bare stub nodes in the graph (pr/<num>, release/<tag>,
item/<ULID>) with no title, no dedicated page, and no attributes beyond
doc_type. docs/.index/rendered/releases.md and traceability.md are flat
shared indexes, not per-entity pages. The user (Rick) supplied a full PRD:
every ticket/PR/release should get its own generated page — reusing the same
wiki_key/truth_state/graph machinery — showing hierarchy, related artifacts,
and traceability in one place, so nobody has to hunt through indexes or logs.
This is a direct, sanctioned extension point, not new territory: bin/ia.py:32
already comments "release and code-change join [the entity enum] when they
need validation." Phase 5 of the original IA plan (issue #98, still todo)
is a different, unrelated scope (hard-fail gate promotion, GitLab/ADO/
Confluence render adapters, /worklog:find) — don't conflate the two, but
this plan continues from the same Phase 4 traceability foundation
(docs/plans/2026-07-22-ia-content-model.md:680-685).
Two design decisions confirmed with Rick before finalizing:
-
No new stored fields. The PRD asked for
parent_wiki_key/child_wiki_keys[]/linked_pr_keys[]/release_keyas stored record fields. Rejected in favor of deriving all four at render time from the graph's existing edges (belongs-to/reverse,lands-in,targets) — the graph already has this data; a stored field would be a second, driftable source of truth, whichbin/ia_graph.py:8-12's own sidecar rule already forbids ("never title/status/external, which the fold owns"). -
Live PR metadata (files changed, review/CI status) is deferred. No code
in this repo fetches
gh pr viewdata today — it's genuinely new GitHub API integration, separate risk profile from pure rendering. Phases 0-2 ship full ticket/PR/release pages from data that already exists (PR page shows linked tickets + release, "files changed" reads "not tracked"). The live sync becomes a filed follow-up item, not a silent drop.
-
bin/ia_render.py: additem_page_name(iid, it)/release_page_name(tag)next topage_name()(:40-62); extendbuild_manifest()(:309-335) to also loopfold(...).itemsandrelease/tags fromgraph["nodes"]. -
bin/ia_graph.py: additem_links(iid, graph)— one adjacency-projection helper (parent/children/PRs/release), reusing thefwd/backpattern already built inrender_traceability(ia_render.py:259-266). Every later renderer calls this one helper — not three copies. - No schema change. Verifiable via
tests/test_ia.py's existingTestGraph/manifest-shape assertions growing.
-
render_item_page(iid, it, items, records, graph)inbin/ia_render.py. Reuseia_graph.ticket_body()(:166-216) as the own-description + traceability base; add level-branching (subtask/task vs story/feature/epic downward depth) inside one function, not four near-duplicates — usesitem_links()from Phase 0. - One-line summaries: derive from
body's first sentence at render time (mirrors the existingfirst_heading()pattern,bin/ia.py:151,328) — no stored/cached field, stays byte-deterministic like the rest ofia_render.py(module docstring,:1-6). - Aggregate progress (Story/Feature/Epic) = inline status-count over
item_links()'s children — no new stored field. -
bin/worklog: newia-ticket <ULID>preview subcommand, wired liketicket-body(:559-562). - Wire into
render_all()(:346-361).
-
render_release_page(tag, records, items, graph): reuses the milestone→ closed-items join already inrender_releases(:206-241) plus PR edges viaitem_links(). Change Log section is graph-derived (closed items tagged with this milestone + their linked PRs), not aCHANGELOG.mdparser — no code parses that file today and building one is a fragile new engine this project avoids.CHANGELOG.mditself stays untouched, human authored; the page's generated Change Log is a separate, always-accurate, mechanical list (say so in one line on the page). -
render_pr_page(pr_num, graph, items, records): title/status from the stub node + reverselands-inedges → linked tickets;targets→ related release. "Changed files" / "Test/Review status" render as "not tracked" until Phase 3 (below) lands. - Both wired into
build_manifest()'s Phase-0 loop.
Do not implement in this epic. When Phases 0-2 land, file a separate
kind:feature child item describing worklog pr-sync <num> (one
gh pr view call, written via ia.write_sidecar("pr/<num>", {...}),
ia.py:253-257) — kept outside render_all() to preserve the network-free
render invariant (ia_graph.py:7).
- Extend
tests/test_ia.py's existing fixture classes (:137-262,:338+) — page-shape test per ticket level, one PR-page test, one release-page test, one manifest-growth assertion. - Regenerate via
worklog ia-render, diffed by the existing CI mechanism. - Maintain the ≥80%/95% coverage target on
bin/ia*.py.
-
pytest tests/test_ia.pygreen, coverage gate holds onbin/ia*.py. -
worklog ia-renderregenerates cleanly; manifest entry count grows to include one page per item + PR node + release tag. - Manually inspect one rendered page per ticket level, one PR page, one release page — hierarchy links, one-line summaries, Change Log correct.
-
worklog trace-checkstill passes/reports the same gaps as before. - After merge: file the Phase 3 follow-up item so the deferral is tracked.
- (P1) Phase 0: add item/release page-name helpers and extend build_manifest()
Add
item_page_name(iid, it)andrelease_page_name(tag)tobin/ia_render.pynext topage_name(), and extendbuild_manifest()to loop work items and release tags in addition to doc records, so every item/PR/release gets a manifest slot. - (P1) Phase 0: add item_links() graph helper
Add
item_links(iid, graph)tobin/ia_graph.py— one shared parent/children/PR/release adjacency lookup, reusing the fwd/back pattern already inrender_traceability, so ticket/PR/release renderers don't each reimplement graph traversal. - (P1) Phase 1: render ticket pages for all four levels
Add
render_item_page()tobin/ia_render.py, reusingticket_body()for the description/traceability base and branching by level (subtask/task vs story/feature/epic) for upward/downward hierarchy sections, wired intorender_all().- One-line summary derivation from body's first sentence (no cache)
- Aggregate progress rollup for Story/Feature/Epic pages
-
ia-ticket <ULID>preview subcommand onbin/worklog
- (P1) Phase 2: render release pages with graph-derived Change Log
Add
render_release_page()— Change Log section built from milestone- tagged closed items and their linked PRs (not a CHANGELOG.md parser), plus Release Tree, Related PRs, Related Tickets, Dependencies sections. - (P1) Phase 2: render PR pages
Add
render_pr_page()— title/status, linked tickets via reverse lands-in edges, related release via targets; files-changed/test-review status render as "not tracked" pending the Phase 3 follow-up. - (P3) Phase 3: file PR live-metadata follow-up item
After Phases 0-2 land, file a separate kind:feature child item for
worklog pr-sync(gh pr view integration) — not implemented in this epic. - (P1) Phase 4: extend tests/test_ia.py for the new page shapes Add page-shape tests per ticket level, a PR-page test, a release-page test, and a manifest-growth assertion to the existing test fixture classes — do not fork a new test file.
- (P2) Phase 4: regenerate all pages and confirm coverage gate holds
Run
worklog ia-render, verify CI diff-clean, confirm bin/ia*.py stays at or above the 80%/95% coverage target.
- Roadmap
- Design-Doc · Code-Walkthrough
- Plan: Plan-ia-content-model
- Plan: Plan-ticket-sync-and-init-detection
- ADR-0001-event-log-fold-union-merge
- ADR-0002-skill-based-edges-typed-contract
- ADR-0003-green-gates-merge
- Index-Releases
- Latest snapshot: Roadmap-2026-07-29_v0.18.0-release
- Index-Status
- Index-Decisions