Skip to content

impl(dashboard): slice 3 — pluggable pages, DNS register, comments, session registry (#906) - #920

Merged
dezren39 merged 5 commits into
mainfrom
dashboard-slice3
Oct 25, 2026
Merged

dezren39 merged 5 commits into
mainfrom
dashboard-slice3

Conversation

@dezren39

@dezren39 dezren39 commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

Implements #906 in three workstreams, building on the slice-2 seam (data-driven nav, flat route chain, page + /api/*.json twin).

§1 Pluggable pages — DNS register first

  • src/pages.ts manifest (PAGES): nav bar, the new Pages ▾ dropdown, and /pages all render from it. Adding a page = manifest entry + render function + route branch (+ JSON twin). Recipe in the README.
  • /dns + /api/dns.json: the register (impl(dns-registry): recurring DNS backup job, renewal/cost tracking, dashboard view of the domain register #902's file) is parsed collector-side (src/dns.ts, keyed on the register's table header) into a dns fleet-feed section — no new sync path. Views: next renewal, renewing-soon (45d) spend, in-use / unused-but-earmarked / completely-unused (status read from the register's own Plan cell — matches its 3 / 18 / 19 split of 40), full table.

§2 Comments on dashboard items

  • Store: src/comments.ts — aggregator-local JSON file (atomic writes), keyed by object ref so threads survive republishes: gh:<owner/repo#N>, orch:<tierItem.id>, session:<id>, board ids, roadmap subjects.
  • Unambiguous authorship: drew / muse / agent identities from the registry; the API refuses authorless comments.
  • Kinds, visually distinct: note (read on pickup, triggers nothing), message to Muse (orchestrator-triaged, triageState), post as GitHub comment (explicit githubRef target required at post time; githubState pending → posted/failed with the resulting URL recorded).
  • UI: threads + forms on item pages (merged across the item's subject and its linked gh: refs), /discuss/<ref> for any object, 💬 count badges on board / roadmap / session / tier cards.
  • API: GET /api/comments.json (object/kind/state filters + pending counts), POST /api/comments, POST /api/comments/triage, POST /api/comments/github-result.
  • Orchestrator consumption contract (also commented on impl(orchestrator): recurring orchestration job — queue triage, priority ladder, blocker awareness, goal measurement #899): each pass polls ?kind=message&state=new and ?kind=github&state=new, triages into its normal flow (post + report github-kind), then marks consumed via the triage endpoint. Notes are read on pickup, never polled.

§3 Agent/session identity registry

  • src/registry.ts normalizes all sources into durable records (file store, max-token merge): OpenCode laptop (live) + sandbox (feed, with per-session tokens read off the server), Jules (keeper state), Muse (launch records).
  • Muse v1: scripts/record-claude-launch.ts appends a JSONL record at spawn; the collector carries it. Unrecorded Muse sessions stay invisible — the coverage note says which sources are wired, honestly.
  • Loose task↔session linkage from PR ref, issue URL in title, or launch record; item pages list 'Sessions that worked this'; /sessions + /api/registry.json render the registry.
  • OpenCode tool opencode-tools/session-identity.ts: a session reports its own { sessionId, parentId, agent, directory }; shipped by install.sh, installed on both hosts.

Verification

Refs #906. The DNS data pipeline itself stays with #902; the comments consumption lands in the orchestrator's contract via #899.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

Muse Sweep added 5 commits October 25, 2026 21:52
…registry, comments store, page manifest

- model: DnsEntry/DnsSection, DashComment/DashAuthor, SessionRecord;
  Provenance gains dns + registry facets
- dns.ts: parse #902's register Markdown into renewal-sorted entries
  with active/earmarked/unused classification from the plan cell
- registry.ts: session records from feed entries + Muse launch
  records, cumulative-token merge, comment author identities
- comments.ts: file-backed dashboard comment store keyed by object
  ref, with validation and the orchestrator consumption contract
- pages.ts: the page manifest (nav + dropdown render from it)
- collector: embeds the DNS section (parsed from the register file)
  and registry records (sandbox OpenCode + Jules + Muse launches)
- scripts/record-claude-launch.ts: the launch-record append helper
… API

- nav and the page dropdown render from the src/pages.ts manifest;
  /pages lists the manifest itself
- /dns renders #902's register: next renewal, renewing-soon spend,
  in-use / unused-but-earmarked / completely-unused views, full table
- /sessions renders the identity registry grouped by source, with
  parent links and token totals; item pages list linked sessions
- dashboard comments: threads keyed by object ref with unambiguous
  authorship (drew / muse / agent identities), two kinds visibly
  distinct (note vs message-to-Muse) plus post-as-GitHub-comment
  with an explicit target; 💬 badges on board/roadmap/session/tier
  cards; /discuss/<ref> for any object
- API: /api/dns.json, /api/registry.json, GET+POST /api/comments.json,
  POST /api/comments, /api/comments/triage, /api/comments/github-result
- opencode-tools/session-identity.ts: a session reports its own
  { sessionId, parentId, agent, directory }; install.sh ships it
- test/slice3.test.ts: DNS parser + classification, registry
  normalization/merge, comment store lifecycle + validation, page
  manifest, slice-3 renders, the identity tool, and full HTTP flows
  (82 tests total, all passing; tsc clean)
- README: views, pluggable-page recipe, comments + orchestrator
  consumption contract, registry, env vars, layout
@dezren39
dezren39 requested a review from a team as a code owner October 25, 2026 22:18
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-25T22:22:51.104470Z 9e74d95 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Oct 25, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 53 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c0efd0e4-7f4f-42c0-b5f1-af3d7e1df459
Commits

Reviewing files that changed from the base of the PR and between 21b7621 and 9e74d95.

Files selected for processing: 19
  • pm-stack/aggregator/README.md
  • pm-stack/aggregator/install.sh
  • pm-stack/aggregator/opencode-tools/session-identity.ts
  • pm-stack/aggregator/scripts/collect-fleet-feed.ts
  • pm-stack/aggregator/scripts/record-claude-launch.ts
  • pm-stack/aggregator/src/comments.ts
  • pm-stack/aggregator/src/config.ts
  • pm-stack/aggregator/src/dns.ts
  • pm-stack/aggregator/src/feed.ts
  • pm-stack/aggregator/src/model.ts
  • pm-stack/aggregator/src/pages.ts
  • pm-stack/aggregator/src/registry.ts
  • pm-stack/aggregator/src/render.ts
  • pm-stack/aggregator/src/server.ts
  • pm-stack/aggregator/src/source.ts
  • pm-stack/aggregator/src/sources/fixtures.ts
  • pm-stack/aggregator/src/sources/live.ts
  • pm-stack/aggregator/test/opencode-plugin.d.ts
  • pm-stack/aggregator/test/slice3.test.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@dezren39
dezren39 merged commit 1262091 into main Oct 25, 2026
4 checks passed
@dezren39
dezren39 deleted the dashboard-slice3 branch October 25, 2026 22:22

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9e74d953cb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +121 to +123
const tmp = `${this.file}.tmp-${process.pid}`;
await writeFile(tmp, JSON.stringify(data, null, 2));
await rename(tmp, this.file);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Serialize comment-store persistence

When comment submissions or triage updates overlap, every persist() call writes to the same process-wide temporary path. One call can rename that file while another is still using it, causing the latter to fail with ENOENT even though its mutation is already visible in memory. Reproducing with 20 concurrent add() calls after loading the store produced 19 rejected operations; the HTTP handler reports these as failed submissions, encouraging duplicate retries. Serialize persistence so each acknowledged mutation is durably written without competing over the temporary file.

Useful? React with 👍 / 👎.

Comment on lines +103 to +107
async load(): Promise<void> {
if (this.loaded) return;
this.loaded = true;
try {
const parsed: unknown = JSON.parse(await readFile(this.file, "utf8"));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Await initialization before allowing concurrent store access

If a second request accesses the store while its first disk read is pending, loaded is already true, so that request proceeds against the empty array. An add() can then succeed before the original load replaces this.comments, removing the acknowledged comment from memory and allowing the next write to erase it from disk. With an existing empty store, concurrently calling all() and add() reproduced this loss; adding a second comment left only the second comment persisted. Cache and await the initialization promise so every caller waits for the same completed load.

Useful? React with 👍 / 👎.

let list: DashComment[] = await commentsStore.all();
if (object) list = list.filter((c) => c.objectRef === object);
if (kind) list = list.filter((c) => c.kind === kind);
if (state === "new") list = list.filter((c) => c.triageState === "new" || c.githubState === "pending");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep failed GitHub posts available to the retry consumer

After a poster reports a transient failure through /api/comments/github-result, markGithubResult() changes the comment's state to failed, but this filter excludes it from the documented ?kind=github&state=new polling queue in README.md and the pending count. There is no endpoint that resets failed records to pending, so a poster following that consumption contract never receives the comment again, despite dashCommentHtml() telling the user that a fleet poster will retry. Keep failed, unposted comments available to the consumer or provide an explicit retry/reset flow.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant