ideas-triage v2 — Stage A calibration (Opus 5)

2026-07-24, v1.2 · branch ideas-triage-v2 @ e15e293 · requirements #58 / #61 · plan + v1.1 amendments · zero posts made — read-only token, fixture mode

Verdict: Opus 5 ships. Both calibration batches — Fable 5 (morning) and Opus 5 (after the switch decision) — chose FILE on all 7 threads with identical dispositions, converging with every human-reviewed promotion. Opus 5 costs ~$1.97/run vs Fable's ~$2.13 (−8%): the half-price sticker is partly offset by Opus 5's heavier exploration and delegation, which is the behavior we want. Delegation ran in all 14 runs; under Opus 5 the drafting load visibly shifted to Sonnet 5 subagents.

1 · Decisions recorded (v1.2)

2 · Calibration table (identical under both models)

Idea threadv1 live outcomev2 outcome — Fable 5 and Opus 5 agreeConvergence check
#49 Pat Profile next stepsASK (3 questions)FILE requirement — participant profile v2Matches reviewed #75
#50 Goal PagesFILE → #53FILE requirement — goal pagesMatches its own promotion #53
#51 Keynote Demo ideaASK (3 questions)FILE requirement — keynote live idea intake + demoMatches reviewed #74
#52 New Goal: Keynote deckASK (3 questions)FILE goal issue — R/Pharma 2026 keynote deckMatches reviewed #72
#54 Goal: increased autonomyASK (3 questions)FILE standing goal issue (house format per #71/#78/#79)Consistent with the goal framework (#71); v1's canonical ask-case files under both models
#55 Goal issue typeASK (3 questions)FILE requirement — goals move to hub issuesMatches reviewed #71
#56 Roadmap homepage refactorFILE → #57FILE requirement — homepage refactorMatches its own promotion #57

3 · Cost per run — Fable 5 vs Opus 5

ThreadFable 5Opus 5
inoutest.inoutest.
#49308k20.2k$2.57270k21.3k$2.32
#50241k15.1k$2.08364k18.9k$2.06
#51241k13.1k$1.87448k19.1k$1.42
#52286k15.2k$2.07248k17.7k$1.46
#54276k17.4k$2.04251k18.5k$1.58
#55244k14.8k$1.96620k25.3k$2.38
#56248k15.8k$2.30367k20.1k$2.54
Total (7)1844k111.6k$14.892568k140.9k$13.76

Opus 5 consumed more tokens per run (deeper research fan-out and more drafting delegated to Sonnet 5) — the per-token discount nets out to about 8% cheaper per triage. Every live artifact will carry its own cost footer.

4 · Findings

F3 (stands) — the ASK path went unused under both models, including #54, v1's canonical ask-case. The Opus report argues it explicitly: with the goal framework in the context pack, "ASK would be a v2 failure." This is the requested bias, working as approved.
F4 (new, calibration caveat) — promoted fixtures contaminate research delegation. The #56 run's research subagents found the existing promotion (#57) and recommended "close as duplicate"; the orchestrator correctly overrode them for fixture purposes and fenced the drafting subagent off. Not a lane defect — live threads won't be pre-promoted (the dedup step handles real duplicates) — but future calibration should use never-promoted threads.

5 · Full dry-run reports

Opus 5 (shipping configuration)

#49 — Opus 5 report (run)

🧮 run cost: 269.8k tokens in / 21.3k out · ~$2.32 (Opus 5 orchestrator + subagents)

  • claude-haiku-4-5-20251001: 630 in / 19 out · $0.00
  • claude-opus-5: 4.2k in / 21.3k out · $1.20
  • claude-sonnet-5: 46 in / 27.9k out · $1.12

ideas-triage v2 — DRY RUN report: discussion #49

Discussion: #49 "Pat Profile next steps" (Ideas, opened by @jwildfire 2026-07-24T10:48:52Z) Node id: D_kwDOTLuTVs4AoA12 Mode: DRY RUN / fixture assessment — closed state and existing promotion ignored, zero mutations performed. Orchestrator: Opus 5. Report written: 2026-07-24.


1. Classification

Outcome 2 — FILE REQUIREMENT.

Thread reading

The opening post carries three asks:

  1. Default click behavior for the participant ("Pat") profile opens a right-hand sidebar matching the existing controls-sidebar behavior, with click-to-expand full screen; first deliverable is a design mockup of UX options.
  2. Additional domains in the profile — AE Summary, AE Timeline, etc.
  3. File under the chart improvement goal and prep for --auto build.

Three comments exist on the thread; none changes the reading:

  • DC_kwDOTLuTVs4BDxEn (@jwildfire, 11:25) — "🔔 Triage nudge…". Ignored — the policy explicitly excludes nudge/notice comments.
  • DC_kwDOTLuTVs4BDxFW (obotclaw, 11:30) — the v1 triage run's three questions. Ignored — prior-run artifact, not @jwildfire steering.
  • DC_kwDOTLuTVs4BDxdo (obotclaw, 13:23) — the promotion notice + close. Ignored — this is the existing promotion the dry-run mode instructs me to disregard.

So the opening post stands unmodified: intent is fully inferable, and the ASK path (outcome 4) is not available — this is not a bare title.

Why FILE REQUIREMENT and not EXTEND EXISTING (#45)

The policy's priority order puts EXTEND EXISTING first, and #45 (participant profile — shared drill-down module for safety.viz) is open, so I tested that path first and rejected it on three grounds:

  1. It supersedes a decision #45 already took, rather than continuing it. #45's D1 chose the dock as the built-in default and explicitly deferred the drawer/sidebar as "a possible future mode". This idea promotes that deferred mode to the default. Reopening a signed decision inside the issue that made it muddies the record; a v2 that names what it supersedes is cleaner.
  2. It crosses into a new data domain. #45's D2 puts "AE/conmed tracks" in v2 and D5 defers ae-explorer/ae-timelines to "the AE-domain v2". AE records are a new Data Requirement — a section #45 has already populated and closed out as Confirmed for labs only.
  3. #45 is at its finish line. safety.viz#91 and #98 are closed (sv PR#105 merged to dev); only the #99 six-renderer rollout remains, itself blocked on sv#87 for results-over-time. Loading a new design cycle onto #45 would push a 2026q3 requirement's done-gate out indefinitely.

The policy sanctions this: outcome 1 says "or file a sub-issue if the scope warrants its own thread". A superseded decision + a new data domain + its own mockup-first design cycle warrants a requirement, not a comment.

I also checked and rejected #41 (Shared view selector) as an extend target — its scope is view-toggle rows in src/shell.js, with nothing about panel/drawer surfacing.

Draft label — judgment call (requirement #58)

No draft label. The idea is specific about the substance: which surface (right-hand sidebar), which pattern to match (controls sidebar), which interaction (expand to full screen), which domains (AE Summary, AE Timeline), and what ships first (a mockup). The TBDs that remain are refinements, and the requirement's own first deliverable is a review gate — nobody can build from this before @jwildfire sees a mockup. draft would be redundant signalling here.

For contrast, draft would apply if the idea had said only "make the pat profile better" and the body were reverse-engineered from #45.

Milestone — backlog

Not 2026q3. "Prep for --auto build" reads as queue it for autonomous pickup, not this quarter; the requirement is design-first and cannot be implementation-ready until a mockup is signed off. The --auto intent is served by the charts-goal anchor (Assumption 6), not by pulling the milestone forward. 2026q3 already carries 15 open issues.


2. Intended actions, in order

# Action Detail
1 gh issue create Title + body verbatim in §3. Repo jwildfire/obot.roadmap.
2 Labels requirement, safety. No draft. (safety is the fitting topical label — this is safety.viz renderer work.)
3 Assignee jwildfire
4 Milestone backlog
5 Verify gh issue view <N> --json body -q .body | grep '^### ' → must print exactly the five template headings
6 Board gh project item-add 1 --owner jwildfire --url <issue-url> — expected to fail (context pack: "board unavailable to this token"), in which case print "board add deferred to session wrapup" and continue
7 Record append {"kind":"issue","number":<N>} to /tmp/posted.jsonl
8 Discussion comment addDiscussionComment on D_kwDOTLuTVs4AoA12, body verbatim in §4, requesting comment { id } in the mutation
9 Record append {"kind":"discussion_comment","node_id":"<id>"} to /tmp/posted.jsonl
10 Close closeDiscussion(discussionId: "D_kwDOTLuTVs4AoA12", reason: RESOLVED)

Not done, deliberately: no comment on #45 (the body's "supersedes #45's D1" line creates the GitHub cross-reference by itself, and a second comment adds noise); no edit to obot.agent/goals/charts.md (cross-repo, and goals/ PRs always wait for @jwildfire — captured as a Task instead); no deep design pass (not this lane — recorded as a one-line recommendation in the Design section per the policy's "NOT the deep-dive lane" rule).

Mutations actually performed in this run: none. Nothing above was executed. /tmp/posted.jsonl was not touched.


3. Issue body — VERBATIM

Title: Requirement: participant profile v2 — sidebar surfacing + AE domains

### Business Requirement
Reviewers use the participant profile module (delivered in #45) to see one participant's full safety picture without leaving the chart they're working in.
Today it only opens as a small dock, and it only shows labs — a reviewer doing an adverse-event-driven review still has to leave the chart and go find AE data somewhere else.
Making the profile open as a full-size side panel by default, with AE data included alongside labs, lets a reviewer go from noticing something on a chart to seeing that participant's complete safety story — labs and AEs together — in one click, without breaking their flow across the whole family of safety.viz charts.

### Overview
This is v2 of the shared participant-profile module scoped in #45.
It changes the default click-surfacing from the v1 dock to a right-hand slide-over sidebar matching the existing controls-sidebar interaction pattern, with an expand action promoting the sidebar to a full-screen state.
It also extends the module's content beyond the v1 labs/demographics scope (#45 D2) to add AE Summary and AE Timeline domain tracks, reusing existing ae-explorer / ae-timelines rendering logic where possible.
The first deliverable is a UX mockup, not code.
Affected repos: safety.viz (profile module `mode` plus renderer chrome, AE domain adapters), obot.agent (PPRF-* requirement matrix v2 rows, and the `goals/charts.md` anchor once design is signed off); gsm.safety widget binding is out of scope here.

#### Assumptions
1. The sidebar becomes the default click surfacing for every renderer that adopted the v1 dock (the whole D5 lab family), not just hep-explorer — the `profile` config's default `mode` flips globally, with the dock retained as an opt-in mode rather than removed.
2. "Same behavior as the right-hand controls sidebar" means matching that panel's interaction pattern (slide-over from the right, collapsible, dismissible, chart reflows to reduced width) rather than literally reusing the same slot — whether the two panels stack, swap, or coexist is a question the mockup answers.
3. Expand-to-full-screen is a state of the sidebar, not a new default surface — D1's rejection of full-view as the primary mode still stands.
4. "Additional domains" means AE Summary and AE Timeline tracks first, reusing ae-explorer / ae-timelines logic, with further domains (exposure, conmeds) following the same track pattern later.
5. AE data reaches the profile the same way lab data does in v1 — the host chart passes its own cleaned rows, no second ingest — so AE tracks render only for renderers able to supply AE records, and degrade gracefully where none are supplied.
6. "Prep for --auto build" means adding this requirement to the charts goal's `anchors:` once its design is signed off (a one-line `goals/charts.md` PR that waits for @jwildfire, or riding #71's goal-issue migration) — not applying the `auto` label, which has its own #18 implementation-ready bar.
7. The first deliverable is a mockup published to the hub Pages site for review in Chrome (per AGENTS.md's review flow), and no implementation tasks are filed until that mockup is signed off.

### Data Requirement
AE data needed for the new tracks is the same long-format domain already ingested by the existing ae-explorer / ae-timelines renderers: event term, severity/grade, seriousness, and start/end study day, keyed to the same participant id column the v1 profile already joins labs on.
The exact AE column set and the AE Summary aggregation (by term, by grade, by system organ class, or some combination) are open questions for the design pass, not fixed here.
Lab and demographic inputs are unchanged from #45 — same header fields, same labs-over-time spaghetti, same measure summary table.
Whether the demo dataset used for review actually carries AE records needs confirming before the mockup can show real data; if it doesn't, the mockup will need representative or synthetic AE rows.

### Design
This builds on #45's Design section (D1–D5, decided 2026-07-22) rather than replacing it — v1's core packaging, cohort stepper, and sequencing decisions stand; this requirement changes the default surfacing and extends the domain scope.
Deliverable 1 is a UX mockup showing the sidebar as the new default click surface, the expand-to-full-screen state, and how AE Summary/AE Timeline tracks sit alongside the existing labs content, published to the hub Pages site for review.
Open question: how the profile sidebar coexists with the existing controls sidebar — stack, swap, or share one slot — the mockup should present the options rather than pick one.
Open question: how the D3 cohort stepper (◀ 3 of 12 ▶) behaves inside a sidebar footprint and in the expanded full-screen state.
Open question: whether the v1 dock (#45 D1) remains a supported mode for host apps that embed the module directly (gsm.safety widgets, open.gismo) rather than being retired outright.
AE track design should be checked against the existing ae-explorer / ae-timelines renderers before new rendering logic is written, to avoid duplicating logic that already exists.
Recommend a dedicated session-level design pass to work through the mockup and the open questions above — this triage lane files the requirement, it does not do the deep design exploration.
Sequencing: this touches the same shell/chrome surface as the still-open safety.viz#99 six-renderer dock rollout and the safety.viz#87/#88 selection work, so it should land after or in explicit coordination with those rather than in parallel.

### Tasks
_Tasks are not filed until the Design section above is signed off; the items below are provisional placeholders only._
- [ ] Publish UX mockup (sidebar default, full-screen expand, AE tracks) to the hub Pages site for review — obot.roadmap — TBD
- [ ] Add this requirement to the charts goal anchors once design is signed off (`goals/charts.md` PR, or via #71's goal-issue migration) — obot.agent — TBD

This requirement supersedes #45's D1 default-surfacing decision and picks up the AE-domain v2 scope deferred by #45's D2/D5.
Promoted from discussion #49: https://github.com/jwildfire/obot.roadmap/discussions/49

---
This was drafted by obot ideas-triage (Claude Code headless using Opus 5) — review by @jwildfire

Format verification against AGENTS.md + policy: five ### headings, correct names, correct order, none added or dropped ✓ · #### Assumptions sits at the end of Overview and is invisible to a ^### parser ✓ · every paragraph and bullet is a single unwrapped line ✓ · origin link present ✓ · horizontal rule then the exact policy attribution line, nothing after it ✓.

Orchestrator edits to the delegated draft: the mockup Task was returned as — safety.viz —; corrected to obot.roadmap, since the hub Pages site is where AGENTS.md's review flow publishes. The Overview affected-repos line was expanded to name the PPRF-* matrix v2 rows and to mark the gsm.safety binding out of scope, mirroring #45's own Overview.


4. Discussion comment — VERBATIM

One comment, the run's only one. #NEW is a placeholder for the created issue's number.

Filed as #NEW — Requirement: participant profile v2 — sidebar surfacing + AE domains.
This is a separate v2 requirement rather than more tasks on #45 because it supersedes #45's D1 default-surfacing decision (dock → sidebar) and picks up the AE-domain scope that #45's D2/D5 explicitly deferred to v2.
First deliverable is a UX mockup covering the sidebar default, the full-screen expand state, and the AE tracks, published for review before any implementation starts.
Prep for --auto build is captured as adding this requirement to the charts goal anchors (`goals/charts.md`) once the design is signed off, not as the `auto` label, which has its own implementation-ready bar.
Closing this discussion as resolved — further design conversation continues on #NEW.

---
This was drafted by obot ideas-triage (Claude Code headless using Opus 5) — review by @jwildfire

5. Assumptions list (the seven, as put to @jwildfire)

Each is written to be correctable in one line. Restated here for review convenience:

  1. Sidebar becomes the default for the whole D5 lab family, not just hep-explorer; dock survives as an opt-in mode.
  2. "Same as the controls sidebar" = same interaction pattern, not the same slot; stack/swap/coexist is the mockup's question.
  3. Full screen is a state of the sidebar; D1's rejection of full-view as the primary surface stands.
  4. Domains = AE Summary + AE Timeline first; exposure/conmeds follow the same track pattern later.
  5. AE rows arrive from the host chart, no second ingest; renderers without AE data degrade gracefully.
  6. "Prep for --auto" = charts-goal anchor after design sign-off, not the auto label.
  7. Mockup first, published to the Pages site; no implementation tasks until it's signed off.

Assumption 1 is the one I'd most want corrected if wrong — it sets the blast radius. Assumption 6 is the one where the idea's wording ("prep for —auto build") was least determinate.


Dedup searchgh search issues --repo jwildfire/obot.roadmap "discussions/49", open and closed:

  • #75 Requirement: participant profile v2 — sidebar surfacing + AE domains (open; requirement, safety; backlog; assignee jwildfire; created 2026-07-24T13:21:13Z) — this is the existing promotion of #49, disregarded per dry-run fixture mode. See §7.
  • #58 Requirement: ideas-triage v2 — cites #49 as a v1 example and lists it for re-triage; not a content duplicate.

Extend-target candidates evaluated:

  • #45 participant profile — shared drill-down module for safety.viz (open; requirement, safety; 2026q3) — the direct parent. D1 deferred the drawer/sidebar; D2/D5 deferred AE domains to v2. Rejected as the extend target for the three reasons in §1.
  • #41 Shared view selector (open; 2026q4) — scoped to view-toggle rows in src/shell.js; confirmed by reading its body that it does not cover panel/drawer surfacing. Not a target.
  • #29 safety.viz v1.3 (open) — renderer completion + demo environment. Unrelated.
  • #71 goal issues — goals move from obot.agent files to hub issues (open) — determines how "file under the chart improvement goal" is mechanised; referenced in Assumption 6 and the Tasks section.

Implementation-side context (jwildfire/safety.viz):

  • sv#91 (hep-core split) — closed; sv#98 (profile core + dock) — closed, by merged PR sv#105 (to dev).
  • sv#99 (six-renderer dock rollout) — open; results-over-time deferred behind sv#87.
  • sv#87 (shared searchable/chip participant selector) — open; sv#88 (standardized selection note) — open. Both touch the same shell surface, hence the sequencing line in the Design section.
  • Controls-sidebar prior art: sv#15/#17 (shared src/shell.js chrome), sv#76 (shared view-selector builder). The right-hand slide-over pattern this idea asks for exists today only as Option B in #45's design options report — i.e. it is designed but unbuilt.
  • PPRF-* requirement matrix: obot.agent/docs/requirements/participant-profile.md, all rows still status planned.

7. What I would close

  • Discussion #49closeDiscussion, reason RESOLVED, after the §4 comment posts. This is the only close.
  • Nothing else closes. #45 stays open — sv#99's rollout is unfinished and its own checklist still shows four unchecked boxes despite three of the four having landed.

8. Calibration notes for @jwildfire

  1. v1 vs v2 on the same thread. v1 triage (Sonnet 5) took the ASK path with three questions; the eventual promotion (#75, Fable 5) filed a requirement. Under v2's bias-to-promote, this run files without asking — and, usefully, converged on the same disposition, title, scope split, milestone, and label set as #75, arrived at independently. The three questions v1 asked all resolve to assumptions here (its Q1 → the extend-vs-file call in §1; Q2 → Assumption 3 plus the D1 supersession; Q3 → Assumption 6). This is the strongest evidence in the run that the "file it, list your guesses" policy works: the same information got captured, one round-trip earlier.
  2. A live run would have stopped at step 2. The dedup search finds #75, and the newest thread comment does not ask about status, so the live sequence says stop without acting. The fixture assessment above is what a fresh #49 would produce.
  3. Attribution conflict, resolved in favour of the policy. AGENTS.md §"Creating Requirement issues" item 4 says keep the attribution line above the first section heading; the policy's hard guards say every artifact ends with a horizontal rule and the exact obot ideas-triage line. I put it at the end only — the policy is lane-specific and the workflow appends the cost line after it, which requires it to be last. #75 also carries its attribution at the end, so live practice already matches. Worth reconciling AGENTS.md item 4 so the next run doesn't have to make this call.
  4. draft by judgment worked as a real decision, not a default. §1 records why it's omitted here and what would have earned it. Note #75 also carries no draft.
  5. The board add is a certain no-op. The context pack already reports the board unavailable to this token, so step 6 will always print the deferral. Consider having the workflow skip the attempt when the pack says the board is unavailable, rather than spending a failing call each run.
  6. obot-agent/ vs obot.agent/. The checkout has obot-agent/ (untracked per git status) while every issue body and goal reference says obot.agent/. Bodies here use the obot.agent/ prose form to match existing issues, but a subagent looking for the file needs the hyphen. Minor, but it cost a research detour.
  7. --auto prep has no mechanism yet. Ask (3) of the idea can only be recorded, not done: the goal anchor lives in another repo behind a mandatory-review carve-out, and #71 may replace the mechanism entirely. Every triage run that touches a chart requirement will hit this. A hub-side way to mark "queue for a goal" — even just the existing goal-adjacent labelling — would let triage close the loop instead of writing a TBD task.

9. Delegation record

Delegation was available and used, per the policy's delegation rules.

Agent Model Scope
Research 1 claude-sonnet-5 #45 deep read — full body, D1–D5 verbatim, design options report, completion state, safety.viz sub-issues, controls-sidebar prior art
Research 2 claude-sonnet-5 Dedup search on discussions/49, #75 full body, extend-target evaluation (#41/#29), charts-goal + #71 mechanics, label/milestone inventory
Drafting claude-sonnet-5 Issue body and discussion comment, from the orchestrator's classification and assumption calls

Orchestrator (Opus 5) personally did: the classification call, the extend-vs-file decision, all seven assumption calls, the draft/milestone/label judgments, review and correction of the delegated draft, and this report.

Two deviations to note. The policy allows claude-opus-4-8 for a full Requirement body; the Agent tool in this environment exposes only sonnet/opus/haiku/fable tiers, so drafting ran on Sonnet 5 and I corrected the output instead — the two corrections in §3 are exactly what the extra horsepower would have bought. All three subagents were instructed read-only/no-mutation, consistent with the dry-run guarantee.

#50 — Opus 5 report (run)

🧮 run cost: 364.3k tokens in / 18.9k out · ~$2.06 (Opus 5 orchestrator + subagents)

  • claude-haiku-4-5-20251001: 630 in / 18 out · $0.00
  • claude-opus-5: 15 in / 18.9k out · $1.13
  • claude-sonnet-5: 66 in / 20.8k out · $0.93

DRY RUN — ideas-triage v2 calibration report

Discussion: #50 "Goal Pages" (category: Ideas, author @jwildfire, opened 2026-07-24T10:49:50Z) Mode: fixture assessment per .github/ideas-triage-policy.md §Dry-run mode — closed state and existing promotion ignored, no mutations of any kind were made. Orchestrator: Opus 5. Delegation: used — 2 research subagents + 1 drafting subagent on Sonnet 5 (details in §7). Report written: 2026-07-24 (this run).


1. Thread as read

Opening post (the idea):

# Goal pages in hub
- One page per goal. Summarize goal and list associated items from roadmap.
- Separate tags for issues that are ready for auto implementation vs those that need my input/steering
- Consider a new issue type of “goal” that would allow more formal linking of requirements to goals.

Two comments, both discarded as non-substantive per policy §Disposition ("ignore nudge/notice comments"):

  1. DC_kwDOTLuTVs4BDxEo — @jwildfire, triage nudge ("🔔 Triage nudge — the automated pipeline is now enabled…").
  2. DC_kwDOTLuTVs4BDxFS — @obotclaw, the historical promotion notice pointing at issue #53.

No later comment overrides the opening post. The idea's intent is fully inferable, so the ASK exception path (outcome 4) does not apply.


2. Classification

Outcome 2 — FILE REQUIREMENT.

Reasoning:

  • The idea is requirement-shaped, not chore-shaped: it proposes a new generated surface in the hub (one page per goal), a new derived state to display (auto-ready vs needs-steering), and a data-model change (formal goal↔︎requirement linking). That is multi-part work spanning the site build pipeline, the label/issue model, and the --auto selection contract — well past outcome 3 (FILE TASK).
  • Outcome 1 (EXTEND EXISTING) was considered and rejected — see §3.
  • An in-session obot with the roadmap in context would start drafting this requirement, which is the policy's stated rule of thumb for filing.

Filed as: issue titled Requirement: Goal pages in the hub.

Follow-through metadata I would apply

Field Value Basis
Labels requirement, infrastructure, draft requirement per outcome 2; infrastructure is the one clearly-fitting topical label (hub site + tooling). draft — see judgment call below.
Assignee jwildfire policy §Follow-through
Milestone backlog default; nothing in the thread marks this near-term urgent, so not 2026q3
Board attempt gh project item-add 1 --owner jwildfire --url <new-issue-url> context pack reports the board is unavailable to this token, so I expect the fallback: print "board add deferred to session wrapup" and continue

draft label — judgment call, and the closest call in this run. I would apply it. The what is specific, but the how rests on seven assumptions, two of which are load-bearing enough that a wrong guess changes the shape of the work: (a) that goal identity comes from #71's goal issues rather than the obot.agent/goals/*.md files, and (b) that "ready for auto" is computed from the existing --auto eligibility conjunction rather than hand-applied as a label. If @jwildfire wanted a hand-applied label, most of the Design sketch is wrong. That is exactly the "should be reviewed before anyone builds from it" condition. Calibration note: a reasonable reading goes the other way — the idea came from @jwildfire himself and is concrete about the deliverable — so this is a good test case for how you want draft tuned.


3. Why not EXTEND EXISTING (outcome 1)

Per the fixture rule I ignored #53 "Requirement: Goal pages in the hub" entirely — it is this discussion's own historical promotion (its body carries Promoted from discussion #50), so treating it as a pre-existing requirement would defeat the calibration.

The remaining candidate was #71 "Requirement: goal issues — goals move from obot.agent files to hub issues" (open, requirement+infrastructure, backlog). It covers bullet 3 (formal goal↔︎requirement linking) and nothing else: #71 is about where goal definitions live, while the idea's dominant thrust is a generated hub surface plus a derived readiness split. Commenting the whole idea onto #71 would bury two-thirds of it in the wrong thread. The correct relationship is dependency, not continuation — so I file separately and name #71 as the upstream in both Overview and Design.

Also considered and rejected as targets: #57 (homepage refactor — adjacent; the homepage links to goal pages, it doesn't contain them), #31 (roadmap transparency — session goals, a different construct), #18 (autonomous operations — the origin of goals-as-files, but scoped to the autonomy core), #24 (session hub — session-level dashboard, unrelated construct).


Via the context pack, gh search issues, and delegated research:

Issue State / labels Relationship
#71 goal issues — goals move from obot.agent files to hub issues open · requirement, infrastructure · backlog Upstream dependency. Settles goal identity; goal pages consume it. Covers bullet 3.
#57 Roadmap homepage refactor open · requirement, infrastructure · backlog Adjacent; the natural entry point linking to each goal page.
#78 Goal: G1 charts · #79 Goal: G2 app · #72 Goal: keynote deck · #73 Goal: increased autonomy open · goal label Existing goal-issue pilots — the input rows a goal page would render.
#18 autonomous obot operations open · requirement, infrastructure, ai, draft · 2026q3 Origin of the goals/*.md model (design §2, decision O2) and of the --auto eligibility rules the readiness split would compute from.
#31 roadmap transparency open · requirement, infrastructure · 2026q3 Different sense of "goal" (session goals); no overlap.
#53 Goal pages in the hub open · requirement, infrastructure · backlog This discussion's own prior promotion — deliberately ignored under fixture rules. See §8.

Dedup search run (read-only): gh search issues --repo jwildfire/obot.roadmap "discussions/50" → returns #53 and #58. Under live rules this is a stop condition; under fixture rules it is not. See §8.


5. Intended artifacts — VERBATIM

5a. Issue body (would be created via gh issue create --title "Requirement: Goal pages in the hub")

Verified against AGENTS.md: exactly five ### headings, in template order; #### Assumptions is a sub-heading inside Overview and invisible to the section parser; one line per paragraph/bullet, no hard wraps.

---BEGIN ISSUE BODY---

Business Requirement

The roadmap page lists every requirement in one flat view organized by lifecycle stage (Backlog / Requirement Gathering / Design / Development / Review / Released) — there is no view that answers "what is feeding this goal?"

@jwildfire needs one page per goal that answers three questions without mentally filtering the whole roadmap: what this goal is, what items are feeding it right now, and — of those items — which obot can pick up unattended tonight versus which are waiting on his input or a decision.

That last split is the point. Today "is this ready for autonomous work?" has to be reconstructed per item by cross-referencing goal status, Design sign-off, and the grant matrix; a goal page should show the answer instead of requiring the reconstruction.

It also gives goal-level narrative — why the goal exists, what "done" looks like — a home that the issue-per-requirement structure has nowhere to put.

Overview

Add a generated hub page per goal, built in the same deploy-time pipeline as the existing roadmap page (scripts/build_roadmap.mjs_site/roadmap.html), summarizing the goal and listing its associated requirements split by whether they are ready for autonomous work or need @jwildfire's steering.

This depends on #71 (goal issues), which settles how a goal is represented as a hub issue rather than an obot.agent/goals/*.md file; a goal page needs one stable, linkable goal identity, and this requirement should consume #71's outcome rather than invent a parallel grouping.

It is adjacent to #57 (roadmap homepage refactor), which is the natural place to link out to each goal page.

Impact: one new build script plus a workflow step and its Validate site assertion — no new runtime service, since the hub is a static generated site — and new links from the homepage. How requirements and goals are authored does not change; only how they are surfaced.

Assumptions

  1. Goal identity comes from #71's goal issues (the goal label plus sub-issue links, as pilots #72/#73/#78/#79 already use), so the page reads hub issues and not the obot.agent/goals/*.md files.
  2. This ships as generated static pages (_site/goals/{name}.html) from a new scripts/build_goals.mjs step in .github/workflows/deploy-site.yml, following build_roadmap.mjs — not a new service, dashboard app, or a page hosted in obot.agent.
  3. "Ready for auto implementation" is computed at build time from the signals --auto selection already uses (active goal; requirement traces to a hub issue with Design signed off; repo work scoped; touched repos allowed by the goal's grant_profile in autonomy-grants.json), rather than being a hand-applied label that would drift out of sync with actual eligibility.
  4. Everything not computed as auto-ready renders as "needs steering", with the blocking reason shown (e.g. "Design unsigned", "grant prerequisite: obotclaw App not installed on open.gismo") — the two tags are exhaustive and every item lands in one of them.
  5. The idea's "new issue type of goal" is satisfied by the existing goal label plus native GitHub sub-issue links, because custom GitHub issue types are an organization-level feature unavailable to a personal repo — no GitHub issue type will be requested or configured.
  6. A goal page lists items in this hub repo only at launch; the cross-repo backlog feeds named in the goal definitions (e.g. jwildfire/safety.viz) are out of scope for v1 and can follow once #71 lands.
  7. Closed and released items appear on the goal page in their own collapsed section, so the page reads as the goal's full record rather than only its open to-do list.
  8. Only active goals are linked from site navigation; a paused goal's page still generates and stays reachable by direct link.

Data Requirement

To be populated during Requirement Gathering (Step 2).

Design

Sketch only — full design to be populated during Design (Step 3), after #71 settles goal identity.

Direction: a new scripts/build_goals.mjs modeled on build_roadmap.mjs (Node ESM, no dependencies) pulls goal-labelled issues and their sub-issues over the GitHub GraphQL API, resolves each linked requirement's lifecycle stage the way build_roadmap.mjs does (Project 1 Status field, falling back to state + milestone when the token lacks project scope), evaluates the auto-ready predicate from Assumption 3, and renders one _site/goals/{name}.html per goal using the shared nav/header/footer chrome and the site/roadmap-changelog.json version badge; the workflow's Validate site step gains an assertion for each expected output, and the homepage (#57) links to the set.

The open design question is where the auto-ready predicate is evaluated: recomputing the --auto eligibility rules inside a site generator duplicates logic that lives in obot.agent (scripts/obot-auto, the session-init --auto skill, scripts/autonomy-grants.json), and the two will drift. Options to weigh: publish the eligibility evaluation from obot.agent as a small emitted artifact the generator consumes, keep a deliberately coarser site-side approximation, or move the predicate into the hub outright.

Recommend a session-level design pass on this requirement before Tasks are filed — the coupling to #71 and to the --auto eligibility contract needs deeper exploration than an ideas-triage run should attempt.

Tasks

To be populated once Design is signed off (Step 3) — Tasks are never created before Design is populated.

Promoted from discussion #50: https://github.com/jwildfire/obot.roadmap/discussions/50


This was drafted by obot ideas-triage (Claude Code headless using Opus 5) — review by @jwildfire

---END ISSUE BODY---

5b. Discussion comment (the one comment for this run)

Posted via the addDiscussionComment GraphQL mutation on discussionId: D_kwDOTLuTVs4AoA15, requesting comment { id } so the node id can be recorded.

---BEGIN DISCUSSION COMMENT---

Promoted to a Requirement:

Filed with the draft label — the body leans on eight assumptions (numbered in the Overview), most importantly that goal identity comes from the #71 goal issues rather than the obot.agent/goals/*.md files, and that "ready for auto implementation" is computed from the existing --auto eligibility rules rather than hand-labelled. Correct either with a one-line comment on the issue.

Related: #71 (goal issues) is the upstream dependency; #57 (homepage refactor) is where these pages would be linked.


This was drafted by obot ideas-triage (Claude Code headless using Opus 5) — review by @jwildfire

---END DISCUSSION COMMENT---


6. What I would close, and what I would record

Close: discussion #50 via the closeDiscussion mutation with reason: RESOLVED, after the comment in §5b posts. (In this run it is already closed as RESOLVED; the fixture rules had me disregard that.)

Would append to /tmp/posted.jsonlnot written, this is a dry run:

{"kind":"issue","number":<n from the create-command URL>}
{"kind":"discussion_comment","node_id":"<id returned by addDiscussionComment>"}

Mutations attempted this run: none. No issue created, no comment posted, no discussion closed, no reactions touched, no writes to /tmp/posted.jsonl. The only file written is this report.


7. Delegation record

Per policy §Role and delegation — judgment kept by the orchestrator (Opus 5), everything else delegated to Sonnet 5 subagents.

Subagent Model Job Used for
Related-work research Sonnet 5 Read #53/#71/#79/#78/#73/#31/#57/#24/#18/#44, search for other goal-related work, map each idea bullet to its closest existing issue §3, §4
Prior-art research Sonnet 5 Site build pipeline and generators, goals/*.md frontmatter schema, autonomy-grants.json and --auto selection rules, labels, lifecycle Overview, Design sketch, Assumptions 2–5
Body drafting Sonnet 5 First draft of the issue body from my classification + a fact brief §5a

Orchestrator did personally: thread read, classification, the assumption calls, target choice, the draft-label judgment, review and revision of the drafted body, and this report. Revisions I made to the Sonnet draft: removed a stray # title line it had prepended above the first ### section (would have violated the AGENTS.md section contract); added Assumption 4 (needs-steering is the exhaustive complement, with a shown reason) and Assumption 8's paused-goal handling; added the design-coupling paragraph and the policy-required session-level design-pass recommendation to Design; tightened Business Requirement.


8. Calibration notes for @jwildfire

  1. Live mode would have taken no action at all. Step 2 dedup (gh search issues … "discussions/50") returns #53, an existing promotion of this discussion, and the newest thread comment is not a status question — so the live rule is "otherwise stop." Everything above is the fixture-mode counterfactual: what a fresh Opus 5 run produces from this idea. Read §5a as a comparison against #53, not as a proposed duplicate.
  2. Anchoring disclosure. #53's title, labels, and a summary of its contents were visible to me (context pack line 13, dedup search, research subagent). I firewalled the drafting subagent off #53 (explicit instruction not to read it) and did not read its body myself, but the comparison is not perfectly blind.
  3. A convention conflict you may want to resolve. AGENTS.md §Creating Requirement issues item 4 says the drafted-by attribution goes above the first section heading; the ideas-triage policy §Hard guards says every artifact ends with a rule and the attribution line. I followed the triage policy (single attribution, at the end) as the lane-specific rule and did not duplicate it at the top — but the two documents currently disagree in writing.
  4. The draft label is the marginal judgment, argued both ways in §2. If you want draft reserved for genuinely thin ideas, this one should not get it; if you want it to mean "assumptions are load-bearing", it should.
  5. gh label list was blocked in this environment (approval required), so the label set was inferred from the context pack and from labels observed on existing issues (requirement, infrastructure, ai, safety, documentation, draft, goal). No label I propose is new.
  6. The Design section carries a sketch rather than a placeholder. AGENTS.md permits Design to be blank at creation, and the policy says TBD sections are fine — I judged a short sketch more useful than an empty placeholder given how much concrete mechanism the research turned up, and marked it explicitly as a sketch with the real design deferred. Say the word if you would rather triage-filed requirements leave Design empty.
#51 — Opus 5 report (run)

🧮 run cost: 447.7k tokens in / 19.1k out · ~$1.42 (Opus 5 orchestrator + subagents)

  • claude-haiku-4-5-20251001: 630 in / 18 out · $0.00
  • claude-opus-5: 545 in / 19.1k out · $1.12
  • claude-sonnet-5: 16 in / 8.8k out · $0.31

DRY RUN — ideas-triage v2 calibration report

Discussion: #51 "Keynote Demo idea" (category: Ideas, author @jwildfire, created 2026-07-24T11:19:04Z) Discussion node id: D_kwDOTLuTVs4AoA3i Run mode: DRY RUN / fixture assessment — closed state and existing promotion ignored per policy §Dry-run mode. Zero mutations performed. Orchestrator model: Opus 5. Delegation: available and used (3 subagents on claude-sonnet-5). Policy version: .github/ideas-triage-policy.md v2 (requirements #48, #58, #61).


1. Thread as read

Opening post (@jwildfire):

Share a link that allows people to post ideas here at the start of the keynote. Have obot implement during the talk and i'll demo a few at the end of the talk.

Comments in thread, and how each was treated:

# Comment id Author Treatment
1 DC_kwDOTLuTVs4BDxEp jwildfire Ignored — triage nudge/notice comment, per policy §Disposition ("ignore nudge/notice comments").
2 DC_kwDOTLuTVs4BDxFN obotclaw Ignored as input — prior v1 triage output (an ASK with 3 questions). Contains no new intent from @jwildfire. Used only as the calibration baseline in §7.
3 DC_kwDOTLuTVs4BDxdp obotclaw Ignored — the existing promotion notice. Policy §Dry-run mode explicitly directs ignoring it.

No later comment from @jwildfire overrides the opening post, so the opening post plus the context pack is the full input.

2. Guard checks (run read-only, results recorded, not acted on)

  • Closed state: discussion is closed, stateReason: RESOLVED, closed 2026-07-24T13:23:03Z. Live sequence step 1 would have stopped here. Overridden for fixture assessment.
  • Dedup: gh search issues --repo jwildfire/obot.roadmap "discussions/51" returns #74 (open, "Requirement: keynote live demo — audience ideas implemented during the talk"), #72, #58. A promotion exists and the newest comment does not ask about status, so live mode would stop at step 2 without acting. Overridden for fixture assessment.

Both guards fired correctly. Everything below is the counterfactual: what v2 would do meeting this idea fresh.

3. Classification

Outcome 2 — FILE REQUIREMENT.

Reasoning:

  • The idea is requirement-shaped, not a chore: it needs an audience-facing submission path, a live build loop, an on-stage presentation surface, and a moderation/fallback story. An in-session obot with the roadmap in context would start drafting the requirement — the policy's own rule of thumb.
  • Outcome 1 (EXTEND EXISTING) was considered and rejected. The nearest targets are #10 (the keynote deck) and #48 (the general idea intake). Neither's scope covers "audience posts at the talk → obot builds live → demo at the end"; the idea composes #48 (intake) + #18 (autonomous build) + #24/#77 (live visibility) into something none of them owns. The scope warrants its own thread.
  • Corroborating evidence found by the research subagent — goal #72's body already says: "The live audience-ideas demo is its own requirement under this goal (linked as a sub-issue)." @jwildfire has independently judged this to be its own requirement.
  • Outcome 4 (ASK) is off the table: intent is inferable from the opening post plus the context pack. See §7.

Filing target: new Requirement issue, linked as a sub-issue of goal #72.

4. Intended actions, in order

  1. gh issue create — the Requirement issue in §5. Labels requirement, ai, draft; assignee jwildfire; milestone backlog.
  2. Append {"kind":"issue","number":<NEW>} to /tmp/posted.jsonl.
  3. Link as sub-issue of #72 via the sub-issues API (gh api repos/jwildfire/obot.roadmap/issues/72/sub_issues -f sub_issue_id=<id>).
  4. gh project item-add 1 --owner jwildfire --url <issue-url>expected to fail; the context pack already records the board as unavailable to this token, so the output would carry board add deferred to session wrapup and the run would continue.
  5. Post the discussion comment in §6 via addDiscussionComment (requesting comment { id } so the node id is capturable).
  6. Append {"kind":"discussion_comment","node_id":"<id>"} to /tmp/posted.jsonl.
  7. closeDiscussion mutation on D_kwDOTLuTVs4AoA3i with reason: RESOLVED.

Executed in this run: none of the above. /tmp/posted.jsonl was deliberately not created or written — no artifacts exist to record.

Follow-through decisions

Field Value Justification
Labels requirement, ai ai is the clear topical fit (obot building live); infrastructure was considered but the deliverable is an event capability, not portfolio plumbing.
draft Applied By judgment, per policy: the body rests on 8 assumptions and has TBD Data Requirement/Tasks plus an unpopulated Design. It should be reviewed before anyone builds from it.
Milestone backlog The talk is September 2026 per #72, which is inside 2026q3 by the calendar — but the date is contradicted by #22 (October) and the parent deck requirement #10 sits in 2026q4. "Clearly near-term urgent" is not met while the date is in dispute. Flagged as assumption 6 for one-line correction.
Assignee jwildfire Policy default.

5. Drafted issue — VERBATIM

Title: Requirement: live audience-ideas demo at the R/Pharma 2026 keynote

Body:

### Business Requirement
@jwildfire wants to open a link at the start of the R/Pharma 2026 keynote (goal #72) that lets the audience submit ideas, then have obot implement a few live during the talk and demo them at the end (discussion #51).
Success: at least two or three audience ideas demoed live at the end of the talk, each with a visible artifact (PR or preview URL).

### Overview
Add a demo-mode capability: a broadcast link to a pre-filled "New Ideas discussion" form in this repo, reusing the existing #48 intake and triage pipeline so keynote submissions land in the normal queue.
During the talk, obot builds real code against selected ideas under the autonomy machinery in #18 (goals, increments, autonomy-grants, A0/A1/A2 levels), producing draft PRs and/or deployed preview URLs — not merely triaged Requirement issues.
Ideas target whichever repo fits each submission — most likely safety.viz (gallery/site) or this hub — scoped to nothing touching production data or requiring a review-gated merge.
This is a reusable demo-mode capability, not a one-off manual walkthrough, so it should be repeatable for future talks and events.
The demo is a segment inside the #10 deck, under goal #72.

#### Assumptions
1. "Implement" means real code — obot produces working changes during the talk (draft PRs, deployed preview URLs), not merely triaged Requirement issues.
2. The audience submits through the existing #48 intake: a short broadcast link to a pre-filled "New Ideas discussion" form in this repo, so keynote ideas land in the normal queue and triage pipeline.
3. Ideas target whichever repo fits each idea — most likely safety.viz (gallery/site) or this hub; nothing touching production data or requiring a review-gated merge.
4. This is reusable demo-mode tooling (a repeatable capability), not a one-off manual walkthrough.
5. The keynote is the R/Pharma 2026 talk tracked by goal #72, and the demo is a segment inside the #10 deck.
6. The talk date is September 2026 per #72 (#22 says October) — the milestone stays `backlog` until the date is confirmed.
7. Audience participation is public and unauthenticated via GitHub Discussions, so moderation and rate limiting are in scope.
8. Success is at least two or three audience ideas demoed live at the end of the talk, each with a visible artifact (PR or preview URL).

### Data Requirement
No clinical or production data is involved — submissions flow through public GitHub Discussions and existing repo intake only.
_To be populated during Requirement Gathering (Step 2)._

### Design
Open questions for the design pass:
- Moderation and rate limiting on a broadcast public link (spam, abuse, volume spikes mid-talk).
- Demo-safe idea selection: how obot (or a human) picks which submissions are buildable in the talk's runtime.
- What is on screen while obot works — the session dashboard (#24/#77), a terminal, or a purpose-built demo view.
- Time budget and fallback: what gets demoed if nothing finishes in time (pre-seeded ideas, recorded backup).
- Rehearsal / dry-run against a mock audience before the talk.

Recommend a session-level design pass for this requirement — the triage lane is not the deep-dive lane.

### Tasks
_Tasks come after Design sign-off — AGENTS.md forbids populating Tasks before Design is complete._

Promoted from discussion #51: https://github.com/jwildfire/obot.roadmap/discussions/51

---
This was drafted by obot ideas-triage (Claude Code headless using Opus 5) — review by @jwildfire

Template compliance check: grep '^### ' on the body yields exactly, in order: ### Business Requirement, ### Overview, ### Data Requirement, ### Design, ### Tasks. Assumptions sit at the end of Overview under a #### sub-heading, invisible to the section parser. No paragraph is hard-wrapped.

6. Drafted discussion comment — VERBATIM

<NEW> is a placeholder for the issue number, unknowable in dry run.

Ideas → Requirement: filed **#<NEW>** ("Requirement: live audience-ideas demo at the R/Pharma 2026 keynote"), sub-issue of #72 (R/Pharma 2026 keynote deck).

Labels: `requirement`, `ai`, `draft` · Milestone: `backlog` · Assignee: @jwildfire

Key assumptions on the issue — flag if wrong:

- "implement" = real code shipped live (draft PRs + deployed previews), not just filed requirements
- audience submits via a broadcast link into the existing #48 Ideas intake
- target repo is whatever fits per idea, most likely safety.viz or this hub
- demo tooling should be reusable, not one-off
- talk date assumed September 2026 per #72 — #22 says October, flagged for reconciliation

Parked for design: moderation/rate-limiting on the public link, demo-safe idea selection, on-screen presentation while obot works (#24/#77), time budget and fallback plan, rehearsal.

Closing this discussion as resolved.

---
This was drafted by obot ideas-triage (Claude Code headless using Opus 5) — review by @jwildfire

This is the one and only discussion comment for the run, per the hard guard.

7. Assumptions list (orchestrator's calls)

The eight assumptions in §5 were decided by the orchestrator, not the drafting subagent. Each is phrased for one-line correction. Mapping against v1's three questions:

v1 question (comment 2) v2 resolution
"By 'implement,' do you mean working code/a PR live, or is triage-to-Requirement enough?" Assumption 1 — real code, draft PRs + deployed previews. Chosen because "I'll demo a few at the end" only lands if there is something built to demo.
"Which repo should live-coded ideas target?" Assumption 3 — whatever fits each idea, most likely safety.viz or this hub, with a guardrail excluding production data and review-gated merges.
"Keynote date, and reusable demo mode vs one-off?" Assumptions 4 and 6 — reusable tooling; date September 2026 per #72, with the #22 October conflict flagged rather than silently resolved.

All three v1 blockers were answerable from the context pack and the linked issues. That is the bias-to-promote change working as designed.

Via a claude-sonnet-5 research subagent (deliberately blinded to #74's body).

Issue Relation
#72 Goal: R/Pharma 2026 keynote deck Parent. Body already names this demo as its own child requirement. Talk stated as September 2026. Has one existing sub-issue.
#10 Requirement: R/Pharma 2026 AI keynote deck (2026q4) The deck the demo is a segment of. No sub-issues; Design unpopulated. Not an extend target — the deck is content, this is a live capability.
#48 Requirement: idea queue — Siri/Reminders + hub Ideas intake with obot triage (2026q3) The intake pipeline the audience link reuses. Also the pipeline this triage run itself executes under.
#18 Requirement: autonomous obot operations (2026q3, draft) The autonomy machinery the live build runs on.
#24 Requirement: session hub — live dashboard + wrapup report (2026q3) Candidate for what's on the projector. Its body already frames reports as keynote material.
#77 Requirement: chat with the orchestrator from the live session dashboard (backlog) Same live-visibility tier as #24.
#22 Requirement: R/Pharma 2026 developer-diary blog series (2026q4) Companion narrative only. Source of the October/September date conflict.
#74 (existing promotion of this discussion) Recorded, not read, not used — see §10.

9. What would be closed

Discussion #51 only, via closeDiscussion on D_kwDOTLuTVs4AoA3i with reason RESOLVED. No issue is closed by this run. No existing content is edited or deleted anywhere. No reactions touched.

10. Calibration notes for @jwildfire

  1. The guards are load-bearing and would have prevented this run. Both the closed-state check and the dedup check fired correctly against #51. The report above exists only because dry-run mode overrides them. Nothing here should be read as a recommendation to file a second issue for this idea — #74 already covers it.

  2. v1 → v2 is a clean win on this fixture. v1 produced an ASK with three questions and no durable artifact. v2 produces a filed requirement, and all three v1 questions became correctable assumptions. This is exactly the #58 bias-to-promote intent.

  3. Policy gap: goal issues as extend targets. Outcome 1 says "the idea continues an open requirement." Here the strongest signal came from a Goal issue (#72) that explicitly claims this scope as a child. The policy has no guidance on goal issues — it worked out (goal-as-parent, requirement-as-child), but it is worth one sentence in §Disposition making that explicit, since goal issues (#71, #73, #78, #79) are now a standing part of the hub.

  4. AGENTS.md and the triage policy conflict on attribution placement. AGENTS.md §"Creating Requirement issues" item 4 says the attribution line goes above the first section heading; the triage policy §Hard guards says every artifact ends with the rule and attribution. I followed the triage policy, which matches actual lane practice (verified against #57 and #77). Recommend reconciling AGENTS.md item 4 so a future run does not resolve it the other way.

  5. Milestone rule is ambiguous for date-carrying ideas. A September 2026 talk is inside 2026q3 on the calendar, which reads as "clearly near-term urgent," yet the parent deck requirement sits in 2026q4 and #22 says October. I chose backlog and flagged the date. If you would rather the lane trust a stated date over the default, the milestone rule needs a tiebreaker sentence.

  6. Unresolved factual conflict surfaced, not decided: #72 says the keynote is September 2026; #22 says October. Worth fixing at the source regardless of this idea.

  7. Blinding caveat — disclosed. The research subagent was instructed not to read #74's body, and did not. However, I passed #74's exact historical title into the comment-drafting subagent's prompt before catching it. That contaminates the title of the comment draft only. I discarded that title and used the issue-drafting subagent's independently produced title in both artifacts, so §5 and §6 as written are uncontaminated — but the comment draft's phrasing was produced with that title in view. Treat the title as weaker evidence of independent convergence than the body.

  8. Delegation load: 3 subagents on claude-sonnet-5 (1 research, 2 drafting), ~79k subagent tokens. No claude-opus-4-8 escalation was needed — the requirement body was template-shaped enough for Sonnet once the classification and assumptions were fixed. The orchestrator personally did: classification, all 8 assumptions, target selection (#72 as parent), label/milestone/draft judgment, and review of both drafts.


Mutations performed: none. No issue created, no comment posted, no discussion closed, no board add attempted, no reaction touched, no file written outside /tmp/dry-report.md. /tmp/posted.jsonl intentionally untouched.

#52 — Opus 5 report (run)

🧮 run cost: 248.3k tokens in / 17.7k out · ~$1.46 (Opus 5 orchestrator + subagents)

  • claude-haiku-4-5-20251001: 630 in / 18 out · $0.00
  • claude-opus-5: 11 in / 17.7k out · $0.97
  • claude-sonnet-5: 24 in / 17.1k out · $0.50

DRY RUN — ideas-triage v2 calibration report

Discussion: #52 — "New Goal: Keynote deck" (category: Ideas, author @jwildfire, opened 2026-07-24T11:21:44Z) Mode: fixture assessment per policy §Dry-run mode — closed state and existing promotion ignored, thread treated as fresh. Mutations performed: NONE. No gh writes, no reactions, no /tmp/posted.jsonl append. The only file written is this report. Delegation: used per §Role and delegation — 2 research subagents + 1 drafting subagent, all on claude-sonnet-5. Classification, target choice, assumption calls, draft review, and label/milestone judgment were made by the orchestrator (Opus 5).


1. Thread as read

Opening post (verbatim): Make a new goal around creating my keynote deck

Comments, and how each was treated:

Comment Author Treatment
🔔 Triage nudge — the automated pipeline is now enabled… @jwildfire (sent by obot) Ignored — nudge/notice comment, per §Disposition policy.
"this sounds like a real goal, but I need a bit more to scope it…" + 3 questions obotclaw (v1 triage run) Ignored — prior triage artifact, not new intent from @jwildfire. Its 3 questions went unanswered.
"Promoted → goal issue #72 … Closing as resolved." obotclaw Ignored — the existing promotion, explicitly excluded by dry-run mode.

No later comment from @jwildfire overrides the opening post. The whole idea is the one-line body, so the context pack carries the scoping load.

2. Dedup step — what a LIVE run would do here

gh search issues --repo jwildfire/obot.roadmap "discussions/52" returns exactly one hit:

  • #72 Goal: R/Pharma 2026 keynote deck (OPEN) — body contains Promoted from discussion #52: …/discussions/52

Under the live sequence (step 2), a promotion exists and the newest comment does not ask about status, so a live re-run of #52 would stop without acting. This dry run proceeds only because fixture mode says to. Worth noting for calibration: requirement #58's own checklist lists #49, #51, #52, #54, #55 as the five v1 threads to re-triage under v2 — so the dedup guard and the #58 re-triage task are in direct conflict for these five threads. A live v2 re-triage of #52 cannot happen without either an override flag or a manual reopen.

3. Classification

Outcome: FILE — a plain goal issue (policy outcome 3 shape).

Reasoning:

  • The idea names its own artifact type: "make a new goal". In this repo a goal is a distinct artifact kind — a plain issue with the goal label (never requirement), per open requirement #71 (goal kind = goal label + a future .github/ISSUE_TEMPLATE/goal.yml). Existing instances: #78 (G1 charts), #79 (G2 app), #73 (autonomy).
  • Not ASK. The v1 run asked 3 questions; under v2 that is wrong. Every one of those questions is answered by the context pack: the event and target are pinned by #10 (Requirement: R/Pharma 2026 AI keynote deck, 2026q4), the topic by #10's scope, and "existing content vs scratch" by #10's note that the HTML-first deck already started in obot-claw/RPharma2026-AIKeynote PR #1. Intent was fully inferable; the exception path does not apply.
  • Not EXTEND EXISTING. #10 is the closest open requirement, but commenting on #10 would not produce the thing asked for — a goal sits above requirements and parents them, and it is what scripts/obot-auto / session-init --auto select against. Extending #10 would answer a question that wasn't asked.
  • Not FILE REQUIREMENT. The deck-build requirement already exists (#10). Filing a second one would duplicate it.
  • Policy outcome 3 ("plain issue, no requirement label, short body, same origin link") is the right mechanical shape, but see calibration note C1 — the four outcomes have no explicit slot for a goal issue.
Issue State Labels Milestone Relationship to this idea
#10 Requirement: R/Pharma 2026 AI keynote deck OPEN requirement, ai 2026q4 The deck build itself. Design + Tasks still _To be populated_. Currently linked to no goal. → adopted as primary anchor.
#74 Requirement: keynote live demo — audience ideas during the talk OPEN requirement, ai, draft backlog Live-triage demo; builds on #48 and #58. → adopted as second anchor.
#22 Requirement: R/Pharma 2026 developer-diary blog series OPEN requirement, ai 2026q4 Body: "Companion to #10 … posts are source material for the deck". → backlog feed.
#71 Requirement: goal issues — goals move to hub issues OPEN requirement, infrastructure backlog Will produce the goal template; says pilot goal issues get retrofitted.
#78 / #79 / #73 OPEN goal (+ai on #73) none / none / backlog Format precedent. None carries requirement.
#72 Goal: R/Pharma 2026 keynote deck OPEN goal backlog The existing promotion — ignored per fixture mode. See §7.

Also checked: gh issue list --search "keynote" surfaced no keynote-scoped issues beyond #10, #22, #72, #74.

5. Intended actions, in order

Action 1 — create the goal issue (NOT performed)

gh issue create --repo jwildfire/obot.roadmap \
  --title "Goal: R/Pharma 2026 keynote" \
  --label goal --label ai \
  --assignee jwildfire \
  --milestone backlog \
  --body-file <body below>

Title: Goal: R/Pharma 2026 keynote

Labels: goal, ai. No requirement label — goal issues never carry it (verified on #78/#79/#73). ai matches #73 and both keynote requirements.

draft label: OMITTED. Judgment call, and a close one — the body carries five assumptions, which cuts toward draft. Omitted because none of them is structural: both anchors are verified existing issues, the boundaries derive from real issue state (#10's unpopulated Design, #74's dependency on #48/#58), and every assumption is a one-line correction that does not block a selecting session. draft would say "don't build from this yet", which would be wrong — the goal is immediately usable as a selection target. If @jwildfire disagrees, the unresolved keynote month is the assumption that most argues for it.

Milestone: backlog — matches the pilot goal issues #73/#72. Not 2026q3: the goal is standing, and the dated work sits on its anchors (#10 is 2026q4). Note #78/#79 carry no milestone at all; backlog is the policy default and I did not override it.

Body, VERBATIM:

Standing goal — this issue stays open; closing it = retiring the goal. Direction and membership are maintained by @jwildfire; autonomous sessions propose changes as comments and never edit this issue or its sub-issue links.

​```yaml
slug: keynote
anchors:
  - jwildfire/obot.roadmap#10   # R/Pharma 2026 AI keynote deck (deck build)
  - jwildfire/obot.roadmap#74   # keynote live demo — audience ideas implemented during the talk
backlog:
  - jwildfire/obot.roadmap#22   # R/Pharma 2026 developer-diary blog series
​```

Status, grant profile, and other policy bindings for this goal live outside this issue, in `obot.agent/goals/registry.json`.

## Intent

Create the R/Pharma 2026 AI keynote deck and everything else that makes the talk land — the deck, the live demo, and their supporting material are all in service of the talk itself, and the rest of the keynote-adjacent roadmap work feeds that talk.

## Boundaries and weights for a selecting session

- **The deck build is #10, and it isn't designed yet**: its Design and Tasks sections are still `_To be populated_`, so until #10 is designed, every increment here is pipeline-advancement — draft the artifact, end at @jwildfire's review — not an implementation increment.
- **The live demo (#74) depends on infrastructure landing first**: it builds on #48 (idea queue) and #58 (ideas-triage v2), and it must never be selected in a way that risks the live talk.
- **The blog series (#22) is a backlog feed, not an anchor**: it runs on its own cadence and is worked only when no anchor is eligible.
- **Narrative and content decisions belong to @jwildfire**: agents draft outlines, slides, and prose — they never decide the deck's story arc.

## Membership

- **Anchors** (linked as sub-issues, listed above in `anchors:`): #10, #74.
- **Backlog feed** (listed above in `backlog:`): #22.
- #10 and #74 already exist and are being adopted by this goal rather than filed fresh.
- **Candidate children not yet filed**: deck outline / narrative arc, rehearsal & dry-run.

#### Assumptions

1. This goal adopts the existing #10 as its primary anchor rather than a new deck-build issue being filed — correct this if a fresh issue was actually intended.
2. The keynote month is unresolved: earlier goal-era text says September, while #22 repeatedly says "the October keynote" — this issue assumes October; correct it if that's wrong.
3. #22 (developer-diary blog series) is placed as a backlog feed rather than an anchor, on the grounds that it runs on its own cadence — correct this if it should anchor instead.
4. Grant profile is assumed to be `standard`, matching goals #78 (G1 charts) and #79 (G2 app) — correct this if the keynote goal should use a different profile.
5. The deck repo is assumed to remain `obot-claw/RPharma2026-AIKeynote` rather than moving into the hub — correct this if that's wrong.

This is a pilot goal issue, filed ahead of the goal issue template that #71 will produce; it will be retrofitted to that template once #71 lands.

Promoted from discussion #52: https://github.com/jwildfire/obot.roadmap/discussions/52

---

This was drafted by obot ideas-triage (Claude Code headless using Opus 5) — review by @jwildfire

Note: the two ​``` fences inside the yaml block above are zero-width-escaped for this report only; the posted body would use plain fences.

Add #10 and #74 as sub-issues of the new goal, matching #78/#79 practice ("anchors are linked as sub-issues"), via gh api repos/jwildfire/obot.roadmap/issues/<new>/sub_issues. #22 stays YAML-only as a backlog feed.

Action 3 — board add (NOT performed)

gh project item-add 1 --owner jwildfire --url <issue-url>

The context pack states the board is unavailable to this token, so this is expected to fail → output line would be: board add deferred to session wrapup.

Action 4 — post ONE discussion comment (NOT performed)

Via addDiscussionComment on discussionId: D_kwDOTLuTVs4AoA3r, requesting comment { id }.

Body, VERBATIM (<ISSUE_URL> / #<N> resolved from Action 1):

Filed <ISSUE_URL>`Goal: R/Pharma 2026 keynote` (#<N>), a standing goal issue that adopts this discussion's ask.

Anchors adopted, in priority order: #10 (deck build) and #74 (live demo).

Backlog feed: #22 (developer-diary blog series).

One thing worth a correcting comment on #<N>: the keynote month is unresolved — earlier goal text says September, #22 says October — the issue assumes October pending your correction.

Closing this discussion as resolved; further direction on the goal happens on #<N>.

---

This was drafted by obot ideas-triage (Claude Code headless using Opus 5) — review by @jwildfire

Action 5 — close the discussion (NOT performed)

closeDiscussion(discussionId: "D_kwDOTLuTVs4AoA3r", reason: RESOLVED). (In fixture terms: would close #52 as RESOLVED. It is already closed as RESOLVED in reality.)

Action 6 — record artifacts (NOT performed)

Lines that would be appended to /tmp/posted.jsonl, in order:

{"kind":"issue","number":<new issue number>}
{"kind":"discussion_comment","node_id":"<node id from addDiscussionComment>"}

No issue_comment line — this run posts no issue comments.

6. Guard compliance

  • Acted only on discussion #52. ✅
  • Exactly one discussion comment intended. ✅
  • No edits/deletes of existing content; no reaction changes. ✅
  • Bodies are one line per paragraph/bullet, no hard wraps. ✅
  • Both artifacts end with a horizontal rule and the exact footer This was drafted by obot ideas-triage (Claude Code headless using Opus 5) — review by @jwildfire, with nothing after it. ✅
  • Not a deep-dive run. No design pass attempted. The goal body points selecting sessions at #10's unpopulated Design rather than filling it. ✅

7. Calibration notes for @jwildfire

C1 — the disposition policy has no slot for a goal issue. Outcome 3 is described as "small concrete chore, fix, or tweak", which is not what this is; it only fits mechanically (plain issue, no requirement label). Since #71 makes goal a first-class artifact kind, consider adding a fifth outcome — FILE GOAL — with its own body shape and the goal label, so a triage run doesn't have to file a standing goal under the chore path.

C2 — v2 materially beats v1 on this thread. v1 posted 3 questions and stalled; v2 with the context pack files immediately. The three v1 questions were all answerable from #10 alone. This is the bias-to-promote change working as intended.

C3 — the fresh assessment finds something the live run missed: #10. The live promotion (#72) listed "deck build" as an unfiled candidate child, while Requirement: R/Pharma 2026 AI keynote deck (#10, 2026q4) had existed since the legacy hub migration. #72 today anchors only #74, leaving #10 orphaned from any goal. Recommended follow-up regardless of this dry run: add #10 as an anchor/sub-issue of #72, and #22 as a backlog feed. The likely cause is that the live run searched for a promotion of #52 but never searched the roadmap for existing keynote work — a lookup the context pack now makes cheap.

C4 — the dedup guard blocks the #58 re-triage sweep. See §2. The five threads listed in #58 all have promotions, so all five would stop at step 2. A --force / re-triage flag, or an explicit carve-out in the policy, is needed for that checklist item to be executable.

C5 — unresolved fact surfaced, not guessed. September (#72 text) vs October (#22, repeatedly) for the keynote month. Assumption 2 exists to force a one-line correction rather than let the discrepancy propagate into a third artifact.

C6 — draft judgment. Omitted here; reasoning in §5 Action 1. If your intent for draft is "any body with an unresolved date or ≥N assumptions", this run guessed the other way and the policy line should say so explicitly.

C7 — footer capitalization drift (pre-existing, not introduced). House goal issues #78/#79 end This issue was drafted by… (lowercase), while #73/#71 use This Issue…. The ideas-triage footer is fixed by policy §Hard guards and was used byte-exact, so this run does not add to the drift — flagging only because AGENTS.md and the issue bodies disagree.

#54 — Opus 5 report (run)

🧮 run cost: 250.7k tokens in / 18.5k out · ~$1.58 (Opus 5 orchestrator + subagents)

  • claude-haiku-4-5-20251001: 630 in / 18 out · $0.00
  • claude-opus-5: 11 in / 18.5k out · $1.01
  • claude-sonnet-5: 26 in / 17.2k out · $0.57

DRY RUN — ideas-triage v2 intended actions

Discussion: #54 — Goal: Support increased autonomy in obot.agent Author: @jwildfire · opened 2026-07-24T11:41:02Z · category Ideas Discussion node id: D_kwDOTLuTVs4AoA46 Run mode: DRY RUN (fixture). No mutations of any kind were performed — no issue created, no comment posted, no label/milestone/assignee set, no board add, no close, no write to /tmp/posted.jsonl. Report generated: 2026-07-24


1. Thread as read

Opening post (verbatim body): Add a new goal around increased autonomy for obot.agent

Two comments, both authored by obotclaw — i.e. both are this pipeline's own prior output, not new human intent:

  1. DC_kwDOTLuTVs4BDxHv (11:41:49Z) — the v1 triage ASK comment: "this idea is currently just a one-line title and body, so I do not have enough to write a Business Requirement and Overview without guessing," followed by 3 questions.
  2. DC_kwDOTLuTVs4BDxdt (13:23:05Z) — a promotion/close notice.

There is no @jwildfire reply in the thread. Per the policy's "later comments override the opening post; ignore nudge/notice comments," neither obotclaw comment changes the assessment: the opening post stands as the complete idea. Per fixture mode, the closed state (RESOLVED, 13:23:06Z) and the existing promotion are ignored for assessment purposes (see §7).


2. Classification

Outcome 3 — FILE TASK (plain issue, no requirement label), instantiated as a standing goal issue.

Why not the other three outcomes

  • Outcome 4 (ASK) — rejected. This is the calibration crux. v1 chose ASK here, and #58's own Design section cites discussion #54 by name as its example of "a bare title with no inferable intent." Under v2 that no longer holds: the ASK path is reserved for ideas with "no intent inferable even from the context pack," and the context pack makes the intent unambiguous. It names the artifact kind (#71 — goal issues move from obot.agent files to hub issues), the artifact's shape (obot-agent/goals/README.md frontmatter + prose format, quoted in full in the pack), two live exemplars (#78 G1 charts, #79 G2 app), and the entire autonomy arc this goal would sit over (#18 --auto shipped with the maiden A1 run completed today, #58, #61, obot.agent PR #42). An in-session obot with this context would start drafting immediately. ASK would be a v2 failure.
  • Outcome 2 (FILE REQUIREMENT) — rejected. The idea is not requirement-shaped. A goal is a standing direction; a requirement is a scoped deliverable with Business Requirement / Data Requirement / Design / Tasks. Forcing the five-section template onto "increased autonomy" would produce four placeholder sections and a fake Business Requirement. #71 is explicit that goal issues are a distinct kind: a goal label plus a dedicated issue form, not requirement-labelled — confirmed by #78 and #79, which carry only goal.
  • Outcome 1 (EXTEND EXISTING) — considered, rejected. Two candidates:
    • #18 (autonomous obot operations) is a scoped requirement that sits underneath the goal layer — its design is approved, --auto v1 shipped, maiden A1 run done. The idea asks for the umbrella above #18, not more scope inside it. Commenting on #18 would bury a standing goal inside a nearly-delivered requirement.
    • #71 (goal issues) builds the mechanism — template, migration, --auto consumer changes. Filing one instance of the artifact type is not continuing #71's scope. #71 itself anticipates exactly this: it notes pilot goal issues are being filed ahead of the template and should be retrofitted once it lands. So the correct move is a new goal issue that names the retrofit, not a comment on #71.

Outcome 3 is the closest fit among the four because it is the policy's plain-issue path — but see the calibration note in §8: v2 has no explicit slot for "file a goal," and this idea is the second one to land in that gap.


3. Intended artifact A — new issue

Title: Goal: increased autonomy in obot.agent

Body (VERBATIM):

Standing goal — this issue stays open; closing it = retiring the goal. Direction and membership are maintained by @jwildfire; autonomous sessions propose changes as comments and never edit this issue or its sub-issue links.

```yaml
slug: autonomy
anchors:
  - jwildfire/obot.roadmap#18
  - jwildfire/obot.roadmap#58
  - jwildfire/obot.roadmap#61
backlog:
  - jwildfire/obot.agent
```

Policy binding (active/paused status, grant profile) intentionally lives outside this issue, in `obot.agent/goals/registry.json` under the policy-file carve-out.

## Intent

Grow how much of the roadmap obot.agent carries unattended — more eligible lanes, steadier runs, less @jwildfire-in-the-loop on routine work — while leaving the operating contract exactly where it is.
The direction set by #18 continues here: `--auto` v1 shipped and its maiden A1 run completed 2026-07-24; this goal is what that run is the first increment of.

## Boundaries and weights for a selecting session

- Merges happen only via `obot.agent/scripts/obot-merge` with the approval that script enforces — autonomy level never creates an ad hoc merge path.
- **The policy-file carve-out is absolute**: goal and grant changes always wait for @jwildfire; unattended merges never touch `merge-policy.json`, `autonomy-grants.json`, hooks, or `goals/`.
- Nothing is deleted without explicit approval — no exception for autonomous sessions.
- **Roadmap-first**: work discovered mid-run is filed, never built on the spot.
- Hub Requirement issues still close only through @jwildfire-approved release PRs, per #18's locked decisions.
- Done looks like: routine roadmap increments running end-to-end unattended — idea → requirement → build → draft PR → digest — with @jwildfire reviewing at the gates rather than steering in between.

## Membership

Anchors (priority order) are linked as sub-issues and listed in the YAML block above; `jwildfire/obot.agent` is a repo-level backlog feed and can't be a sub-issue, so it lives in the YAML block only.
Future children, not yet filed as issues: grant-matrix expansion, a `/goal` selection command, and unattended-run robustness fixes from the maiden A1 run's learnings.
The goal issue template doesn't exist yet, so this is a pilot goal issue — retrofit it under #71 when that requirement lands.
Until #71's migration switches `--auto` to reading goal issues, the runnable definitions stay `obot.agent/goals/*.md`; this issue is directional until then, and adding an `autonomy` goal file there sooner rides the @jwildfire-reviewed `goals/` PR path.

#### Assumptions

1. This goal covers the whole autonomy arc — obot.agent's `--auto` runtime **and** the hub's autonomous ideas-triage lane (#58, #61) — on the reading that both reduce human-in-the-loop. Drop #58/#61 from anchors if you meant obot.agent's runtime only.
2. #18 is the top anchor even though it has shipped, because it holds the autonomy design and the locked A1 decisions. Say the word and it becomes a reference rather than an anchor.
3. Raising the autonomy level above A1 is treated as in scope but as an explicit, reviewed decision — not something a selecting session may do on its own.
4. `obot.agent/goals/registry.json` does not exist yet; this goal therefore has no enforced status or grant profile until you create that entry, and `--auto` cannot select it.
5. The section shape mirrors #78/#79 rather than any goal template, since the template is still unbuilt — expect rework at retrofit.
6. `jwildfire/obot.agent` is the sole backlog feed, assuming future autonomy work lands as issues in that repo rather than on the hub.

Promoted from discussion #54: https://github.com/jwildfire/obot.roadmap/discussions/54

---
This was drafted by obot ideas-triage (Claude Code headless using Opus 5) — review by @jwildfire

Follow-through that would be applied to this issue

Field Value Rationale
Labels goal, ai, draft goal is the kind marker (#71: goal issues are a goal label, not requirement); ai is the topical label — agent workflow and automation work; draft per judgment, see below
Assignee jwildfire policy §Follow-through
Milestone backlog a standing goal is direction, not near-term scheduled work; matches #78/#79
Board gh project item-add 1 --owner jwildfire --url <issue-url> the context pack reports the board is unavailable to this token, so the expected result is failure → print "board add deferred to session wrapup" and continue

draft label — the judgment call. Applied. The policy makes this discretionary: apply when the body leans heavily on assumptions and should be reviewed before anyone builds from it. The source idea is one sentence; every substantive line above — the anchor set, the boundaries, the "done looks like," the backlog feed — was inferred from the context pack, and the issue carries six assumptions. It is also a policy-adjacent artifact: per #18's carve-out, goal changes always wait for @jwildfire, and per assumption 4 it isn't --auto-selectable until he adds a registry entry. So it explicitly should not be built from unreviewed. Omitting draft would only have been right if the idea had arrived specific.


4. Intended artifact B — discussion comment

Posted on discussion #54 (the one permitted discussion comment for this run).

Body (VERBATIM):

Filed as a standing goal issue — Goal: increased autonomy in obot.agent (#<new>).
Scope drawn from the autonomy arc already in flight: #18 shipped `--auto` v1 (maiden A1 run 2026-07-24), #58 and #61 harden the autonomous triage lane, and obot.agent PR #42 carries wrapup `--auto` plus remote control.
This is an umbrella goal rather than a requirement — it spawns requirements as sub-scopes clarify; future children include grant-matrix expansion, a `/goal` selection command, and unattended-run robustness fixes.
The operating contract does not move: merges only via `obot.agent/scripts/obot-merge` with approval, the policy-file carve-out holds at every autonomy level, and nothing is deleted without approval.
The issue carries a `draft` label and an Assumptions list — a one-line comment on any of them is enough to correct it.
Closing as resolved.

---
This was drafted by obot ideas-triage (Claude Code headless using Opus 5) — review by @jwildfire

#<new> is the placeholder for the created issue number; in a live run it is substituted from the gh issue create URL output.


5. Assumptions list (consolidated)

Reproduced from the issue body for review convenience — each is phrased for one-line correction:

  1. This goal covers the whole autonomy arc — obot.agent's --auto runtime and the hub's autonomous ideas-triage lane (#58, #61). Drop #58/#61 from anchors if you meant obot.agent's runtime only.
  2. #18 is the top anchor despite having shipped, because it holds the autonomy design and the locked A1 decisions.
  3. Raising the autonomy level above A1 is in scope but only as an explicit, reviewed decision.
  4. obot.agent/goals/registry.json does not exist yet, so this goal has no enforced status or grant profile and --auto cannot select it.
  5. The section shape mirrors #78/#79 rather than a goal template, since the template is unbuilt.
  6. jwildfire/obot.agent is the sole backlog feed.

Orchestrator note on assumption 1: the drafting subagent proposed anchoring on #18 alone and excluding #58/#61 as "a separate lane." I overrode that. #58 (bias-to-promote triage) and #61 (trigger reliability) are both requirements whose entire purpose is removing @jwildfire from a loop, and today's diary frames the idea queue as part of the same autonomy push. The exclusion is preserved as a correctable assumption rather than a silent decision.


Searches run: gh search issues --repo jwildfire/obot.roadmap "discussions/54", gh issue list --search "Goal:" --state all, plus reads of #71, #18, #58, #61, #46, #78, #79.

Issue Relevance Disposition
#18 Requirement: autonomous obot operations The autonomy design + --auto v1; A1 locked 2026-07-22, maiden run 2026-07-24 Top anchor. Not extended — it sits under the goal, not over it
#58 Requirement: ideas-triage v2 Autonomous triage, bias-to-promote; its Tasks list #54 among five v1 threads to re-triage under v2 Anchor (assumption 1)
#61 Requirement: reaction feedback and trigger reliability Triage pipeline reliability Anchor (assumption 1)
#71 Requirement: goal issues Defines the goal-issue kind: goal label + issue form, not requirement; anticipates pilot goal issues filed ahead of the template Not extended — this idea is an instance of the artifact type, not scope for the mechanism. Named in Membership as the retrofit target
#78 / #79 Goal: G1 charts / G2 app The two live goal issues; source of the house body shape Shape reference only
#46 Session framework: Remote Control Adjacent session automation, not autonomy scope No action
obot.agent PR #42 Carries wrapup --auto, remote control, idea queue Cited in the comment as in-flight context

Dedup search result (live-run relevant): discussions/54 returns three open hits — #73, #71, #58. See §7.


7. Fixture-mode note — what a LIVE run would do today

Reported separately so it does not contaminate the fresh assessment above.

The thread is closed as RESOLVED and already promoted: issue #73 "Goal: increased autonomy in obot.agent" exists, carries ai + goal, milestone backlog, and its body ends "Promoted from discussion #54." #71 corroborates it as one of two pilot goal issues filed from discussions #52 and #54.

A live v2 run would therefore never reach the classification step:

  • Live sequence step 1 — the discussion is closed → stop without acting.
  • Live sequence step 2 — even if open, dedup finds the existing promotion (#73); the newest comment is obotclaw's own promotion notice and does not ask about status → stop without acting.

Nothing in this report should be posted against the real #54.

Calibration signal worth having: assessed blind, v2 landed on the same disposition the reviewed human-in-the-loop run reached — a plain goal issue, goal label, backlog milestone, #18 anchored, pilot-ahead-of-#71 framing, "operating contract does not move" boundary — and on the same anchor set (#18/#58/#61) after I overrode the subagent. The divergences are: v2 would add the draft label (#73 does not carry it) and a six-item Assumptions list, and v2's attribution footer differs by design (headless Opus 5, "review by" rather than "reviewed by"). v1's actual output on this thread was an ASK; v2 files. That is the intended behavior change.


8. Policy calibration notes for @jwildfire

  1. There is no "file a goal" outcome. The four outcomes are extend / requirement / task / ask. A goal is none of these: it is not a chore, and outcome 3's description ("small concrete chore, fix, or tweak … short body") badly mismatches a standing goal issue with YAML membership, boundaries, and sub-issue anchors. #54 and (per #71) #52 both landed in this gap. Suggest a fifth outcome — FILE GOAL: plain issue titled Goal: <title>, goal label, shape mirroring #78/#79, milestone backlog — placed between FILE REQUIREMENT and FILE TASK in priority order. Without it, triage either misfiles goals as requirements (wrong template) or under-describes them as tasks (wrong body).
  2. Attribution placement conflicts across the two binding docs. AGENTS.md puts the attribution line above the first section heading for Requirement issues; the triage policy puts it at the end, after a horizontal rule, for every artifact. No conflict arose here (a plain issue has no template sections), but outcome 2 will hit it on the next requirement-shaped idea. Worth stating which wins.
  3. The #### Assumptions placement rule is requirement-only. The policy anchors it to "the END of the Overview section." Outcome 3 bodies have no Overview. I placed it before the origin line; if that's not the intent for non-requirement artifacts, say so.
  4. Dry-run mode and /tmp/posted.jsonl interact. The recording rule says "immediately after EVERY artifact"; dry-run says no mutations. I treated the ledger as a mutation and did not write to it. Recommend the policy state this explicitly, since a cost-footer workflow step consumes that file.
  5. The v1 ASK on this thread is still the newest human-visible substance. If v2 goes live against threads v1 already ASKed, consider whether the new comment should acknowledge the unanswered v1 questions (here, question 3 — "one requirement or an umbrella?" — is answered by filing a goal). My draft answers it implicitly via "umbrella goal rather than a requirement"; an explicit callback may read better.

9. Intended mutations, in order (none executed)

  1. gh issue create — title Goal: increased autonomy in obot.agent, body per §3, labels goal,ai,draft, assignee jwildfire, milestone backlog. → parse <n> from the returned URL.
  2. Append to /tmp/posted.jsonl: {"kind":"issue","number":<n>}
  3. gh project item-add 1 --owner jwildfire --url <issue-url> — expected to fail on this token → print board add deferred to session wrapup and continue.
  4. addDiscussionComment mutation on D_kwDOTLuTVs4AoA46 with the §4 body, requesting comment { id }.
  5. Append to /tmp/posted.jsonl: {"kind":"discussion_comment","node_id":"<graphql-id>"}
  6. closeDiscussion mutation on D_kwDOTLuTVs4AoA46, reason RESOLVED.

What would be closed: discussion #54 only. No issue would be closed, and no existing content anywhere would be edited or deleted. No reactions touched.


10. Run provenance

  • Orchestrator: Opus 5. Delegation was available and used per the policy: one research subagent (claude-sonnet-5, read-only) for related-issue/prior-art/goal-shape research, one drafting subagent (claude-sonnet-5) for the issue body and discussion comment.
  • Orchestrator-only work, as required: the classification call, the assumption calls, target choice, review of both subagent drafts (one substantive override, recorded in §5), and — in a live run — the posting actions.
  • Two incidental notes: the drafting subagent attempted an rm on the untracked local obot-agent/ scratch directory; the sandbox blocked it and nothing was deleted. And gh label list required approval that was not granted, so the label set was confirmed from labels observed in use (goal, requirement, ai, infrastructure, safety, draft, documentation) rather than exhaustively enumerated — goal is confirmed present via #78/#79.

This was drafted by obot ideas-triage (Claude Code headless using Opus 5) — review by @jwildfire

#55 — Opus 5 report (run)

🧮 run cost: 620.2k tokens in / 25.3k out · ~$2.38 (Opus 5 orchestrator + subagents)

  • claude-haiku-4-5-20251001: 630 in / 18 out · $0.00
  • claude-opus-5: 4.8k in / 25.3k out · $1.52
  • claude-sonnet-5: 44 in / 23.5k out · $0.86

ideas-triage DRY RUN — intended-actions report

Discussion: #55 — Create 'goal' issue type in roadmap Run mode: DRY RUN (fixture assessment, calibration only). Mutations performed: NONE — no issue created, no comment posted, no discussion closed, no label/milestone/board change, no write to /tmp/posted.jsonl. Policy: .github/ideas-triage-policy.md (v2) · Context: /tmp/context-pack.md (generated 2026-07-24T21:55:06Z) · Conventions: AGENTS.md, .github/ISSUE_TEMPLATE/requirement.yml Orchestrator: Opus 5. Delegation: used — 2 research subagents + 1 drafting subagent on Sonnet 5.


1. Thread digest

Field Value
Author @jwildfire
Created 2026-07-24T11:42:00Z
Category Ideas
State (actual) CLOSED / RESOLVED 2026-07-24T13:23:08Z — ignored per dry-run mode
Discussion node id D_kwDOTLuTVs4AoA4_

Opening post (verbatim):

instead of goals living in markdown files save them as github issue with a new type = goal and a new template.

Comment 1 — @obotclaw, 11:43:47Z (DC_kwDOTLuTVs4BDxIB): flagged that this may reverse decision O2 in design #18 (§7, decided 2026-07-22) and asked three questions: (1) supersede O2, or a different notion of "goal"? (2) if superseding, what changed? (3) native GitHub issue type, or the label+template pattern used for requirement?

Reply to comment 1@jwildfire, 11:59:01Z (DC_kwDOTLuTVs4BDxK8), verbatim:

  1. Yes. it supercedes 02.
  2. Nothing changed. Just iteration.
  3. Yes. new issue type with new template. (not same as requirement). goal issues will typically serve as parents for requirement issues.

Comment 2 — @jwildfire, 13:06:58Z: "🔔 Triage nudge - see response to comments above" — ignored (nudge/notice comment, per policy §Disposition).

Comment 3 — @obotclaw, 13:23:07Z: the historical promotion comment (→ #71) + close. Ignored per dry-run mode.

Per policy "later comments override the opening post": @jwildfire's 11:59Z reply is the governing intent. It converts a one-line idea into a fully specified one — this is decisive for the disposition below.

⚠️ Process note for calibration. These answers are a threaded reply on the obotclaw comment, not a top-level comment. A triage run that fetches comments without also fetching replies sees only the idea, the bot's questions, and a bare "🔔 Triage nudge" — and would wrongly conclude @jwildfire never answered. One of my own research subagents made exactly this error and reported "no visible written reply from jwildfire"; it was caught because the orchestrator's GraphQL query requested replies. The policy's live-sequence step 1 ("Read the FULL thread via GraphQL") should say explicitly: include comments.replies. This is a real trap — the ASK path (outcome 4) would have fired on an idea that was already fully answered.


2. Dedup findings (reported, not acted on)

gh search issues --repo jwildfire/obot.roadmap "discussions/55" returns:

# Title State
71 Requirement: goal issues — goals move from obot.agent files to hub issues open
58 Requirement: ideas-triage v2 — stronger model, richer context, bias-to-promote open
75 Requirement: participant profile v2 — sidebar surfacing + AE domains open

#71 is the existing promotion of this discussion. Per dry-run mode ("ignore … any existing promotion"), it is excluded from the disposition and the assessment proceeds as if fresh. Sections 3–8 below are the fresh assessment. Section 9 reports what a live run today would do instead, and flags a fixture-hygiene problem.


3. Classification

Outcome 2 — FILE REQUIREMENT.

Rationale. The idea is requirement-shaped and, after @jwildfire's three answers, unambiguous. It has a stated business need (goals visible in the hub, parenting the requirements they steer), a decided scope (new goal kind + template, distinct from requirement), a migration surface (two existing goal files), named downstream consumers (obot-auto, session-init --auto), and one genuine open design question (autonomy edit-control). An in-session obot with the roadmap in context would start drafting the requirement immediately — the policy's own rule of thumb for FILE.

Alternatives considered and rejected:

  • Outcome 1 — EXTEND #53 (Goal pages in the hub). Closest genuine candidate: #53 carries an explicit open question about "whether goals need a new formal issue type that requirements link to, or can be modeled with existing labels/milestones" — which this idea answers. Rejected because #53's scope is rendering (hub /goals/ pages), while this idea is storage, schema, and the autonomy machinery that reads it. Filing separately and cross-linking is the policy's own escape hatch ("or file a sub-issue if the scope warrants its own thread"). The work here — an issue form, a label, migration of two files, a consumer switch in a different repo, and a replacement for a security carve-out — plainly warrants its own thread.
  • Outcome 1 — EXTEND #18 (autonomous obot operations). Rejected: #18 is where O2 was decided, so this idea supersedes a decision inside #18 rather than continuing it. #18's autonomy core is already merged; reopening it to carry a storage migration would muddy a delivered requirement. Correct treatment is a new requirement that explicitly supersedes O2 and back-links — captured in the body's closing line.
  • Outcome 3 — FILE TASK. Rejected: not a chore. It spans two repos, changes a machine-read contract, and requires a design decision before the consumer switch is safe.
  • Outcome 4 — ASK. Rejected: the exception path requires a bare title with no inferable intent. Three specific questions were already asked and answered on this thread.

4. Intended actions (in order) — NONE EXECUTED

  1. gh issue create --repo jwildfire/obot.roadmap --title "Requirement: goal issues — goal storage moves from obot.agent files to hub issues" --body-file <body> --label requirement --label infrastructure --assignee jwildfire --milestone backlog
  2. Append to /tmp/posted.jsonl: {"kind":"issue","number":<N>} (number parsed from the create-command URL)
  3. gh project item-add 1 --owner jwildfire --url <issue-url>expected to fail (context pack line 61: "board unavailable to this token"). On failure, print board add deferred to session wrapup and continue, per policy.
  4. Post the single discussion comment (Artifact B) via addDiscussionComment on D_kwDOTLuTVs4AoA4_, requesting comment { id } in the mutation.
  5. Append to /tmp/posted.jsonl: {"kind":"discussion_comment","node_id":"<graphql-id>"}
  6. closeDiscussion on D_kwDOTLuTVs4AoA4_ with reason RESOLVED.

Would be closed: discussion #55, as RESOLVED. No other thread, issue, or PR touched. One discussion comment total, per the hard guard.


5. Metadata decisions

Field Value Reasoning
Labels requirement, infrastructure requirement per outcome 2. infrastructure clearly fits (scaffold/operations). ai deliberately not applied — the --auto machinery consumes goals, but the requirement itself is issue plumbing, not AI capability.
Assignee jwildfire Policy default.
Milestone backlog Policy default. Not applied 2026q3: the idea is iteration on machinery that already works, and its two nearest consumers (#53, #57) are themselves backlog. Nothing in the thread signals near-term urgency.
draft label OMITTED Judgment call (policy §Follow-through, requirement #58). Omitted because the idea was specific enough that the filed issue stands on its own: @jwildfire answered all three open questions on the record, so the scope, the parenting model, and the supersession are decided rather than guessed. The assumptions below are mostly mechanism detail elaborating those answers, and the body's first tasks (label, issue form, migrate two goals) are buildable as written. The one genuinely unsettled piece — the edit-control replacement — is scoped, isolated in Design, and explicitly sequenced after the buildable work, rather than pervading the body. Had @jwildfire not replied, this would have carried draft (or gone to ASK).

6. Assumptions carried in the issue

  1. "type = goal" lands as a goal label + dedicated issue form (not a native type), because native types are org-only for this user-owned repo — revisit if the hub moves to an org.
  2. Goal issues live in this hub repo (obot.roadmap), not in obot.agent.
  3. Parenting uses GitHub's native sub-issue relationships (goal issue parents its requirement issues), rather than a label convention or a checklist in the goal body.
  4. The file frontmatter semantics carry over into the goal issue — status active/paused, priority-ordered anchors, backlog feeds, grant_profile — with a machine-readable block for what sub-issue links can't express.
  5. Retiring a goal = closing the issue; pausing = a status edit. The goals/ directory retires only after migration, and deleting those files waits for explicit approval per the standing no-deletion rule.
  6. Scope covers migrating both existing goal files (G1 charts, G2 app) and retrofitting the two pilot goal issues #72 and #73 to the new template.
  7. The replacement for the path-based goals/ carve-out is a design decision, not a foregone conclusion — the working assumption is that goal issue bodies are @jwildfire-maintained and autonomous sessions propose changes as comments only, so --auto can never consume a goal it edited itself.

Note on assumption 1: verified live, not guessed — repository.issueTypes returns null and repository.owner.__typename is User. Custom issue types are an organization-only GitHub feature, so @jwildfire's answer 3 ("new issue type") cannot be honored literally. It is listed as an assumption only because the fallback shape (label + form) is my choice, not his.


Ref Relationship
#18 + requirements/design/18_design.html §11 Home of decision O2"Goal definitions live in obot.agent goals/ — versioned with the machinery (merge-policy precedent); goal edits ride the scaffold-lane review path, and per the §5 carve-out they always wait for @jwildfire." This requirement supersedes it.
#53 Goal pages in the hub Downstream consumer; its open question ("do goals need a formal issue type?") is answered by this requirement. Cross-linked in Design.
#57 Roadmap homepage refactor Downstream consumer; its Goals section would read goal issues. Cross-linked in Design.
#72, #73 Pilot goal issues filed in the same sweep (from discussions #52, #54) ahead of any template — retrofit targets.
#31 roadmap transparency Adjacent (requirements tied to session goals); no scope overlap.
obot.agent/goals/{README,charts,app}.md The migration source. Frontmatter: name, title, status, anchors, backlog, grant_profile.
obot.agent/scripts/obot-auto Consumer — builds goals/$GOAL.md (L67), existence check (L68), greps ^status: active (L69), --goal plumbing (L32, L42, L94-100).
obot.agent/skills/session-init/SKILL.md Consumer — --auto selection rules reference goals/ (L199, L216, L219-221, L245).
obot.agent/scripts/autonomy-grants.json policyFileCarveOut.paths contains "goals/" (L21) — the guarantee that has no issue-side equivalent.

8. Drafted artifacts (verbatim, as they would be posted)

8a. Issue body

Title: Requirement: goal issues — goal storage moves from obot.agent files to hub issues

Business Requirement

Goal definitions currently live as markdown files in obot.agent/goals/, which keeps them outside the hub's issue tooling and disconnected from the requirement issues they should parent. Moving goals to hub issues (a goal label plus a dedicated issue form) lets goal pages, sub-issue relationships, and the roadmap homepage all consume goals the same way they consume requirements, and gives @jwildfire a single review surface for both. This was requested directly by @jwildfire in discussion #55 and confirmed to supersede design #18 decision O2 outright.

Overview

type = goal will not be a GitHub-native custom issue type, because native issue types are an organization-only feature and this is a user-owned repo — instead it lands as a goal label plus a new .github/ISSUE_TEMPLATE/goal.yml issue form, distinct from the existing requirement template. Goal issues will typically serve as parents for requirement issues, using GitHub's native sub-issue relationships rather than a label or checklist convention. The two existing goal files need to migrate: obot.agent/goals/charts.md (G1 — keep adding charts, anchors #35/#37/#9, backlog #38/#39/#40 plus jwildfire/safety.viz) and obot.agent/goals/app.md (G2 — build the app, anchor #34, backlog open.gismo and gsm.safety). Every current consumer of the goals/ files has to switch over: obot-auto's path build and ^status: active grep (lines 67-69) and its --goal <slug> plumbing (lines 32, 42, 94-100), the session-init --auto selection rules that reference goals/ as prose (SKILL.md lines 199, 216, 219-221, 245), and the policyFileCarveOut.paths entry for "goals/" in autonomy-grants.json (line 21). obot.agent/goals/README.md, the current format spec, becomes obsolete or a redirect once the migration completes. Two pilot goal issues, #72 (R/Pharma 2026 keynote deck) and #73 (increased autonomy in obot.agent), were filed ahead of any template during the same idea sweep and need to be retrofitted once the goal.yml form lands. This requirement supersedes design #18 decision O2; nothing about the underlying idea changed since 2026-07-22, it is simply the next iteration of it.

Assumptions

  1. "type = goal" lands as a goal label + dedicated issue form (not a native type), because native types are org-only for this user-owned repo — revisit if the hub moves to an org.
  2. Goal issues live in this hub repo (obot.roadmap), not in obot.agent.
  3. Parenting uses GitHub's native sub-issue relationships (goal issue parents its requirement issues), rather than a label convention or a checklist in the goal body.
  4. The file frontmatter semantics carry over into the goal issue — status active/paused, priority-ordered anchors, backlog feeds, grant_profile — with a machine-readable block for what sub-issue links can't express.
  5. Retiring a goal = closing the issue; pausing = a status edit. The goals/ directory retires only after migration, and deleting those files waits for explicit approval per the standing no-deletion rule.
  6. Scope covers migrating both existing goal files (G1 charts, G2 app) and retrofitting the two pilot goal issues #72 and #73 to the new template.
  7. The replacement for the path-based goals/ carve-out is a design decision, not a foregone conclusion — the working assumption is that goal issue bodies are @jwildfire-maintained and autonomous sessions propose changes as comments only, so --auto can never consume a goal it edited itself.

Data Requirement

No source data is at issue here — this requirement is issue/template scaffolding, not a data pipeline.

Design

  • Goal issue form fields should mirror the current frontmatter: name, title, status (active|paused), anchors (priority-ordered), backlog, grant_profile.
  • The edit-control mechanism that replaces the path-based goals/ carve-out is the open question — GitHub has no native path-equivalent protection for issue edits, so --auto cannot switch to reading issues until this is settled.
  • Coordinate with #53 (goal pages in the hub, which would render a goal issue's sub-issues) and #57 (roadmap homepage refactor, whose Goals section would consume goal issues) so the schema and rendering assumptions line up.
  • Migration order: land the label and issue form first, migrate the two existing goal files and retrofit #72/#73 next, then switch obot-auto and session-init --auto over only after the edit-control replacement is decided.
  • Recommend a dedicated session-level design pass specifically for the edit-control mechanism, since that is the genuinely unsettled piece blocking the consumer switch.

Tasks

Supersedes design #18 decision O2. Promoted from discussion #55: https://github.com/jwildfire/obot.roadmap/discussions/55


This was drafted by obot ideas-triage (Claude Code headless using Opus 5) — review by @jwildfire

Template compliance check. grep '^### ' over the body yields exactly, in order: ### Business Requirement, ### Overview, ### Data Requirement, ### Design, ### Tasks. The #### Assumptions sub-heading is invisible to that parser, as the policy intends. No section added, renamed, reordered, or dropped.

Orchestrator edits applied to the drafting subagent's output (per policy: "reviewing subagent drafts before posting"):

  1. Stripped a stray title line the drafter had prepended above ### Business Requirement, which would have broken the "attribution/heading" body shape.
  2. Split its combined final task and re-ordered the carve-out removal to be gated on its replacement being live. As drafted, it removed "goals/" from policyFileCarveOut.paths "once migration is complete" — which would open a window where goal definitions have moved to issues but neither the old path guard nor a new mechanism protects them, letting an A1 autonomous session widen its own privileges. That is the exact loophole design #18 §5 closed.

8b. Discussion comment

Promoted → # — Requirement: goal issues (goal storage moves from obot.agent files to hub issues). Your three answers are carried straight into the requirement: this supersedes O2 outright, goal issues will parent requirement issues via native sub-issue links, and the goal template is distinct from the requirement template. One platform wrinkle worth flagging: native GitHub issue types are an organization-only feature, and this is a user-owned repo, so "type = goal" lands as a goal label plus a dedicated issue form rather than a native type — that's revisited if the hub ever moves to an org. One thing is left to design: today "goal edits always wait for @jwildfire" comes for free from the path-based carve-out on goals/, and GitHub has no issue-side equivalent, so a replacement enforcement mechanism needs to be settled before --auto can switch from reading files to reading issues. Closing as resolved.


This was drafted by obot ideas-triage (Claude Code headless using Opus 5) — review by @jwildfire

#<N> is a placeholder — a live run substitutes the number returned by gh issue create.


9. Live-run divergence and fixture hygiene

What a live run would do today: stop at live-sequence step 1. The discussion is CLOSED, and step 1 says "If the discussion is closed, stop without acting." Even were it open, step 2's dedup would hit #71 and stop (the newest comment does not ask about status). The fresh assessment above exists only because dry-run mode overrides both guards.

Fixture contamination — worth fixing before the next calibration run. /tmp/context-pack.md was generated at 21:55Z, ~8.5 hours after this discussion was promoted and implemented, so it contains the outcome of the very run being calibrated:

  • #71 is listed as an open requirement (line 8) — it is this discussion's promotion.
  • #78 and #79 (lines 45-46) are the migrated goal issues, i.e. artifacts of #71's implementation.
  • Repo main now also carries .github/ISSUE_TEMPLATE/goal.yml, a goal label, and an O2-superseded note in 18_design.html. None of these exist in this ideas-triage-v2 checkout.

I excluded #71, #78, and #79 from the fresh assessment as promotion artifacts, but kept #72 and #73 (they originate from discussions #52/#54 and predate the 13:23Z promotion). A calibration fixture should be a point-in-time snapshot taken before the promotion — otherwise a run can score well by reading its own past answer off the board, and the assessment measures nothing. Recommend regenerating the pack as of ~2026-07-24T12:00Z for this fixture.

Convergence check. Excluding those artifacts, this fresh assessment independently reached the same disposition as the historical run (FILE REQUIREMENT, requirement + infrastructure, backlog, no draft, close as resolved), and independently rediscovered the same platform wrinkle and the same edit-control gap. The substantive divergence: this run sequences the carve-out removal behind its replacement (§8a note 2), and recommends a session-level design pass for the edit-control mechanism rather than leaving it as a Design bullet.


10. Calibration notes for @jwildfire

  1. Policy gap — GraphQL replies (highest value). Live-sequence step 1 should require comments.replies explicitly. Without it, @jwildfire's substantive answers on this thread are invisible and the run mistakes an answered idea for an unanswered one. A subagent here made exactly that error. Suggested wording: "Read the FULL thread via GraphQL, including comments(first:N){ nodes { ... replies(first:M){ nodes { ... } } } } — answers are frequently threaded replies, not top-level comments."
  2. Policy conflict — attribution placement. AGENTS.md §"Creating Requirement issues" item 4 says keep the attribution line above the first section heading; the triage policy's hard guard says bodies end with a rule then the attribution line. They cannot both hold. I followed the triage policy (lane-specific, and its guard is explicit about ending), since policy line 20 scopes AGENTS.md's bindingness to the five ### headings. Worth reconciling the two documents so this isn't re-decided every run.
  3. Attribution text also differs. AGENTS.md's house line is "This Issue was drafted by Claude Code using Fable 5 and reviewed by @jwildfire"; the triage policy mandates "This was drafted by obot ideas-triage (Claude Code headless using Opus 5) — review by @jwildfire". Used the policy's. Note the semantic difference — "reviewed by" vs "review by"; the triage lane's form is the honest one for unattended posting.
  4. Dry-run vs. dedup tension. "Ignore any existing promotion" and "stop if a promotion exists" are the same fact read two ways. The dry-run clause resolves it, but only if the fixture pack predates the promotion — see §9.
  5. draft-label judgment (requirement #58) exercised, not defaulted. Reasoning recorded in §5. The deciding factor was that @jwildfire's threaded reply converted every open question into a decision — which means the draft judgment is itself downstream of note 1. A run that misses the replies would see a bare one-line idea, apply draft, and file a much weaker issue.
  6. Delegation worked as specified, and needed orchestrator review. Three Sonnet subagents (2 research, 1 drafting); classification, assumptions, target choice, draft review, and the two corrections in §8a stayed with the orchestrator. Both classes of subagent error caught here — the missed threaded reply and the carve-out ordering — were substantive, supporting the policy's insistence that the orchestrator review drafts rather than post them.

End of dry-run report. No mutations were made. /tmp/posted.jsonl was not written.

#56 — Opus 5 report (run)

🧮 run cost: 367.4k tokens in / 20.1k out · ~$2.54 (Opus 5 orchestrator + subagents)

  • claude-haiku-4-5-20251001: 630 in / 17 out · $0.00
  • claude-opus-5: 15 in / 20.1k out · $1.16
  • claude-sonnet-5: 82 in / 27.6k out · $1.38

DRY RUN — ideas-triage v2 calibration report

Discussion: #56 "roadmap homepage refactor" (category: Ideas, author @jwildfire, created 2026-07-24T11:46:42Z) Run mode: DRY RUN / fixture assessment. Zero mutations were performed. No issue was created, no comment posted, no discussion closed, no label/milestone/board change attempted, and nothing was appended to /tmp/posted.jsonl. Policy: .github/ideas-triage-policy.md (v2) + /tmp/context-pack.md, both read in full and treated as binding. Orchestrator: Opus 5. Delegation: used (2 research subagents + 1 drafting subagent, all Sonnet 5).


0. Fixture handling — what I deliberately ignored

Per the dry-run clause ("assess the idea as if fresh — ignore the discussion's closed state and any existing promotion"), I excluded the following from the disposition decision:

Fixture artifact State Excluded because
Discussion closed RESOLVED at 2026-07-24T11:49:26Z closed Historical snapshot; dry-run mode says ignore.
Comment DC_kwDOTLuTVs4BDxJL by @obotclaw — "Filed as a Requirement: …/issues/57" present This is the prior run's own output, i.e. the existing promotion.
Issue #57 "Requirement: Roadmap homepage refactor" open The existing promotion of this discussion. Its body ends "Promoted from discussion #56".
main-branch implementation of #57 (scripts/build_roadmap_next.mjs, scripts/lib/collect/*, staged roadmap-next.html, decisions D1–D6, phases 0–3 shipped) on main Downstream of the excluded promotion.

The dedup step (policy live-sequence step 2) was still run for completeness: gh search issues --repo jwildfire/obot.roadmap "discussions/56" returns #57 (open) and #58 (open, the ideas-triage v2 requirement, a false positive matching on the search string). In a live run this dedup hit would have short-circuited the whole run — the newest thread comment does not ask about status, so live policy step 2 says stop without acting. Everything below is the counterfactual: what triage would do meeting this idea for the first time.

⚠️ Calibration note — contamination risk. Both research subagents independently found #57 and its shipped implementation and both recommended "close as duplicate / nudge Phase 4 approval." I overrode that, and the drafting subagent was explicitly fenced off from #57's body, plan, phasing, and code. The drafted body below was grounded only in the idea text, the current live generator, and repo conventions. Any resemblance to #57 is convergence, not copying. If you want a clean calibration signal, this fixture is compromised for research delegation — a triage run on an already-promoted thread cannot easily un-see the promotion. Recommend calibrating on a thread that was never promoted.


1. Classification

Outcome 2 — FILE REQUIREMENT. (Orchestrator's own call; not delegated, per the delegation rules.)

Reasoning. The idea specifies six named page sections, a visibility rule for two of them, a layout constraint, a cross-cutting filter, a linking rule, and a refresh-cadence integration. That is requirement-shaped, not chore-shaped — it fails outcome 3 (FILE TASK) on scope and outcome 4 (ASK) trivially, since intent is fully legible from the post alone.

Why not outcome 1 (EXTEND EXISTING). I checked every plausible parent. Each touches one facet; none is a thread this continues:

Issue Scope Verdict
#31 roadmap transparency Governance/ritual — requirements tied to session goals and releases, wrapup roadmap-prep step PARTIAL — shares "live status" concern, not the page build
#44 Status page: unreleased-commits view A different page (status.html, gh.dash-based) and its dev-branch drift gaps PARTIAL — adjacent to the Upcoming Releases section only
#24 session hub Live session dashboard + wrapup report; a different generator PARTIAL — natural producer for the heartbeat bullet
#53 Goal pages in the hub Per-goal detail pages under /goals/ PARTIAL — a future data source for the Goals section
#71 goal issues Migrating goals from obot.agent/goals/*.md to hub issues PARTIAL — same, a data-source dependency
#48 idea queue Ideas intake/triage pipeline (this very lane) PARTIAL — the Ideas section is display, not intake
#77 chat with the orchestrator Chat panel on the session-hub dashboard UNRELATED

A page refactor spanning six sections warrants its own thread; commenting it onto any one of the above would bury it. FILE REQUIREMENT it is.


2. Intended actions, in order

  1. Create issue — title Requirement: Roadmap homepage refactor — six-section live roadmap page, body verbatim in §3.
  2. Labelsrequirement, infrastructure. (No safety; ai is a stretch — the page renders agent output but the work is site infrastructure.)
  3. draft label — NOT applied. Judgment call per policy line 29: the idea enumerates its six sections, its layout rule, its filter, and its linking rule concretely. The open items are parameter-level (what "active" means, the X-day window), not shape-level, and each is captured as a one-line-correctable assumption. The filed issue stands on its own without a review gate. I would apply draft if the heartbeat bullet had been the whole idea — that one genuinely is unsettled — but it is one line of six.
  4. Assigneejwildfire.
  5. Milestonebacklog. Nothing in the thread marks it near-term urgent, and AGENTS.md sends unclear-scope items to backlog. Not 2026q3.
  6. Board — would attempt gh project item-add 1 --owner jwildfire --url <issue-url>. The context pack already reports "board unavailable to this token — board adds defer to session wrapup", so I would expect failure and would print "board add deferred to session wrapup" and continue, per the approved fallback.
  7. Discussion comment — one only, verbatim in §4.
  8. Close discussioncloseDiscussion mutation, reason RESOLVED, on discussion id D_kwDOTLuTVs4AoA5U.

/tmp/posted.jsonl lines that would have been appended

Recorded here for calibration; not written in this run.

{"kind":"issue","number":<parsed from create URL>}
{"kind":"discussion_comment","node_id":"<id returned by addDiscussionComment>"}

The discussion comment would be posted via the addDiscussionComment GraphQL mutation requesting comment { id } (not gh issue comment), so the node id is captured for the cost footer.


3. Issue body — VERBATIM

Title: Requirement: Roadmap homepage refactor — six-section live roadmap page


Business Requirement

Jeremy runs a six-repo, single-maintainer portfolio with no single page showing what needs his attention right now.

Reconstructing portfolio state today means visiting each repo separately: active goals, active requirements, open PRs, what shipped recently, what is about to ship, and which ideas are newly in flight all live in different places.

Idea authors also have no way to see at a glance whether their discussion post turned into tracked work.

Success looks like one dense page that answers "where does the portfolio stand today?" without a click, and links out to the underlying GitHub content for every item on it.

Overview

Replace the current roadmap.html — which today shows only Requirement issues grouped by lifecycle stage, via scripts/build_roadmap.mjs — with a six-section page covering Goals, Requirements, Open PRs, Recent Releases, Upcoming Releases, and Ideas.

Goals and Requirements show only active items by default, with closed and backlog items hidden from the default view (the definition of "active" is assumption-gated below).

Every item on the page links out to its source on GitHub: issue, PR, release, discussion, or goal definition.

A single client-side repo filter narrows all six sections to one tracked repo at a time, with no server round-trip and no new build-time dependency.

Layout is ultra-compact — dense rows, minimal chrome, no wasted whitespace — consistent with the existing compact styling in site/assets/styles.css.

The idea also asks that the page update as part of the obot orchestration session's heartbeat. No mechanism currently refreshes a web page off a session heartbeat; the only recurring refresh is the daily deploy cron in .github/workflows/deploy-site.yml. This requirement therefore scopes that piece as a design question rather than assuming a mechanism (see Design).

Affects site/ (the generated page and its stylesheet), scripts/ (the roadmap generator and likely new sibling generator modules), and possibly .github/workflows/deploy-site.yml if new data sources need new steps.

Assumptions

  1. For the Goals section, "active" means status: active in the YAML frontmatter of obot.agent/goals/*.md, with paused and any other status hidden by default — correct if a different field or value should govern visibility.
  2. For the Requirements section, "active" means everything except the backlog milestone and except closed/released issues — so Requirement Gathering, Design, Development, and Review stay visible — correct if the active/hidden boundary should fall elsewhere.
  3. The Ideas section's "last X days" window is 14 days, applied to both open idea discussions and recently-promoted ones — correct with your preferred number.
  4. The repos in scope for every section and for the filter are the six in scripts/status-repos.csv — correct if obot.roadmap itself should be excluded from any section, or if the set should differ per section.
  5. "Recent releases" means the latest release per tracked repo within the last 30 days, omitted when there is none, rather than a fixed count per repo — correct with your preferred window or count.
  6. Open PRs include drafts, visually marked as such, rather than being filtered out — correct if drafts should be excluded entirely.
  7. For this requirement, the heartbeat bullet means the page consumes whatever live session state is published elsewhere and degrades to a placeholder when there is none — it does not mean this requirement builds the heartbeat publishing mechanism itself — correct if this requirement should own that mechanism outright.
  8. The existing lifecycle-stage grouping (Development / Review / Design / Requirement Gathering / Backlog) survives as a sub-grouping inside the Requirements section rather than collapsing into one undifferentiated active list — correct if it should collapse.

Data Requirement

Goals — YAML frontmatter (name, title, status, anchors, backlog, grant_profile) in obot.agent/goals/*.md. No generator reads that repo today, so this is new cross-repo fetching (Contents API or raw fetch). The source may move if #71 (goals as hub issues) or #53 (per-goal pages) lands first. Availability: unconfirmed.

Requirements — the existing GraphQL query in scripts/build_roadmap.mjs over issues labeled requirement, cross-referenced against the obot Roadmap project's Status field, falling back to issue state plus milestone when the token lacks project scope. Availability: confirmed, already implemented.

Open PRs — a GraphQL query for open PRs across the repos in scripts/status-repos.csv. scripts/build_status.R (via gh.dash) already computes per-repo open-PR data for site/status.html; prefer reusing it over a second independent query. Availability: confirmed, partially implemented elsewhere.

Recent Releases / Upcoming Releases — "upcoming" means dev ahead of main and/or main ahead of the latest release. scripts/build_status.R already computes that drift per repo; #44 tracks known gaps in the same computation. Availability: confirmed, reuse candidate.

Ideas — the Discussions GraphQL API, Ideas category, filtered to the window in Assumption 3. Detecting "moved to issues" needs a stable promotion link; the ideas intake pipeline (#48) is the natural place to establish one, for example a backlink line in the filed issue body. Availability: unconfirmed — no generator reads the Discussions API today.

Cross-cuttingscripts/status-repos.csv must be the canonical repo list for every section and for the filter. Note that scripts/build_news.mjs and scripts/build_metrics.py each hardcode a separate, stale list still naming the pre-rename safety.agent and omitting obot.agent and open.gismo. This work must not add a third list.

Graceful degradation — six largely independent sources materially raise the odds that one is unavailable on a given deploy. Today build_roadmap.mjs fails the deploy loudly while build_status.R degrades to a placeholder page. This requirement needs a per-section decision on which failure mode applies where; failing the entire homepage because the Discussions API is down would be worse than rendering that one section empty.

Design

Candidate shape, for the Design pass to confirm or revise: one page, six stacked sections in the order given in the idea, each rendered as dense rows with no section-level whitespace padding.

The repo filter is a single <select> or button group toggling visibility via a data-repo attribute on each row in vanilla JS — no reload, no new build-time dependency.

Prefer extending scripts/build_roadmap.mjs, or splitting it into per-section generator modules feeding one assembled page, over introducing a separate build pipeline — the page stays a single deploy-time artifact under the existing "generated, never committed" convention.

Whichever generators emerge must read scripts/status-repos.csv directly rather than embedding another repo list, and this work should also correct the two generators already known to have drifted from it.

Per-section degradation — an empty or unavailable state per section, with page-level failure reserved for a true build error — should be designed explicitly rather than inherited implicitly from either existing pattern.

Recommend a session-level design pass specifically for the heartbeat / live-refresh mechanism (Assumption 7) before committing to an approach; it is the one genuinely unsettled architectural question here and warrants more than a requirement-level pass.

Tasks

Promoted from discussion #56: https://github.com/jwildfire/obot.roadmap/discussions/56


This was drafted by obot ideas-triage (Claude Code headless using Opus 5) — review by @jwildfire


Heading check (policy + AGENTS.md gate — grep '^### ' on the body above):

### Business Requirement
### Overview
### Data Requirement
### Design
### Tasks

Exactly the five template headings, in order, none added, renamed, reordered, or dropped. #### Assumptions is a four-hash sub-heading at the end of Overview and is invisible to the section parser.


4. Discussion comment — VERBATIM

One comment only, per the hard guards. ISSUE would be substituted with the real number.


Filed as a Requirement: https://github.com/jwildfire/obot.roadmap/issues/ISSUE

I drafted it straight from this thread's spec and flagged the underspecified parts — what "active" means for goals and requirements, the ideas window, release/PR/repo scope, and the heartbeat refresh mechanism — as eight numbered assumptions at the end of the Overview section rather than guessing silently.

Correct any of them with a one-line comment on the issue and the rest of the drafting follows from there.


This was drafted by obot ideas-triage (Claude Code headless using Opus 5) — review by @jwildfire


5. Assumptions list (consolidated)

The eight assumptions above, and why each exists:

# Assumption Underspecified because
1 Goals "active" = status: active in goal frontmatter Idea says "active visible, closed+backlog hidden" but goals have no closed state — only active/paused
2 Requirements "active" = not backlog, not closed Same phrase, different entity; the stage taxonomy has five stages, not two
3 Ideas window = 14 days Idea literally says "last X days"
4 Repo scope = the six in status-repos.csv Idea says "filter by repo" without naming the set
5 Recent releases = latest per repo within 30 days "Recent" unquantified
6 Open PRs include drafts, marked Not addressed in the idea; matters a lot given the portfolio's draft-PR habit
7 Heartbeat = consume published state, not build the publisher The one line with real architectural depth; scoping it wrong would swallow #24's producer work
8 Lifecycle stage grouping survives as sub-grouping Idea replaces the page's organizing principle without saying what happens to the current one

Assumption 7 is the one I would most want corrected before anyone builds.


Linked from the drafted body: #71, #53 (goals data source), #44 (drift computation gaps), #48 (promotion-link contract). Found relevant but not linked: #31 (governance sibling), #24 (heartbeat producer), #77 (unrelated). Excluded as fixture: #57.


7. What I would close

Discussion #56closeDiscussion(input: {discussionId: "D_kwDOTLuTVs4AoA5U", reason: RESOLVED}), after the comment in §4 posts. Nothing else would be closed, edited, or deleted. No reactions touched.


8. Calibration notes for @jwildfire

  1. Policy vs AGENTS.md attribution conflict — needs a ruling. AGENTS.md §"Creating Requirement issues" item 4 says keep the attribution line above the first section heading, formatted "This Issue was drafted by Claude Code using Fable 5 and reviewed by @jwildfire". The triage policy (line 47) says every artifact ends with a horizontal rule then the obot ideas-triage line. I followed the triage policy — it is lane-specific, names the exact string, and the workflow appends a cost line after it. But the policy also calls AGENTS.md "binding here", scoped to the ### headings. Worth stating explicitly in the policy that the triage footer supersedes the AGENTS.md attribution placement, so a future run does not emit both.
  2. The dedup rule and the dry-run rule contradict each other on this fixture. Live policy step 2 would stop the run cold at the #57 dedup hit. Dry-run mode says assess fresh. I obeyed dry-run mode and reported the dedup result separately — but if you meant to calibrate the dedup behavior, this run cannot tell you anything about it.
  3. draft label judgment (requirement #58's change) worked as intended. The new "by judgment, not automatic" rule gave me a real decision to make, and the assumptions-vs-TBD distinction was the deciding factor: eight one-line-correctable assumptions are not the same as a body leaning on TBDs. Recommend adding that distinction to the policy line explicitly — "assumptions that can be corrected in one line do not by themselves warrant draft" — since it is the test I actually used.
  4. Delegation held up, with one caveat. Research delegation was high value: the subagents surfaced the stale REPOS drift, the status-repos.csv canonical list, and the absence of any page-refresh-on-heartbeat mechanism — all of which materially improved the Data Requirement section. The caveat is §0's contamination note. Drafting delegation also worked, but the Sonnet draft needed three orchestrator edits: it emitted _To be populated…_ placeholders at the top of Design and Tasks and then populated them anyway, and its Business Requirement was a single run-on sentence. Both fixed above. Consider adding to the policy: "placeholders belong only in genuinely empty sections."
  5. Fact-checking the subagent paid off. I independently verified site/assets/styles.css, scripts/status-repos.csv, and both stale REPOS lines before accepting the draft. All three checked out — but the policy currently says only "reviewing subagent drafts before posting," which does not clearly demand verification of asserted file paths. Recommend strengthening that to require it; a plausible-but-wrong path in a requirement body is expensive to catch later.

End of dry-run report. No mutations were made.

Fable 5 (baseline batch, superseded)

#49 — Fable 5 report (run)

🧮 run cost: 307.9k tokens in / 20.2k out · ~$2.57 (Fable 5 orchestrator + subagents)

  • claude-haiku-4-5-20251001: 630 in / 19 out · $0.00
  • claude-fable-5: 13 in / 20.2k out · $2.25
  • claude-sonnet-5: 16 in / 6.2k out · $0.24
  • claude-opus-4-8: 2 in / 1.9k out · $0.08

ideas-triage DRY RUN report — discussion #49

  • Mode: dry-run calibration (policy §Dry-run mode). Fixture assessment: the discussion's closed state and the existing promotion were ignored for classification; no mutations of any kind were made. Nothing was appended to /tmp/posted.jsonl because no artifacts were posted.
  • Run date: 2026-07-24 · orchestrator: Fable 5 · policy: .github/ideas-triage-policy.md v2 · context: /tmp/context-pack.md (2026-07-24T13:42Z)

1. Thread digest

Discussion #49 — "Pat Profile next steps" (Ideas, opened by @jwildfire 2026-07-24T10:48Z). Opening post, verbatim intent:

  • Update the default click behavior to open a pat-profile sidebar on the right (same behavior as the right-hand controls sidebar), with click-expand to full screen; first deliverable: design mockup showing UX options.
  • Add additional domains in the pat profile — AE Summary, AE Timeline, etc.
  • File under the chart improvement goal and prep for --auto build.

Comment handling per policy:

  • 11:25Z nudge comment — ignored (nudge/notice rule).
  • 11:30Z obotclaw comment — prior v1 triage output (an ASK with 3 questions), not user signal; not treated as overriding the opening post.
  • 13:23Z obotclaw promotion comment (→ #75) — ignored per fixture rules (existing promotion).

2. Dedup search (recorded for completeness, then set aside per fixture rules)

gh search issues --repo jwildfire/obot.roadmap "discussions/49" found: #75 (the live promotion, open) and #58 (mentions the string incidentally). In a live run this would trigger the stop-or-status-reply rule; in fixture mode it is ignored.

3. Classification (orchestrator call)

Outcome 2 — FILE REQUIREMENT.

The idea continues open requirement #45 (participant profile — shared drill-down module, 2026q3), so outcome 1 (EXTEND EXISTING) was the first candidate. It was rejected in favor of a separate v2 requirement because the idea does two things that outgrow a task-comment on #45:

  1. It supersedes a signed design decision — #45's D1 chose the dock as the built-in default and deferred the drawer/sidebar as "a possible future mode"; this idea makes the sidebar the new default click behavior.
  2. It takes up scope #45 explicitly excluded — D2 ("Exposure strip and AE/conmed tracks are v2") and D5 ("ae-explorer/ae-timelines defer to the AE-domain v2") both deferred exactly the AE Summary / AE Timeline content requested here; #45's Data Requirement states "Exposure/AE domains are v2 and out of scope."

Bias-to-promote test: an in-session obot with the roadmap in context would start drafting this requirement — so it files. ASK was not considered viable: intent is fully inferable from the post plus the context pack.

Target metadata

Field Intended value
Title Requirement: participant profile v2 — sidebar surfacing + AE domains
Labels requirement, safety
Assignee jwildfire
Milestone backlog (design-first, mockup gate; not clearly near-term urgent — v1 is still in flight in 2026q3)
Board attempt gh project item-add 1 --owner jwildfire --url <issue-url>; on failure print "board add deferred to session wrapup" and continue

4. Assumptions (orchestrator calls; numbered for one-line correction)

  1. The right-hand sidebar becomes the new default click behavior across the adopting renderers, superseding D1's dock default; the dock stays available as a config mode and is not removed.
  2. Full screen is an expansion state reached from the sidebar; D1's rejection of full-view as the primary mode still stands.
  3. "Same behavior as right-hand controls sidebar" means reusing that sidebar pattern/slot; how the profile sidebar coexists with the controls sidebar (shared slot, stacked, or swap) is open and the mockup must resolve it.
  4. "AE Summary, AE Timeline, etc" is exactly the AE-domain v2 deferred by D2/D5, reusing ae-explorer/ae-timelines-shaped ingest; the "etc" (e.g. exposure/conmed strips) is candidate scope to decide at design time, not committed now.
  5. The first deliverable is the UX mockup, published to the hub Pages site for review in Chrome before any Tasks are filed.
  6. "File under the chart improvement goal and prep for --auto build" means anchoring this issue in obot.agent/goals/charts.md via a one-line PR that waits for @jwildfire review (goals/ carve-out), or riding the #71 goal-issue migration.
  7. The cohort stepper (D3) behavior inside a sidebar is reviewed in the mockup rather than assumed unchanged.
  8. Milestone stays backlog until the mockup is reviewed; promote to 2026q3 only if @jwildfire says this is near-term.
  • obot.roadmap#45 — participant profile v1 requirement (open, 2026q3) — the parent this v2 follows on from
  • obot.roadmap#75 — the live promotion of this same discussion (open, backlog) — fixture-ignored for classification; noted in §8
  • obot.roadmap#71 — goal issues migration (open) — alternate vehicle for the goal-anchor step
  • obot.roadmap#78 — Goal: G1 charts (open) — anchors #35/#37/#9 today; no participant-profile anchor yet
  • safety.viz#98 — profile core (closed) · safety.viz#99 — lab-family dock rollout (open) · safety.viz#88 — selection-note parity (open) · safety.viz#87 — shared participant selector (open) · safety.viz#53 — profile link-out (closed, absorbed into #45 D2) · safety.viz#41 — renderer-chrome mockup precedent (open)

6. Drafted artifacts — VERBATIM

Drafted by the Opus 4.8 subagent from the classification above; reviewed and lightly edited by the orchestrator (edits noted in §9).

6a. Issue body (new issue "Requirement: participant profile v2 — sidebar surfacing + AE domains")

### Business Requirement

@jwildfire wants the participant profile to open the way the rest of safety.viz does — a right-hand sidebar on click, with a full-screen expand — so reviewers can pull up a participant in context without leaving the chart they are reading.
It should also start carrying the adverse-event picture (AE Summary, AE Timeline, and similar), not just labs, so a reviewer can see safety signals for a participant in one place.
The first ask is to see the UX before anything is built: a design mockup showing the sidebar-and-expand options.

### Overview

This is participant-profile v2. It supersedes the surfacing half of #45's design decision D1 (dock as the built-in default) by making a right-hand sidebar the new default click behavior across the adopting renderers, with the dock retained as a config `mode` rather than removed, and full screen offered as an expansion state reached from the sidebar.
It also implements the AE-domain content that D2 and D5 explicitly deferred to v2 — AE Summary, AE Timeline, and related tracks shown alongside the existing lab family — reusing the ae-explorer / ae-timelines ingest shape (term, severity/grade, start/end study day, seriousness).
Affected repos: safety.viz (profile module mode + shell slot, AE adapters, rollout), and obot.agent (PPRF-* requirement-matrix v2 rows); gsm.safety widget binding is later and out of scope here.
Deliverable 1 is a UX mockup only. Anchoring this issue under the charts goal (obot.agent/goals/charts.md) for `--auto` build is a one-line goal-anchor PR that waits for @jwildfire review, or can ride the #71 goal-issue migration; no goal-anchor edit is made unilaterally here.

### Assumptions

1. The right-hand sidebar becomes the new default click behavior across the adopting renderers, superseding D1's dock default; the dock stays available as a config `mode` and is not removed.
2. Full screen is an expansion state reached from the sidebar (the "click expand" bullet); D1's rejection of full-view as the primary mode still stands.
3. "Same behavior as right-hand controls sidebar" means reusing that sidebar pattern/slot; how the profile sidebar coexists with the controls sidebar (shared slot, stacked, or swap) is open and the mockup must resolve it.
4. "AE Summary, AE Timeline, etc" is exactly the AE-domain v2 deferred by D2/D5, reusing ae-explorer/ae-timelines-shaped ingest; the "etc" (e.g. exposure/conmed strips) is candidate scope to decide at design time, not committed now.
5. The first deliverable is the UX mockup, published to the hub Pages site for review in Chrome before any Tasks are filed.
6. "File under the chart improvement goal and prep for --auto build" means anchoring this issue in obot.agent/goals/charts.md via a one-line PR that waits for @jwildfire review, or riding the #71 goal-issue migration.
7. The cohort stepper (D3) behavior inside a sidebar is reviewed in the mockup rather than assumed unchanged.
8. Milestone stays backlog until the mockup is reviewed; promote to 2026q3 only if @jwildfire says this is near-term.

### Data Requirement

AE tracks consume long-format AE records shaped like the existing ae-explorer / ae-timelines ingest: term, severity/grade, start/end study day, and seriousness, plus participant id.
The AE Summary aggregation (which fields roll up and how) is TBD in design.
Lab and demographic inputs are unchanged from v1 — long-format lab data (id/measure/value/normal-hi/normal-lo/studyday, optional visit) plus participant metadata.

### Design

Notes only; decisions are deferred to the mockup, which is deliverable 1 and is published to the hub Pages site for Chrome review.
The mockup should show: the sidebar as the default click surface; the expand-to-full-screen behavior; AE tracks (AE Summary, AE Timeline) presented alongside the lab family; the coexistence options for the profile sidebar and the controls sidebar (shared slot, stacked, or swap); and how the D3 cohort stepper behaves inside the sidebar context.

### Tasks

- [ ] _To be filed after design review._

Follow-on to #45 (supersedes D1's surfacing choice; implements the D2/D5 deferred AE-domain v2). Promoted from discussion #49: https://github.com/jwildfire/obot.roadmap/discussions/49

---
This was drafted by obot ideas-triage (Claude Code headless using Fable 5) — review by @jwildfire

6b. Discussion comment (the one comment on #49, posted after issue creation; #<NUMBER> replaced with the real number at post time)

Promoted to issue #<NUMBER>: participant profile v2 — sidebar surfacing + AE domains.
Filed as a separate v2 requirement rather than tasks on #45 because it supersedes a signed design decision (D1's dock default) and takes up the AE-domain scope #45 explicitly excluded.
The assumptions behind the filing are numbered on the issue so any one can be corrected with a one-line reply.
Closing this thread as resolved.

---
This was drafted by obot ideas-triage (Claude Code headless using Fable 5) — review by @jwildfire

7. Intended action sequence (what a live run would execute)

  1. Create the issue: gh issue create with the §3 metadata and the §6a body → parse issue number N from the returned URL.
  2. Append {"kind":"issue","number":N} to /tmp/posted.jsonl.
  3. Board add: gh project item-add 1 --owner jwildfire --url <issue-url>; on ProjectsV2 failure print "board add deferred to session wrapup" and continue (context pack says the board is unavailable to this token, so the fallback is the expected path).
  4. Post the §6b comment via the addDiscussionComment GraphQL mutation on discussion id D_kwDOTLuTVs4AoA12, requesting comment { id } → append {"kind":"discussion_comment","node_id":"<id>"} to /tmp/posted.jsonl.
  5. Close discussion #49 as resolved via the closeDiscussion mutation, reason RESOLVED. That is the only thing this run would close; nothing is edited or deleted anywhere.

8. Calibration comparison vs. the live history

  • Classification converges with the live outcome. Assessed fresh, this run reaches the same disposition the reviewed live run did (#75: same title, same labels, same backlog milestone, same D1-supersede / D2-D5-v2 framing, same goal-anchor treatment). Good signal that the v2 policy encodes the intended judgment.
  • v1 vs v2 policy delta on this exact thread: the v1 triage (11:30Z obotclaw comment) chose ASK with 3 questions; under v2's bias-to-promote, the same thread files directly, converting those three questions into Assumptions 1, 4, and 6. This thread is a clean demonstration of the intended behavior change.

9. Delegation record and reviewer edits

  • Research — general-purpose subagent on Sonnet 5 (read-only): #45 sections + D1–D5 verbatim, #75 reference, related-issue sweep, charts-goal anchor check. ~30.2k subagent tokens, 11 tool calls.
  • Drafting — subagent on Opus 4.8: both §6 artifacts from the orchestrator's classification and assumptions (not shown #75, to keep the draft an uncontaminated product of the fresh assessment). ~13.3k subagent tokens.
  • Orchestrator (Fable 5) — classification, assumptions, target choice, draft review. Reviewer edits applied to the drafts: (a) Artifact B "The orchestrator's assumptions are numbered…" → "The assumptions behind the filing are numbered…" (internal role name removed from user-facing text); (b) Artifact A Business Requirement third line rephrased to "The first ask is to see the UX…" (pronoun-free phrasing).

10. Policy issues flagged for @jwildfire (calibration findings)

  1. Section-count conflict (blocking before go-live): policy outcome 2 mandates six sections including ### Assumptions, but AGENTS.md §Creating Requirement issues and .github/ISSUE_TEMPLATE/requirement.yml mandate exactly five sections and prescribe a grep '^### ' verification that a six-section body fails ("downstream automation parses the five sections"). This report follows the policy (it deliberately adds Assumptions for the one-line-correction workflow), but one of the two documents needs an edit — either add Assumptions to the template/AGENTS.md, or move assumptions into a non-heading block. Note the live, reviewed #75 has five sections (no Assumptions heading).
  2. Attribution placement tension (minor): AGENTS.md asks for an attribution line above the first section heading; the policy mandates the exact attribution sentence at the end after a horizontal rule. The live #75 uses footer-only, so this report does too — worth one clarifying line in AGENTS.md.
  3. Dedup command in the policy is not runnable as written: gh search issues has no combined open+closed flag (--state all errors). The default (state-unfiltered) search does cover both states; the policy text "(open + closed)" should say that or give the exact command.
  4. gh issue view <n> --json body -q .body | grep '^### ' verification (AGENTS.md) will flag every triage-filed requirement while finding 1 stands — the workflow should not treat that failure as fatal until the conflict is resolved.

This was drafted by obot ideas-triage (Claude Code headless using Fable 5) — review by @jwildfire

#50 — Fable 5 report (run)

🧮 run cost: 241.1k tokens in / 15.1k out · ~$2.08 (Fable 5 orchestrator + subagents)

  • claude-haiku-4-5-20251001: 630 in / 18 out · $0.00
  • claude-fable-5: 12 in / 15.1k out · $1.70
  • claude-sonnet-5: 14 in / 7.5k out · $0.30
  • claude-opus-4-8: 4 in / 1.3k out · $0.08

DRY RUN — intended-actions report: discussion #50 "Goal Pages"

  • Run date: 2026-07-24 · Mode: dry-run fixture calibration per .github/ideas-triage-policy.md §Dry-run mode
  • Fixture rules applied: discussion assessed as fresh; its closed state (closed 2026-07-24T11:31Z) and existing promotion (#53) ignored for classification; NO mutations made (read-only throughout).
  • Orchestrator: Fable 5. Delegation per policy: thread/related-issue research → claude-sonnet-5 subagent; drafting → claude-opus-4-8 subagent. Classification, assumptions, target choice, and draft review done by the orchestrator.

Classification and chosen outcome

Outcome 2 — FILE REQUIREMENT: "Requirement: Goal pages in the hub"

Rationale:

  • The idea (posted by @jwildfire, Ideas category) is requirement-shaped: three coherent facets — (a) one hub page per goal listing associated roadmap items, (b) readiness tagging (auto-ready vs needs-steering), (c) a formal "goal" issue construct — that together need their own design and lifecycle. An in-session obot with the roadmap in context would start drafting this requirement, so per the bias-to-promote rule it is filed.
  • EXTEND EXISTING was considered and rejected: the idea consumes #71 (goal issues) and complements #57 (homepage Goals section) but continues neither — #71 supplies the data model, #57 the at-a-glance list; per-goal pages are new scope with their own generator and design questions.
  • FILE TASK rejected (not a small chore — new site surface plus label semantics plus goal linkage), ASK rejected (intent fully inferable; the author is the maintainer).
  • Later-comments check: the only thread comments are a triage nudge (ignored per policy) and the live promotion notice (ignored per fixture rules) — the opening post stands as the idea.
  • Calibration signal: this fresh assessment independently reproduces what the live v1 pipeline did (promotion to #53, same title), which suggests the disposition policy is stable on this fixture.

Intended actions (in order)

  1. Create issue "Requirement: Goal pages in the hub" with the body below.
  2. Labels: requirement, infrastructure. Assignee: jwildfire. Milestone: backlog (open design questions; not clearly near-term urgent — Assumption 7 invites correction to 2026q3).
  3. Board: attempt gh project item-add 1 --owner jwildfire --url <issue-url>; the context pack says the board is unavailable to this token, so expect the approved fallback — print "board add deferred to session wrapup" and continue.
  4. Append to /tmp/posted.jsonl: {"kind":"issue","number":<n>} (parsed from the create-command URL output).
  5. Post the discussion comment below on #50 via GraphQL addDiscussionComment (requesting comment { id }), then append {"kind":"discussion_comment","node_id":"<id>"} to /tmp/posted.jsonl.
  6. Close discussion #50 as resolved via the closeDiscussion mutation (reason RESOLVED). Discussion node id captured for this: D_kwDOTLuTVs4AoA15.

What I would close: discussion #50 only. No issues would be closed; no existing content edited or deleted; no reactions touched; exactly one discussion comment posted.

Drafted issue body (VERBATIM)

### Business Requirement

@jwildfire needs a per-goal view of the roadmap: for each standing goal, what the goal means, which requirements and tasks feed it, and which of those are ready for autonomous implementation versus waiting on his steering. Today that picture is scattered across individual issues, so there is no single place to see a goal's intent alongside the state of the work driving it. A per-goal view lets him steer the autonomy pipeline (#18) at a glance — deciding what can run on its own (`auto`) and what still needs his input (`draft`) — without reconstructing the mapping by hand each time.

### Overview

Generate one page per goal on the hub site. Each page summarizes the goal (intent, boundaries, and done-criteria drawn from the goal issue) and lists the goal's associated roadmap items grouped by readiness — items labeled `auto` (ready for autonomous implementation) separated from those labeled `draft` (awaiting steering). The pages build on the goal issues from #71, complement the homepage Goals section from #57 (which links out to each per-goal page), and extend the roadmap transparency work from #31. Pages are generated at deploy time from issue data, like the existing roadmap view.

### Assumptions

1. "Hub" means the deployed roadmap site (https://jwildfire.github.io/obot.roadmap/) — goal pages are generated at deploy time like roadmap.html, not committed markdown.
2. The canonical goal source is the hub goal issues from #71 (pilots #78/#79/#73/#72), not the obot.agent/goals files, so this requirement sequences after or alongside #71.
3. "Separate tags" means the existing `auto` and `draft` labels already in this repo — goal pages group each goal's items by those labels rather than introducing a new tag scheme.
4. The "new issue type of goal" facet is covered by #71's label + template + sub-issue approach (GitHub custom issue types are unavailable on user-owned repos), so no separate platform work is needed here.
5. "Associated items from roadmap" = each goal issue's native sub-issues plus the backlog repo feeds declared in its YAML frontmatter.
6. The homepage Goals section from #57 links to these per-goal pages — the at-a-glance list lives there, the per-goal detail lives here.
7. Milestone `backlog` until the design is scoped; correct if this should target 2026q3.

### Data Requirement

_To be populated during Requirement Gathering (Step 2)._

### Design

_To be populated before Tasks are created (Step 3)._

### Tasks

_To be populated before implementation begins._

Promoted from discussion #50: https://github.com/jwildfire/obot.roadmap/discussions/50

---
This was drafted by obot ideas-triage (Claude Code headless using Fable 5) — review by @jwildfire

Drafted discussion comment (VERBATIM)

Promoted this idea to a Requirement issue: https://github.com/jwildfire/obot.roadmap/issues/<NEW>

Where each bullet landed: the "one page per goal summarizing and listing associated items" bullet drives the Business Requirement and Overview; the "separate tags for auto vs steering-needed" bullet maps to grouping by the existing `auto`/`draft` labels (Assumption 3); and the "new goal issue type" bullet is captured as Assumption 4, noting it's already covered by #71's label + template + sub-issue approach.

---
This was drafted by obot ideas-triage (Claude Code headless using Fable 5) — review by @jwildfire

(<NEW> is a dry-run placeholder for the created issue number.)

Assumptions list

The seven numbered assumptions above (issue body §Assumptions), each phrased for a one-line correction from @jwildfire. Load-bearing ones: #2 (goal issues, not goal files, are canonical — depends on #71 landing), #3 (reuse auto/draft rather than mint new labels), #4 (no new issue-type work — #71 covers it).

Dedup search (gh search issues "discussions/50", open + closed):

  • #53 Requirement: Goal pages in the hub — the live promotion of this very discussion; ignored for classification per fixture rules. In live mode this hit plus the closed state would stop the run at sequence steps 1–2 with no action.
  • #58 Requirement: ideas-triage v2 — mentions discussions/50 as a calibration fixture; not a promotion.

Research (Sonnet subagent) related-issue map:

  • #71 goal issues — implements facet (c): goal label + planned .github/ISSUE_TEMPLATE/goal.yml + native sub-issues; pilots #78 (6 sub-issues), #79 (1 sub-issue), #73, #72 already live. Custom GitHub issue types confirmed unavailable on this user-owned repo (.issue_types → null).
  • #57 homepage refactor — homepage Goals section; its design doc explicitly notes goal pages "may become the source for the goals list if that lands first." Direct complement to facet (a).
  • #18 autonomous obot operations — origin of the goal concept and of the readiness distinction; the auto ("ready for autonomous implementation") and draft ("needs @jwildfire input/steering") labels already exist and are in use — facet (b) is substantially pre-built.
  • #31 roadmap transparency — shares the "roadmap reads live sub-issue signals" mechanism; tangential.
  • #24 session hub — adjacent transparency surface only; no direct overlap.
  • Site prior art: roadmap/metrics pages are generated at deploy time and never committed (scripts/build_roadmap.mjs etc.) — the natural pattern for goal pages (Assumption 1). No design doc exists yet for goal pages.

Calibration flags for @jwildfire

  1. Section-count conflict between binding documents. The triage policy mandates six sections (inserting ### Assumptions) while AGENTS.md mandates exactly the template's five ("never rename, reorder, add, or drop") and warns downstream automation parses them; AGENTS.md's own verify command (grep '^### ' must equal the five headings) would fail on every triage-lane requirement. I followed the lane policy (more specific, explicitly ordered for this outcome), but one of the two documents should be amended — e.g. AGENTS.md gains a triage-lane carve-out, or the parser learns to skip ### Assumptions.
  2. Attribution-placement conflict. AGENTS.md puts the attribution line above the first section heading; the triage policy puts its drafted-by footer at the end after a horizontal rule. I followed the policy footer (matches the live #53 promotion). Worth harmonizing.
  3. Fixture agrees with live v1. Fresh v2 assessment reproduces the live v1 outcome (same disposition, same title as #53) while adding the Assumptions section and tighter cross-links (auto/draft reuse, #71 dependency) — the intended v2 uplift, no disposition drift.
  4. Facet (b) and (c) are already partly built (auto/draft labels live; goal issues piloted). If #53's real design hasn't absorbed that yet, the assumptions above are the delta worth porting to it.

Delegation record

  • Research: claude-sonnet-5 subagent (thread context, #71/#57/#18/#31/#24/#78/#79/#73/#72 digests, label inventory, site prior art, issue-type check) — ~45k tokens, 25 tool uses.
  • Drafting: claude-opus-4-8 subagent (issue body + discussion comment from the orchestrator's classification and assumption list) — ~13k tokens.
  • Orchestrator (Fable 5): classification, assumption calls, target choice, draft review, this report.

This was drafted by obot ideas-triage (Claude Code headless using Fable 5) — review by @jwildfire

#51 — Fable 5 report (run)

🧮 run cost: 241.1k tokens in / 13.1k out · ~$1.87 (Fable 5 orchestrator + subagents)

  • claude-haiku-4-5-20251001: 630 in / 18 out · $0.00
  • claude-fable-5: 11 in / 13.1k out · $1.59
  • claude-sonnet-5: 8 in / 4.9k out · $0.18
  • claude-opus-4-8: 2 in / 1.3k out · $0.10

DRY RUN — ideas-triage v2 intended-actions report

  • Run date: 2026-07-24 · Trigger: dry-run calibration, discussion #51 (fixture mode)
  • Policy: .github/ideas-triage-policy.md (v2) · Context pack: /tmp/context-pack.md (2026-07-24T13:42:34Z)
  • Mutations made: NONE (read-only token; fixture mode honored)

Thread digest — discussion #51 "Keynote Demo idea"

  • Author @jwildfire, category Ideas, created 2026-07-24T11:19Z. Body: "Share a link that allows people to post ideas here at the start of the keynote. Have obot implement during the talk and i'll demo a few at the end of the talk."
  • Comment 1 (jwildfire, 11:25Z): triage nudge — ignored per policy (nudge/notice).
  • Comment 2 (obotclaw, 11:30Z): the v1 lane's ASK comment (3 questions, no answer from @jwildfire) — treated as historical snapshot.
  • Comment 3 (obotclaw, 13:23Z): live promotion to #74 + close — ignored per dry-run fixture rules, as is the discussion's closed state (closed 13:23Z).

Dedup search (live sequence step 2)

gh search issues --repo jwildfire/obot.roadmap "discussions/51" → #74 (the existing promotion), #72 (goal: keynote deck), #58 (ideas-triage v2). In a live run this would trigger the stop-or-status-reply rule; in fixture mode the assessment proceeds fresh.

Classification (Fable decision)

Outcome 2 — FILE REQUIREMENT. Confidence: high.

  • Requirement-shaped, not a chore: clear business why (make the keynote's AI-closes-the-loop thesis tangible) and an inferable technical approach via existing machinery. Under bias-to-promote, an in-session obot would start drafting — so file.
  • Not EXTEND EXISTING: #10 (keynote deck) is scoped to the slide deck; #48 (idea queue) is the intake pipeline this reuses but the live-demo machinery (moderation, demo-safe selection, live-run orchestration, rehearsal) goes well beyond intake; #72 is a goal issue, not a requirement. Scope warrants its own thread rather than a comment on any of these.
  • Not ASK: the v1 lane asked 3 questions here and got no reply. With the context pack (keynote = R/Pharma 2026 #10/#72; intake pipeline #48 live; autonomy framework #18 merged) intent is fully inferable — under v2 policy ASK is not permitted for this thread, and the v1 questions become Assumptions 1–3 below.
# Title Relevance
#10 R/Pharma 2026 AI keynote deck (open, 2026q4) The talk this demo lives in; deck repo is separate
#72 Goal: R/Pharma 2026 keynote deck (open) Parent goal; its body already anticipates this demo as a candidate child
#48 Idea queue — Discussions intake + obot triage (open) The intake pipeline the audience link reuses
#18 Autonomous obot operations (open) Autonomy framework any live unattended run needs
#24 Session hub — live dashboard (open) Likely "what's on screen while obot works" surface; its design doc names keynote material
#22 Developer-diary blog series (open, 2026q4) Companion narrative; source material for the deck
#58 ideas-triage v2 (open, draft) The triage mechanism itself; #74 cites it
#74 Keynote live demo (open, draft, backlog) Existing live promotion of this same discussion — ignored for the decision, see calibration notes

Prior art: no demo-mode/audience-interaction tooling exists anywhere in the repo; the concept appears only in #74's own Design section. 18_design.html (supervised overnight runs) is the closest precedent for unattended execution.

Intended actions (would execute in a live run — NOT executed)

  1. Create issue — title: Requirement: keynote live demo — audience ideas implemented during the talk
    • Labels: requirement, ai · Assignee: jwildfire · Milestone: backlog (keynote is 2026q4; policy's near-term escalation is 2026q3-only, so default applies)
    • Body: verbatim in Artifact 1 below.
    • Record {"kind":"issue","number":<n>} to /tmp/posted.jsonl.
  2. Board add — attempt gh project item-add 1 --owner jwildfire --url <issue-url>; context pack says the token lacks ProjectsV2, so expected output: "board add deferred to session wrapup" (approved fallback).
  3. Post ONE discussion comment on #51 via addDiscussionComment (requesting comment { id }), body verbatim in Artifact 2 with <NEW-ISSUE-URL> substituted. Record {"kind":"discussion_comment","node_id":"<id>"} to /tmp/posted.jsonl.
  4. Close discussion #51 as resolved via closeDiscussion mutation, reason RESOLVED.

Nothing would be edited or deleted; no reactions touched.

Artifact 1 — issue body (VERBATIM)

Business Requirement

The R/Pharma 2026 AI keynote (deck requirement #10) argues that AI can close the loop from roadmap idea to shipped code; this demo makes that thesis tangible by having the audience post ideas at the start of the talk and watching obot triage and implement real changes live, so the claim lands as a demonstration rather than a slide.

Overview

Audience members open a shared link and post ideas into the Discussions "Ideas" category; obot picks them up through the existing idea queue and, during the talk, triages and implements a selected few, with results demoed at the end. Building blocks: the existing Ideas pipeline (idea queue #48: "Ideas" category + ideas-triage Action) for intake and triage, the autonomy framework (#18, obotclaw identity and autonomy grants) for unattended live runs, the session hub (#24) as the on-screen "what obot is doing now" surface, all rolling up to parent goal #72 and in service of deck #10.

Assumptions

  1. "Implement" means real code — obot produces draft PRs and deployed results live during the talk, not just triage-to-requirement-issue.
  2. Targets are chosen per idea for demo-safety — most likely safety.viz gallery/site tweaks or small hub changes; no fixed single repo.
  3. The keynote in question is the R/Pharma 2026 AI keynote (#10), so this lands ahead of that talk (2026q4).
  4. Audience intake reuses the existing Ideas pipeline (#48) via a shared pre-filled "new Ideas discussion" link — no new intake system.
  5. The tooling is reusable demo-mode machinery (rehearsable before the talk), not a one-off manual walkthrough.
  6. Live implementation runs operate under the #18 autonomy framework with the obotclaw identity, with moderation/rate-limiting on the public link designed before the talk.

Data Requirement

Not applicable in the usual clinical-data sense — there is no clinical source data; inputs are audience-authored discussion posts.

Design

TBD — to be populated during Design. Open questions worth deciding early:

  • Moderation and rate limiting on a broadcast public link.
  • Demo-safe idea selection heuristics.
  • What's on screen while obot works (likely #24 session hub).
  • Fallback / pre-seeded ideas if the audience is quiet.
  • Rehearsal plan.
  • Compute and identity for live runs.

Tasks

To be populated after Design.

Parent goal: #72.

Promoted from discussion #51: https://github.com/jwildfire/obot.roadmap/discussions/51


This was drafted by obot ideas-triage (Claude Code headless using Fable 5) — review by @jwildfire

Artifact 2 — discussion comment on #51 (VERBATIM; <NEW-ISSUE-URL> substituted live)

Promoted this idea to a tracked requirement:

I took a few assumptions to move it forward — chiefly that "implement" means real live draft PRs/deploys during the talk, intake reuses the existing Ideas pipeline (#48), and runs happen under the #18 autonomy framework as obotclaw; the full list is in the issue's Assumptions section, each phrased so you can correct it with a one-line reply.

This rolls up to parent goal #72, tied to the R/Pharma 2026 AI keynote deck (#10).

Closing this discussion as resolved now that it's tracked in the issue.


This was drafted by obot ideas-triage (Claude Code headless using Fable 5) — review by @jwildfire

Delegation record

  • Research: 1 subagent on claude-sonnet-5 (related issues, #74 comparison, prior-art sweep) — ~37k tokens.
  • Drafting: 1 subagent on claude-opus-4-8 (issue body + discussion comment from the fixed classification) — ~12k tokens. One stray preamble line stripped in orchestrator review; otherwise accepted as drafted.
  • Fable (orchestrator) retained: classification, assumptions, target choice, draft review, report authorship.

Calibration notes for @jwildfire

  1. Convergence with the live run: this fresh assessment lands on essentially the same outcome as the real promotion (#74) — same title, same core assumptions, backlog + requirement/ai — which suggests the v2 policy is well calibrated for this fixture. Differences: v2 adds an explicit ### Assumptions section in-body (v1 put assumptions in the closing comment), and #74 additionally carries the draft label, which the policy never mentions — consider adding "apply draft when Design is TBD" if that's intended practice.
  2. Section-order conflict: policy outcome 2 mandates six sections including ### Assumptions, but AGENTS.md + requirement.yml mandate exactly five sections ("never add a section") and warn that parsers break silently. #74 as filed has five sections (assumptions in prose). One of the two rules should be amended before v2 goes live.
  3. Attribution conflict (minor): AGENTS.md wants an attribution line above the first section heading; the policy hard guard wants the exact footer at the end. This report follows the policy footer only. Clarify whether both are required for issues.
  4. Sub-issue linking: #72's body claims the live demo is "linked as a sub-issue," but no structured sub-issue link exists (#74 → #72 is body text only). If real sub-issue links are wanted, the policy's outcome 1/2 should say so explicitly and name the API.
#52 — Fable 5 report (run)

🧮 run cost: 286.1k tokens in / 15.2k out · ~$2.07 (Fable 5 orchestrator + subagents)

  • claude-haiku-4-5-20251001: 630 in / 18 out · $0.00
  • claude-fable-5: 13 in / 15.2k out · $1.80
  • claude-sonnet-5: 8 in / 8.9k out · $0.21
  • claude-opus-4-8: 2 in / 1.2k out · $0.06

DRY RUN report — ideas-triage v2 calibration — discussion #52

Run date: 2026-07-24. Fixture mode per .github/ideas-triage-policy.md §Dry-run: discussion assessed as fresh — its closed state and the existing historical promotion (issue #72) were ignored for classification but are listed under Related issues. NO mutations were made; the report below is everything the live lane would have done.

Input

  • Discussion: #52 "New Goal: Keynote deck", category Ideas, author @jwildfire, opened 2026-07-24T11:21:44Z.
  • Body: "Make a new goal around creating my keynote deck"
  • Thread comments (all ignored for disposition per policy): a 🔔 triage nudge (nudge/notice — ignored by rule), an obotclaw ASK comment from the v1 Sonnet lane, and the historical promotion/close comment (excluded as fixture).
  • Discussion GraphQL id: D_kwDOTLuTVs4AoA3r (would be used for the closeDiscussion mutation).

Delegation trace (per policy §Role and delegation)

  • Research subagent on Sonnet: digested #10, #74, #22, #71, #73, #78, #79; characterized the goal-issue body convention; swept keynote prior art (gh search issues ... keynote, open + closed).
  • Drafting subagent on Opus: drafted the goal-issue body and discussion comment from the orchestrator's classification decision.
  • Fable (orchestrator) personally: classification, assumptions, target choice, draft review, this report.

Classification: FILE TASK (outcome 3) — file a pilot goal issue

The idea is not a bare title — intent is fully inferable, so ASK is wrong (the v1 lane's historical ASK comment on this thread is exactly the behavior the v2 bias-to-promote replaces). Decisive evidence:

  • Requirement #71 (goal issues) states verbatim in its body: "Two pilot goal issues are being filed in the same sweep (from discussions #52 and #54) ahead of the template; retrofit them once it lands." — this discussion was already earmarked to become a pilot goal issue, sibling to #73 (from #54).
  • Requirement #74's footer already declares "Parent goal: … (R/Pharma 2026 keynote deck)" — the parent layer this idea asks for.
  • A keynote requirement cluster already exists: #10 (deck build, 2026q4), #74 (live demo, draft), #22 (developer diary) — they read as children awaiting an umbrella goal.

Outcomes considered and rejected:

  • EXTEND EXISTING (#10 or #71) — rejected: the idea does not continue #10's scope (the deck build); it asks for a distinct parent artifact above #10/#74/#22. A comment or sub-issue on an existing requirement cannot produce that; goal issues parent requirements, not the reverse.
  • FILE REQUIREMENT — rejected: a goal is a distinct artifact kind in this repo (goal label, standing-issue semantics per #73/#78/#79); filing the five-section requirement template would duplicate #10.
  • ASK — rejected: everything needed (which keynote, which children, which convention) is in the context pack and open issues.

Mapping note for calibration: the policy's outcome 3 wording is "small concrete chore, fix, or tweak" — a goal issue is not literally a chore, but it is the outcome that fits (plain issue, no requirement label, short body, origin link). If goal-issue filings become common, the policy may want an explicit goal-issue clause under outcome 3.

Intended actions, in order (none executed)

  1. Create issue titled Goal: R/Pharma 2026 keynote deck with the body below.
    • Labels: goal, ai. No requirement label (outcome 3). Assignee: jwildfire. Milestone: backlog (matching sibling pilot #73; the keynote itself is 2026q4, not clearly near-term urgent per the 2026q3 test).
    • Record to /tmp/posted.jsonl: {"kind":"issue","number":<n>}.
  2. Attempt gh project item-add 1 --owner jwildfire --url <issue-url>; on failure (token lacks ProjectsV2 — expected per context pack) print "board add deferred to session wrapup" and continue.
  3. Link existing children as sub-issues of the new goal issue: #10, #74, #22 (per the goal-issue Membership convention).
  4. Post ONE discussion comment on #52 with the body below, via the addDiscussionComment mutation requesting comment { id }.
    • Record to /tmp/posted.jsonl: {"kind":"discussion_comment","node_id":"<graphql-id>"}.
  5. Close discussion #52 as resolved via closeDiscussion (reason RESOLVED, id D_kwDOTLuTVs4AoA3r).

Drafted artifact 1 — goal issue (VERBATIM)

Title: Goal: R/Pharma 2026 keynote deck

Body:

Standing goal — this issue stays open; closing it = retiring the goal. Direction and membership are maintained by @jwildfire; autonomous sessions propose changes as comments and never edit this issue or its sub-issue links.

```yaml
slug: keynote
anchors:
  - jwildfire/obot.roadmap#10   # R/Pharma 2026 AI keynote deck (the deck build)
  - jwildfire/obot.roadmap#74   # keynote live demo — audience ideas implemented during the talk
  - jwildfire/obot.roadmap#22   # developer-diary blog series (public narrative companion)
backlog:
  - jwildfire/RPharma2026-AIKeynote   # external deck repo — implementation backlog
```

Not yet in `obot.agent/goals/registry.json` — not selectable by `--auto` until @jwildfire adds a registry entry (policy-file carve-out).

### Goal

Deliver the AI keynote at R/Pharma 2026 — this goal covers everything that has to be true by the day of the talk, not just the deck build.

The deck itself covers open-source safety tooling, GSM, agentic engineering, and autonomous AI workers (per #10), but the goal is the umbrella above the whole requirement cluster — #10 (deck), #74 (live demo), and #22 (developer diary).

Standing this goal up gives #74's "Parent goal" footer a real target and feeds the goal pages (#53) and the homepage Goals section (#57).

### Scope and boundaries

- Deck implementation lives in the external `RPharma2026-AIKeynote` repo (release-per-slide, HTML-first); this goal tracks direction, not build detail.
- #10 is pre-design — anchor increments are pipeline-advancement (draft artifacts, ending at @jwildfire review) until its Design lands.
- The live demo (#74) is `draft` and needs @jwildfire steering before implementation begins.
- Done = keynote delivered at R/Pharma 2026, after which the goal retires by closing this issue.

### Candidate children

- Existing, to link as sub-issues: #10 (deck build), #74 (live demo), #22 (developer diary).
- Future candidate (unfiled): deck outline / narrative arc.
- Future candidate (unfiled): rehearsal + timing dry-run.
- Future candidate (unfiled): post-talk publication of the deck.

### Notes

- Pilot goal issue filed ahead of the goal template — #71 (goal issues requirement) explicitly plans this promotion from discussion #52 and will retrofit it once the template lands.
- Sibling pilot to #73 (promoted from discussion #54).

Promoted from discussion #52: https://github.com/jwildfire/obot.roadmap/discussions/52

---
This was drafted by obot ideas-triage (Claude Code headless using Fable 5) — review by @jwildfire

Drafted artifact 2 — discussion comment on #52 (VERBATIM; #<new> = the created issue's number)

Promoted → goal issue #<new> — Goal: R/Pharma 2026 keynote deck.

Anchors #10 (deck build), #74 (live demo), and #22 (developer diary) under a single standing goal.

This is a pilot goal issue filed ahead of the #71 goal template (sibling to #73) and will be retrofitted once the template lands.

Closing this discussion as resolved.

---
This was drafted by obot ideas-triage (Claude Code headless using Fable 5) — review by @jwildfire

Assumptions (each correctable with a one-line comment)

  1. "My keynote deck" means the R/Pharma 2026 AI keynote (#10) — the only keynote in the portfolio; no other keynote prior art exists.
  2. The goal should be a hub goal issue in the #73/#78/#79 pilot convention (per #71's stated plan for discussion #52), not a new obot.agent/goals/*.md file.
  3. Anchors are #10, #74, #22 in that priority order, with the external jwildfire/RPharma2026-AIKeynote repo as the sole backlog feed.
  4. Goal slug is keynote.
  5. Labels goal + ai and milestone backlog, matching sibling pilot #73 (the 2026q4 keynote date is not "clearly near-term urgent" under the policy's 2026q3 test).
  6. The goal is intentionally NOT added to obot.agent/goals/registry.json--auto selectability is @jwildfire's registry click, under the policy-file carve-out.
  7. Scope is "deliver the keynote," broader than the literal "creating my keynote deck" wording — the deck build stays scoped in #10; the goal wraps demo, diary, and rehearsal too.
  8. The lane attribution line ("This was drafted by obot ideas-triage … — review by @jwildfire") supersedes the AGENTS.md "reviewed by" line for this unreviewed bot filing — the policy hard guard specifies it for every lane artifact.
  • #72 Goal: R/Pharma 2026 keynote deck (open) — the ACTUAL historical promotion of this discussion (dedup search hit for "discussions/52"), excluded from classification per dry-run fixture rules. Calibration signal: the fresh assessment independently converges on the same outcome, title, and anchor set as the live 2026-07-24 promotion (which was Fable-drafted and @jwildfire-reviewed).
  • #71 Requirement: goal issues (open) — names discussion #52 as a planned pilot goal issue; will retrofit the filed issue once the goal template lands.
  • #10 Requirement: R/Pharma 2026 AI keynote deck (open, 2026q4) — primary anchor; the deck build itself.
  • #74 Requirement: keynote live demo (open, draft, backlog) — anchor; already carries a "Parent goal" footer pointing at the keynote goal.
  • #22 Requirement: developer-diary blog series (open, 2026q4) — anchor; explicit public-narrative companion to #10.
  • #73 Goal: increased autonomy in obot.agent (open) — the sibling pilot goal issue (from discussion #54) whose body convention this draft follows.
  • #78 / #79 Goals G1/G2 (open) — the migrated goal issues establishing the standing-goal preamble + yaml convention.
  • #58 Requirement: ideas-triage v2 (open) — hit the dedup search only because its own body references this discussion; not a promotion.
  • Keyword sweep ("keynote", open + closed): #76, #34, #30, #18, #31, #24, #57, #28, #17, #1, #7 matched on incidental mentions only — no additional dedicated keynote artifacts.

What I would close

  • Discussion #52 — closed as resolved (closeDiscussion, reason RESOLVED) immediately after posting the one linking comment.
  • No issues would be closed. The new goal issue stays open by definition (closing a goal issue = retiring the goal).

/tmp/posted.jsonl records that would be appended

{"kind":"issue","number":<n>}
{"kind":"discussion_comment","node_id":"<addDiscussionComment comment.id>"}

This was drafted by obot ideas-triage (Claude Code headless using Fable 5) — review by @jwildfire

#54 — Fable 5 report (run)

🧮 run cost: 276.1k tokens in / 17.4k out · ~$2.04 (Fable 5 orchestrator + subagents)

  • claude-haiku-4-5-20251001: 630 in / 18 out · $0.00
  • claude-fable-5: 13 in / 17.4k out · $1.86
  • claude-sonnet-5: 4 in / 4.0k out · $0.11
  • claude-opus-4-8: 2 in / 1.5k out · $0.07

DRY RUN — ideas-triage v2 calibration report

  • Fixture: discussion #54 — "Goal: Support increased autonomy in obot.agent" (https://github.com/jwildfire/obot.roadmap/discussions/54)
  • Mode: dry-run per .github/ideas-triage-policy.md §Dry-run mode. Fresh assessment; closed state (2026-07-24T13:23Z) and existing promotion (#73) ignored as historical snapshot. No mutations were made.
  • Run date: 2026-07-24. Orchestrator: Fable 5. Report for @jwildfire's policy calibration.

Thread as assessed

  • Opening post (@jwildfire, 2026-07-24T11:41Z): title "Goal: Support increased autonomy in obot.agent", body "Add a new goal around increased autonomy for obot.agent". Category: Ideas. No labels.
  • Comment 1 (obotclaw, v1 triage on Sonnet 5): chose ASK — 3 questions, never answered in-thread. Treated as an ignorable bot notice comment per policy.
  • Comment 2 (obotclaw): the live promotion note (→ #73). Ignored per dry-run fixture rules.
  • Effective input for classification: title + one-line body + context pack. No user follow-up comments override the opening post.

Classification and chosen outcome

FILE — a standing goal issue (mechanically outcome 3, plain issue — see calibration notes below).

  • The idea is goal-shaped, not requirement-shaped: #71 (open requirement) establishes hub "goal issues" as a distinct kind (goal label + dedicated template, parents of requirement issues), and pilots #78 (G1 charts) / #79 (G2 app) define the exact house format. An in-session obot with this context would start drafting the goal issue immediately → the bias-to-promote rule of thumb says FILE.
  • Not ASK (v1's choice): with the context pack, intent is fully inferable — the autonomy arc (#18/#58/#61/#46) is in flight and the goals framework tells us exactly what "add a new goal" means and what the artifact looks like. Every one of v1's three questions is answerable from context (answers are Assumptions 3, 4, and 6 below).
  • Not EXTEND #18: the goal is the standing umbrella above #18, not a continuation of #18's scope (scheduled/event-driven runs). A comment on #18 would bury a direction-setting artifact inside one of its own children.
  • Not FILE REQUIREMENT: goal issues are explicitly a distinct template from requirements per #71; forcing the six-section requirement skeleton onto this would fight the established convention.

Intended actions (in order)

  1. Create the issue below via gh api repos/jwildfire/obot.roadmap/issues — record {"kind":"issue","number":<n>} to /tmp/posted.jsonl.
  2. Labels: goal + ai. Assignee: jwildfire. Milestone: none (standing-goal convention of #78/#79; deliberate deviation from the backlog default — see calibration notes).
  3. Sub-issue links: attempt to link hub-resident anchors (#18, #58, #61, #46) as sub-issues of the new goal per #71's membership model; if that write is outside the triage token's scope or the relationship API rejects, defer to session wrapup and say so in the run output (mirroring the approved board fallback).
  4. Board: gh project item-add 1 --owner jwildfire --url <issue-url> — context pack already says the board is unavailable to this token, so expected output: "board add deferred to session wrapup".
  5. Post the discussion comment below via the addDiscussionComment mutation (discussion id D_kwDOTLuTVs4AoA46), requesting comment { id } — record {"kind":"discussion_comment","node_id":"<id>"}.
  6. Close discussion #54 as resolved via closeDiscussion (reason RESOLVED). That is the only thing this run would close; the goal issue itself stays open by definition (closing a goal issue = retiring the goal).

Drafted issue (verbatim)

Title: Goal: G3 — increased autonomy in obot.agent

Body:

Standing goal — this issue stays open; closing it = retiring the goal. Direction and membership are maintained by @jwildfire; autonomous sessions propose changes as comments and never edit this issue or its sub-issue links.

```yaml
slug: autonomy
anchors:
  - jwildfire/obot.roadmap#18
  - jwildfire/obot.roadmap#58
  - jwildfire/obot.roadmap#61
  - jwildfire/obot.roadmap#46
backlog:
  - jwildfire/obot.agent

Policy binding (active/paused status, grant profile) intentionally lives outside this issue, in obot.agent/goals/registry.json under the policy-file carve-out.

Intent

obot.agent should operate with progressively less human-in-the-loop supervision — the umbrella direction over the autonomy arc already in flight: #18 shipped the --auto core (goals layer, obot-auto, autonomy grants at A1, merge-policy tiers; maiden A1 run unblocked 2026-07-24), #58/#61 harden the ideas-triage lane, #46 put Remote Control on every agent session. Future sub-scopes (grant-matrix expansion, A1→A2 promotion criteria, scheduled runs, a /goal command) are filed as child requirements under this goal as they clarify.

Boundaries and weights for a selecting session

  • The operating contract does not move under this goal — merge gates, the policy-file carve-out (merge-policy.json, autonomy-grants.json, hooks, goals/), no unattended closes of hub Requirement issues, and deletion-needs-approval all stay fixed; loosening any of them is its own reviewed requirement, never a selected increment.
  • Autonomy-level promotions (A1 → A2) are explicit reviewed config changes by @jwildfire, never selected autonomously.
  • Anchor requirements still in lifecycle (design unsigned, sub-issues unfiled) yield pipeline-advancement increments (draft, end at review), not implementation increments.
  • New autonomy ideas found mid-run are filed, never built — roadmap-first.

Membership

Anchors (priority order) are linked as sub-issues and listed in the YAML block above; the sub-issue list also carries hub-resident backlog items. Repo-level backlog feeds (e.g. jwildfire/obot.agent) can't be sub-issues and live in the YAML block only.

Assumptions

  1. "Goal" here means a hub goal issue per #71's direction (pilot format #78/#79), not a new obot.agent/goals/*.md file — the file-based path is being retired.
  2. Numbering continues the pilot series (G1 charts, G2 app → G3 autonomy); slug autonomy.
  3. The anchor set is the autonomy arc in flight — #18, #58, #61, #46 in that priority order — with the jwildfire/obot.agent issue backlog as the secondary feed.
  4. This is an umbrella goal that spawns child requirements as sub-scopes clarify, not a single requirement to implement.
  5. No milestone, per the standing-goal convention of #78/#79 (overriding the triage default of backlog).
  6. The operating contract itself is out of scope — this goal grows autonomy within it.

Promoted from discussion #54: https://github.com/jwildfire/obot.roadmap/discussions/54


This was drafted by obot ideas-triage (Claude Code headless using Fable 5) — review by @jwildfire


## Drafted discussion comment (verbatim)

```markdown
Promoted to a standing goal issue: #<pending — assigned at creation>. It's an umbrella goal for increased autonomy in obot.agent, sitting over the arc already in flight (#18/#58/#61/#46), with child requirements filed as sub-scopes clarify. See the Assumptions list on the issue — each line is phrased so you can correct it with a one-line comment. Closing this discussion as resolved.

---
This was drafted by obot ideas-triage (Claude Code headless using Fable 5) — review by @jwildfire

Assumptions list

The six numbered assumptions above (issue body §Assumptions) — each one-line-correctable. The load-bearing ones: #1 (hub issue, not goals/ file), #3 (anchor set and order), #5 (no milestone).

  • Dedup search (gh search issues "discussions/54", open + closed): #73 "Goal: increased autonomy in obot.agent" (the live promotion — ignored per fixture rules; its body was deliberately not read so this assessment stayed fresh), #71 (goal issues requirement), #58 (this triage lane). No closed matches.
  • Context-pack relatives used in classification: #18, #46, #58, #61 (the autonomy arc → anchors); #71 + pilots #78/#79 (goal-issue format); #48 (this pipeline's parent).

What would be closed

  • Discussion #54, as resolved (closeDiscussion, reason RESOLVED), after the single discussion comment. Nothing else.

/tmp/posted.jsonl — intended records

{"kind":"issue","number":<new goal issue>}
{"kind":"discussion_comment","node_id":"<from addDiscussionComment>"}

Delegation record

  • Research → claude-sonnet-5 subagent: digested #78/#79 (goal-issue format, exemplar body), #71 (goal-issue spec), #18 (autonomy state). ~26k tokens.
  • Drafting → claude-opus-4-8 subagent: issue body + discussion comment from my fixed skeleton. ~13k tokens.
  • Kept with Fable per policy: classification, assumption calls, target choice, draft review, this report.

Calibration notes for @jwildfire

  1. The four-outcome taxonomy has no slot for goal issues. This idea is the second goal-shaped Idea (after the live #54 itself); I mapped it to outcome 3 mechanics (plain issue) with the #71 template. Consider adding an explicit outcome 2b ("FILE GOAL — goal-shaped idea → goal issue per #71 template") to the policy.
  2. Milestone default conflicts with the goal convention. Policy says backlog by default; #78/#79 carry no milestone because goals are standing. I chose the convention over the policy default — confirm or correct.
  3. Labels: policy's topical set (safety/infrastructure/ai) — I added ai alongside goal; the pilots carry only goal. Pick one convention.
  4. Assumptions section on a goal issue is an addition to the #78/#79 template (they were filed pre-reviewed). For triage-promoted goals it seems worth keeping so your one-line corrections land before the body is treated as jwildfire-maintained — confirm.
  5. Sub-issue linking by the triage bot (step 3) brushes against "never edit existing content" — linking #18 as a sub-issue modifies #18's relationships. If you'd rather triage never touches relationships, the fallback is YAML-only + defer links to session wrapup; say which.
  6. v1 vs v2 on this fixture: v1 (Sonnet, no context pack) reasonably chose ASK; v2's context pack alone flips it to FILE — the calibration point the dry run was built to test. For what it's worth, the fresh v2 outcome converges with what you and the live session actually did (goal issue #73), diverging only in the G3-numbered title and the added Assumptions section.
#55 — Fable 5 report (run)

🧮 run cost: 244.3k tokens in / 14.8k out · ~$1.96 (Fable 5 orchestrator + subagents)

  • claude-haiku-4-5-20251001: 630 in / 17 out · $0.00
  • claude-fable-5: 1.0k in / 14.8k out · $1.72
  • claude-sonnet-5: 8 in / 5.0k out · $0.17
  • claude-opus-4-8: 2 in / 1.6k out · $0.07

DRY RUN report — ideas-triage v2 calibration — discussion #55

Run date: 2026-07-24. Fixture: discussion #55 "Create 'goal' issue type in roadmap" (author @jwildfire, category Ideas). Per dry-run policy the closed state (closed 2026-07-24T13:23Z) and the existing promotion were ignored; the thread was assessed fresh. No mutations were made.

Delegation record

  • Research (thread-related issues, dedup, platform check): delegated to a claude-sonnet-5 subagent. ✓
  • Drafting (issue body + discussion comment): delegated to a claude-opus-4-8 subagent. ✓
  • Classification, assumptions, target choice, draft review: Fable (orchestrator). ✓

Thread digest

Opening post: move goals out of markdown files into GitHub issues with a new type = goal and a new template. Later comments (binding, they override the opening post): a prior obotclaw ASK round got three answers from @jwildfire — (1) yes, this supersedes design #18 decision O2; (2) nothing changed since O2, just iteration; (3) a new issue type with a new template, distinct from the requirement template, and goal issues will typically parent requirement issues. The 🔔 nudge comment was ignored per policy. The final "Promoted → #71" comment was ignored per dry-run rules.

Classification and chosen outcome

Outcome 2 — FILE REQUIREMENT. The idea is requirement-shaped: a scoped structural change (goal storage moves repos and representation) with confirmed intent, multiple affected consumers (scripts/obot-auto, session-init --auto), a migration, and a design decision to carry (the O2 edit-control carve-out).

  • Not EXTEND EXISTING: #53 (Goal pages) is adjacent — this idea answers #53's open question about a formal goal type — but the storage migration and machinery switch are their own scope, not a continuation of #53's page-rendering scope. #18 is the source of the superseded decision, not a thread this extends.
  • Not ASK: intent is fully inferable — indeed already confirmed in-thread by the author.

Target: new issue, title "Requirement: goal issues — goals move from obot.agent files to hub issues".

Dedup check (live-mode step 2 result, recorded for calibration)

gh search issues "discussions/55" finds #71 (open) — a direct promotion of this exact discussion. In a live run the sequence would have stopped at step 2 without acting (newest comment does not ask about status). The rest of this report is the dry-run fixture assessment as instructed. Calibration signal: the fresh assessment below converged with the real promotion #71 on classification, title, the org-only issue-type wrinkle, sub-issue parenting, migration + consumer-switch scope, labels, and milestone — the policy reproduces the reviewed outcome from scratch.

  • #71 (open, requirement+infrastructure, backlog) — the actual promotion of this discussion; direct duplicate of what this dry run would file. Ignored as a promotion, listed as a fact.
  • #53 Goal pages in the hub (open, backlog) — left "do goals need a formal issue type?" open; this requirement resolves it.
  • #18 autonomous obot operations (open, 2026q3) — source of decision O2 (design §7, 2026-07-22) being superseded.
  • #57 Roadmap homepage refactor (open, backlog) — homepage Goals section; coordinate.
  • #72 / #73 pilot goal issues (open, goal label) — filed ahead of the template from Ideas #52/#54; carry "retrofit under #71" notes.
  • #78 / #79 G1/G2 goal issues (open, goal label) — already migrated from goals/charts.md / goals/app.md. ⚠️ Their footers cite #53 as the migration authority rather than #71 — a citation inconsistency worth a human look.
  • A goal label already exists (FBCA04, "Standing goal — parent of requirement issues") and is applied to #72/#73/#78/#79.
  • Platform check: gh api users/jwildfire → type User; GitHub-native custom issue types are organization-only, so the native type is unavailable on this repo.

Intended actions (none executed)

  1. Create the requirement issue with the body below: labels requirement + infrastructure, assignee jwildfire, milestone backlog (iteration, not near-term urgent).
  2. Append {"kind":"issue","number":<NEW>} to /tmp/posted.jsonl.
  3. Attempt gh project item-add 1 --owner jwildfire --url <issue-url>; the token lacks ProjectsV2 (per context pack), so expected output: "board add deferred to session wrapup", then continue.
  4. Post the one discussion comment below on #55 via addDiscussionComment (requesting comment { id }), append {"kind":"discussion_comment","node_id":"<id>"} to /tmp/posted.jsonl.
  5. Close discussion #55 via the closeDiscussion mutation, reason RESOLVED.

What would close: discussion #55 (as resolved). Nothing else — no issues would be closed.

Assumptions list (as filed in the issue body)

  1. GitHub-native custom issue types are org-only and this is a user-owned repo, so "type = goal" is a goal label plus a dedicated issue form (.github/ISSUE_TEMPLATE/goal.yml) unless/until the hub moves to an org.
  2. Both existing goal files (G1 goals/charts.md, G2 goals/app.md) are migrated into goal issues, carrying the frontmatter semantics (status, anchors, backlog, grant_profile) into the issue.
  3. Consumers scripts/obot-auto and session-init --auto switch to reading goal issues instead of files; until that switch lands, the files remain the runnable source of truth.
  4. Goal-to-requirement parenting uses GitHub sub-issue links, which also answers #53's open "do goals need a formal type" question in the affirmative.
  5. The O2 "goal edits always wait for @jwildfire" carve-out survives the move in some equivalent form (e.g. only @jwildfire edits goal issues, or --auto never consumes a goal it edited itself) — an open design decision, not decided at filing.
  6. After migration the obot.agent/goals/ directory is retired; since deletion needs explicit approval, that is a task gated on @jwildfire.
  7. Milestone backlog (iteration, not near-term urgent); labels requirement + infrastructure; assignee jwildfire.

Drafted issue body (VERBATIM)

Business Requirement

Goals should be visible and manageable in the hub alongside the requirement issues they parent, so the roadmap runs as one system instead of two (issues plus a separate markdown directory). Making a goal a first-class issue lets it own its child requirements as sub-issues and roll their status up in the GitHub UI, so anyone can see at a glance what a goal covers and how far along it is. This removes the split-brain problem where goals live in files and everything they organize lives in issues.

Overview

Goals move from obot.agent/goals/*.md (YAML frontmatter) into GitHub issues of a new "goal" type with a dedicated issue form, and each goal issue becomes the parent of its requirement issues via sub-issue links. The frontmatter semantics (name/title, status, anchors, backlog, grant_profile) carry into the goal issue body/form; the two existing goals — G1 (goals/charts.md) and G2 (goals/app.md) — are migrated. Consumers scripts/obot-auto and session-init --auto switch from reading files to reading goal issues, and the O2 "goal edits always wait for @jwildfire" carve-out is preserved in an equivalent form. Platform wrinkle: GitHub-native custom issue types are organization-only, so on this user-owned repo "type = goal" is realized as a goal label plus a goal.yml issue form until/unless the hub moves to an org.

Assumptions

  1. GitHub-native custom issue types are org-only and this is a user-owned repo, so "type = goal" is a goal label plus a dedicated issue form (.github/ISSUE_TEMPLATE/goal.yml) unless/until the hub moves to an org.
  2. Both existing goal files (G1 goals/charts.md, G2 goals/app.md) are migrated into goal issues, carrying the frontmatter semantics (status, anchors, backlog, grant_profile) into the issue.
  3. Consumers scripts/obot-auto and session-init --auto switch to reading goal issues instead of files; until that switch lands, the files remain the runnable source of truth.
  4. Goal-to-requirement parenting uses GitHub sub-issue links, which also answers #53's open "do goals need a formal type" question in the affirmative.
  5. The O2 "goal edits always wait for @jwildfire" carve-out survives the move in some equivalent form (e.g. only @jwildfire edits goal issues, or --auto never consumes a goal it edited itself) — an open design decision, not decided at filing.
  6. After migration the obot.agent/goals/ directory is retired; since deletion needs explicit approval, that is a task gated on @jwildfire.
  7. Milestone backlog (iteration, not near-term urgent); labels requirement + infrastructure; assignee jwildfire.

Data Requirement

Not applicable — no study data; the "data" is the goal frontmatter fields (name/title, status, anchors, backlog, grant_profile), covered under Design.

Design

TBD — populated before tasks are created. Must cover two decisions: (1) the replacement for the O2 "goal edits always wait for @jwildfire" edit-control carve-out; (2) the exact goal.yml form fields and how they map the existing frontmatter (name/title, status, anchors, backlog, grant_profile).

Tasks

TBD — tasks are created after the Design section is populated, per the requirement lifecycle.

Promoted from discussion #55: https://github.com/jwildfire/obot.roadmap/discussions/55


This was drafted by obot ideas-triage (Claude Code headless using Fable 5) — review by @jwildfire

Drafted discussion comment on #55 (VERBATIM; #NEW = number of the created issue)

Promoted to a requirement: #NEW — "Requirement: goal issues — goals move from obot.agent files to hub issues". Your three in-thread answers are baked in: this supersedes design decision O2 of #18, it's iteration (nothing changed since O2), and "type = goal" means a new issue type with its own template, distinct from the requirement template, with goal issues typically parenting requirement issues. This also resolves the open question from #53 about whether goals need a formal issue type (yes — via sub-issue parenting). Closing this discussion as resolved; follow-up happens on #NEW.


This was drafted by obot ideas-triage (Claude Code headless using Fable 5) — review by @jwildfire

Policy-conflict notes for calibration (@jwildfire)

  1. Section count. Policy v2 outcome 2 prescribes six sections including ### Assumptions; AGENTS.md and requirement.yml say exactly five sections and "never add a section", and warn downstream parsers break silently on drift. This run followed the lane-specific policy (six sections, Assumptions after Overview). If rollups/dashboards parse strictly, either the parsers or AGENTS.md should learn the Assumptions section, or the policy should move assumptions into Overview.
  2. Attribution placement. AGENTS.md puts the attribution line above the first section heading; policy v2 requires a terminal --- + exact footer (cost line appended after it by the workflow). This run followed the policy footer only. If both are wanted, say so and the lane will carry both lines.
  3. Dedup vs bias-to-promote. Worth confirming intended live behavior when a promotion already exists but new substantive comments arrive later (current rule: stop unless the newest comment asks about status — a substantive scope-changing reply would be silently dropped).
  4. Observed data inconsistency: #78/#79 footers cite #53 as the migration authority; #71 is the issue that actually carries the discussion-#55 supersession. Cheap fix in live ops if desired.
#56 — Fable 5 report (run)

🧮 run cost: 247.5k tokens in / 15.8k out · ~$2.30 (Fable 5 orchestrator + subagents)

  • claude-haiku-4-5-20251001: 630 in / 17 out · $0.00
  • claude-fable-5: 11 in / 15.8k out · $1.80
  • claude-sonnet-5: 28 in / 10.9k out · $0.42
  • claude-opus-4-8: 2 in / 1.9k out · $0.08

ideas-triage DRY RUN report — discussion #56

  • Run mode: DRY RUN (fixture assessment per .github/ideas-triage-policy.md §Dry-run mode). Closed state and existing promotions ignored for classification; NO mutations performed.
  • Date: 2026-07-24
  • Orchestrator: Fable 5 (claude-fable-5)
  • Discussion: #56 "roadmap homepage refactor" — Ideas category, author @jwildfire, opened 2026-07-24T11:46:42Z. Thread = opening post only; the single comment is the live lane's promotion notice (ignored per dry-run rules; no later human comments override the opening post).

Classification and chosen outcome

Outcome 2 — FILE REQUIREMENT.

Reasoning (fresh assessment, orchestrator's call):

  • The idea is requirement-shaped: a structural redesign of roadmap.html with a six-section information architecture, cross-repo data sources (PRs, releases, branch comparisons, discussions), a repo filter, and a heartbeat-driven update path. An in-session obot with the roadmap in context would start drafting the requirement — so per the bias-to-promote rule, file it.
  • Not EXTEND EXISTING: the closest open requirements each cover only a slice — #31 (roadmap transparency) is the umbrella rationale, #44 overlaps only the "Upcoming Releases" section, #71/#53 feed only the Goals section, #24 supplies only the heartbeat state. No single open requirement contains this page refactor; it warrants its own issue that cross-links them.
  • Not FILE TASK: far too large for a plain chore issue (multiple generators, new data collectors, changelog major bump).
  • Not ASK: the opening post is detailed — sections enumerated, layout/link/filter/heartbeat notes given. Ambiguities (e.g. "last X days") are handled as correctable assumptions, not questions.

Calibration note: this matches what the live v1 lane actually did (it filed #57), so policy v2 reproduces the v1 disposition on this fixture while adding the Assumptions section and richer cross-linking.

Intended actions (in live order)

  1. Create issue Requirement: Roadmap homepage refactor with the body below (verbatim).
    • Labels: requirement, infrastructure. Assignee: jwildfire. Milestone: backlog (not clearly near-term urgent; scope still has TBDs).
    • Record {"kind":"issue","number":<n>} to /tmp/posted.jsonl.
  2. Board add: attempt gh project item-add 1 --owner jwildfire --url <issue-url>. The context pack states the board is unavailable to this token, so the expected result is the approved fallback: print "board add deferred to session wrapup" and continue.
  3. Post ONE discussion comment on #56 with the body below (verbatim, <ISSUE_URL> substituted), via the addDiscussionComment mutation requesting comment { id }; record {"kind":"discussion_comment","node_id":"<id>"} to /tmp/posted.jsonl.
  4. Close discussion #56 as resolved via the closeDiscussion mutation (reason RESOLVED).

That is the complete mutation set — nothing else would be created, edited, or reacted to. What I would close: discussion #56 (RESOLVED). Nothing else.

Drafted issue body (VERBATIM)

### Business Requirement

The roadmap page is how @jwildfire and anyone following the project see the state of the work at a glance, and today it only shows requirement issues. Success means one compact homepage that surfaces the goals we are pursuing, the requirements under them, what is in flight (open PRs), what just shipped (recent releases), what is about to ship (upcoming releases), and the ideas being considered — each item one click away from the underlying GitHub content, filterable by repo, and kept current automatically.

### Overview

This is a structural redesign of `roadmap.html` (generated at deploy time by `scripts/build_roadmap.mjs`, published by `deploy-site.yml`) from today's flat, stage-grouped, requirements-only list into a six-section homepage.
The six requested sections:
- Goals — list of goals; active visible, closed and backlog collapsed.
- Requirements — list of requirements; active visible, closed and backlog collapsed.
- Open PRs.
- Recent Releases.
- Upcoming Releases — repos where dev is ahead of main and/or main is ahead of the most recent release.
- Ideas — open idea discussion posts plus posts moved to issues in the last X (default 14) days.
Layout/link/filter/heartbeat notes from the request: ultra-compact modern layout with no whitespace by default; every item links to the relevant GitHub content; filter by repo; the Obot orchestration session updates the page as part of its heartbeat.
Impact spans several own-repo generators and their shared config: `build_roadmap.mjs`, the tracked-repo lists that currently disagree (`scripts/status-repos.csv`, `build_news.mjs`, `build_metrics.py`), `build_status.R`, and a semver-major entry in `site/roadmap-changelog.json` for the structural redesign.
Relationships to existing work:
- Operationalizes #31 (roadmap transparency — this is the "page reads the signals agents maintain" layer); overlaps #44 (unreleased-commits view feeds "Upcoming Releases").
- Consumes #71 + #53 (hub goal issues / goal pages feed the Goals section) and #24 (session hub supplies the heartbeat/session state).

### Assumptions

@jwildfire — each assumption below can be corrected with a one-line comment on this issue.
1. This is a structural redesign replacing the current requirements-only roadmap.html layout, not new sections appended to it (roadmap-changelog major bump).
2. The Goals section reads the obot.agent `goals/*.md` files for now and switches producers to hub goal issues when #71/#53 land.
3. "Hidden" for closed and backlog items means collapsed/toggleable on the page, not omitted from the generated data.
4. The repo scope for Open PRs, Releases, and the repo filter is a single tracked-repo list, consolidating the current drift between status-repos.csv, build_news.mjs, and build_metrics.py.
5. The ideas-section window "last X days" defaults to 14 days.
6. "Update as part of heartbeat" means the orchestration session's heartbeat triggers the existing deploy-site workflow (workflow_dispatch); the page stays a deploy-time-generated static artifact, with no client-side live polling in v1.
7. Sections sourcing external-repo data fail soft (that section degrades, deploy continues), matching the status-page convention.

### Data Requirement

- Goals: obot.agent `goals/*.md` files (frontmatter name/title/status/anchors/backlog) — Confirmed; migrates to hub goal issues when #71/#53 land (TBD).
- Requirements: GitHub issues filtered by the `requirement` label via GraphQL/REST — Confirmed (current source of the page).
- Open PRs: GitHub PRs across the tracked-repo list — Confirmed source, consolidated repo list TBD.
- Recent Releases: GitHub releases across tracked repos — Confirmed source, consolidated repo list TBD.
- Upcoming Releases: branch comparisons (dev vs main, main vs latest release) across tracked repos — Confirmed source (overlaps #44), consolidated repo list TBD.
- Ideas: GitHub discussions (open idea posts) plus issues promoted from discussions within the window — Confirmed source, promotion-tracking mechanism TBD.
- Repo filter scope: single consolidated tracked-repo list replacing status-repos.csv / build_news.mjs / build_metrics.py drift — TBD (consolidation is part of this work).
- Heartbeat/session state: orchestration session heartbeat that dispatches the deploy workflow (#24) — TBD.

### Design

_To be populated during Design (Step 3). Likely produces a `requirements/design/{issue_number}_design.md` artifact._

### Tasks

_To be populated after Design._

Promoted from discussion #56: https://github.com/jwildfire/obot.roadmap/discussions/56

---
This was drafted by obot ideas-triage (Claude Code headless using Fable 5) — review by @jwildfire

Drafted discussion comment (VERBATIM; <ISSUE_URL> = the created issue's URL)

Filed this idea as a requirement: <ISSUE_URL>
It is scoped as a structural redesign of the roadmap homepage into the six sections you described (goals, requirements, open PRs, recent releases, upcoming releases, ideas), with compact layout, per-item GitHub links, repo filtering, and heartbeat-triggered updates. I have listed a few working assumptions on the issue — each can be corrected with a one-line comment there.

---
This was drafted by obot ideas-triage (Claude Code headless using Fable 5) — review by @jwildfire

Assumptions list (orchestrator's calls, restated)

  1. Structural redesign replacing the current requirements-only layout, not appended sections (changelog major bump).
  2. Goals section reads obot.agent/goals/*.md for now; switches producers to hub goal issues when #71/#53 land.
  3. "Hidden" = collapsed/toggleable on the page, not omitted from generated data.
  4. One consolidated tracked-repo list for PRs/Releases/filter (fixes status-repos.csv / build_news.mjs / build_metrics.py drift).
  5. Ideas window "X days" defaults to 14.
  6. Heartbeat = session heartbeat dispatches deploy-site; page stays static, no client-side polling in v1.
  7. External-repo sections fail soft, matching the status-page convention.

Dedup search (gh search issues --repo jwildfire/obot.roadmap "discussions/56") and delegated research:

  • #57 Requirement: Roadmap homepage refactor (open) — the ACTUAL existing promotion of this discussion, with an approved implementation plan and phases 0–3 already shipped (staged at /roadmap-next.html). Ignored for classification per dry-run rules; a live run would stop at the dedup step and at the closed-discussion check.
  • #31 roadmap transparency (open, 2026q3) — umbrella rationale; this refactor is its "page reads the signals agents maintain" layer.
  • #44 status page unreleased-commits view (open) — overlaps the "Upcoming Releases" section; would be cross-linked and likely re-scoped during Design.
  • #71 goals move from obot.agent files to hub issues + #53 goal pages in the hub (open, backlog) — future producers for the Goals section.
  • #24 session hub — live dashboard + heartbeat (open, 2026q3) — supplies the heartbeat/session state for the update path.
  • #77 chat with orchestrator from dashboard (open, backlog) — indirect only (shares #24's producer); not cross-linked in the draft.

Delegation record (per policy §Role and delegation)

  • Research subagent on claude-sonnet-5 (agent a200c63485e5b3cb9): current roadmap.html pipeline, related-issue research, constraints. ~49k tokens, 25 tool uses, read-only.
  • Drafting subagent on claude-opus-4-8 (agent a93e9db240ae0b1a8): issue body + discussion comment from the orchestrator's classification and verbatim assumptions. ~13k tokens, 0 tool uses.
  • Fable personally: classification call, assumption calls, target choice (new issue vs extending #31/#44), draft review (passed unchanged), and this report.

Calibration flags for @jwildfire (policy conflicts surfaced by this dry run)

  1. Section count — policy vs template. Policy v2 mandates SIX headings (adds ### Assumptions); AGENTS.md + .github/ISSUE_TEMPLATE/requirement.yml mandate exactly FIVE, with a pre-submit grep check, and warn that downstream rollups/dashboards parsing the sections "break silently" on drift. The draft above follows the policy (binding for this lane, and the thing this dry run calibrates), but a live run would ship a six-heading body that fails AGENTS.md's own verification step. Suggested resolutions: (a) update the template/parsers to accept an optional Assumptions section, or (b) amend the policy to nest assumptions inside Overview.
  2. Attribution placement. AGENTS.md puts the drafted-by line above the first section heading ("This Issue was drafted by Claude Code using Fable 5 and reviewed by @jwildfire"); the policy's hard guard puts a different exact string after a closing horizontal rule (required for the cost-footer machinery). The draft follows the policy string/placement, matching live-lane precedent (#57's comment); resolve which convention wins for issue bodies.
  3. Live-run behavior on this discussion: outside dry-run mode, #56 is closed and already promoted — the run would correctly stop at sequence step 1 (closed) or step 2 (dedup finds #57).

This was drafted by obot ideas-triage (Claude Code headless using Fable 5) — review by @jwildfire

6 · Next steps (gated)

  1. Stage B — sandbox thread on the branch: live reactions check (👀→👍/😕) + one end-to-end filing.
  2. Gate: @jwildfire's go-live nod — merging ideas-triage-v2 to main is what turns v2 on for real events.
  3. Stage C — event-trigger matrix on the sandbox (evidence to #61) → close #61.
  4. Steady state: v2 live for new ideas; the five open v1 threads are handled in-session (plan v1.1 §8 removal).

This page was drafted by Claude Code using Fable 5 and reviewed by @jwildfire