Skip to content

feat(roadmap): standalone HTML renderer for the roadmap data (ROADMAP-1b) - #1597

Merged
mergify[bot] merged 7 commits into
mainfrom
claude/roadmap-page-1
Oct 16, 2026
Merged

mergify[bot] merged 7 commits into
mainfrom
claude/roadmap-page-1

Conversation

@Cuarroc

@Cuarroc Cuarroc commented Oct 16, 2026 •

Copy link
Copy Markdown
Owner

Dieser PR liefert den Baustein, der aus den schon vorhandenen Plan- und GitHub-Daten eine eigenständige, private Roadmap-Seite als HTML erzeugt, damit du den echten Plan statt des statischen Entwurfs siehst. Die Seite zeigt zuerst, was hängt, dann die Zeitleiste, die Richtungen (Jetzt, Als Nächstes, Später), die Abhängigkeiten sowie Plan-Mängel und Plan-Änderungen, und schreibt „Unbekannt“ oder „noch nicht verbunden“, wo Angaben fehlen, statt etwas zu erfinden. Es gibt noch keinen Aufruf, der die Seite wirklich erzeugt oder veröffentlicht; die Prüfung im Browser und die Freigabe liegen bei Root.

Report

Plan-ID: ROADMAP-1b

Was sich ändert (nur zwei neue Dateien, 227 Zeilen inkl. Tests, keine Naht):

  • scripts/lib/roadmap-page.mjs: renderRoadmap(data, options) gibt ein vollständiges HTML-Dokument als String zurück. data ist die Ausgabe von buildRoadmap; options kann tokensCss, stateCss, releases, findings, changes und now liefern (ohne tokensCss/stateCss werden src/design/tokens.css und src/design/state/state.css gelesen).
  • Abschnitte in DOM-Reihenfolge: Kopf (ein Satz, höchstens vier Zahlen, generatedAt und mainSha wörtlich), Hängt, Zeitleiste, Richtungen, Abhängigkeiten, Plan-Mängel, Plan-Änderungen.
  • Es wird nichts neu berechnet: Prognose, Zustand, Version und Daten kommen so an, wie buildRoadmap sie liefert. Zustandsformen und -farben nur über die vorhandenen g-st-Klassen, nur wenn ein Zustand mitgeliefert wurde. Fehlendes heißt Unbekannt, fehlende Zusatzquellen heißen „noch nicht verbunden“ mit Erklärung. Leerer Plan, unbekannter oder (mit options.now) über 12 Stunden alter Stand zeigen einen Hinweis und kein „0“ als Beleg.
  • Hängt: Was, Wer, Was muss sich ändern, Wann, Wo; keine Schaltflächen oder Formulare. Karten: Quelle Datei:Zeile, PR-Nummer, Abhängigkeiten (nicht im Plan = markiert). Nur die ersten 3/7/5 Einträge sind sichtbar, der Rest steckt hinter nativem „weitere n anzeigen“; nichts wird verworfen. Richtungen ohne „Jetzt“ sind zu einer Zeile „n Richtungen ruhen“ zusammengefasst; erledigte und verschobene Pakete bleiben sichtbar.
  • Sicherheit: jede Eingabe wird escaped; die Seite trägt eine strenge Content-Security-Policy (default-src 'none', Skript nur per Hash), keine externen Dateien, kein Netz, keine Animation (Hover-Übergang nur bei erlaubter Bewegung). Bedienung nur mit nativen Elementen (details, select) und einem kleinen Skript für Theme (System/Hell/Dunkel) und Richtungsfilter; der Filter wirkt nur auf Richtungen und Abhängigkeiten, nie auf die Kopfzahlen.

Belege (alle im eigenen Arbeitsbaum, Linux)

Befehl Ergebnis
node --test scripts/lib/roadmap-page.test.mjs an 43c04272 (nur Test) rot: Modul roadmap-page.mjs fehlt
node --test scripts/lib/roadmap-page.test.mjs an c621479f Exit 0, 11 von 11 grün
bash scripts/ci/red-first.sh Exit 0: alle 11 Tests an der Merge-Base c7a43fbd rot/fehlend, am Kopf grün
bash scripts/ci/secret-scan.sh Exit 0 (auch in beiden Commit-Hooks)
bash scripts/ci/gates.sh lane prepush an c621479f Exit 0, 358 s, gruen inkl. architecture-drift, lint, typecheck, fe-test, hq-test, clippy, rust-suite
git ls-remote origin claude/roadmap-page-1 c621479f1c68fe169dabefdc355cb5c1ad5fb79b

Messung im Browser (Chromium aus dem Playwright-Cache, Wegwerfseite außerhalb des Repos, erzeugt aus dem docs/PLAN.md dieses Stands mit sechs erfundenen Test-PRs; nichts davon ist committet): Seitenbreite = Fensterbreite bei 390 und 1440 px, hell und dunkel (scrollWidth 390/390 und 1440/1440); keine Konsolen- oder CSP-Fehler; Richtungsfilter lässt die Kopfzahlen unverändert; Theme-Wechsel setzt/entfernt data-theme; Tab-Fokus auf summary zeigt 2 px solid Ring. Ich habe 1440 hell (Kopf, Hängt, Zeitleiste), 390 dunkel (Kopf, Hängt), Richtungen/Abhängigkeiten bei 1440 und Abhängigkeiten bei 390 als Screenshot angesehen. Die Abnahme im Browser liegt bei Root.

Architecture drift: keine Meldung (Gate grün), nichts auf die Allowlist gesetzt.

Offene Anforderungen und Grenzen (ehrlich)

  • Nicht geliefert (keine Datenfelder oder ausserhalb von „nur zwei Dateien“): Balken und Marker „Neu/Umstellung“ auf der Zeitleiste (es gibt keine Typ-Spalte), kritischer Pfad (nicht von buildRoadmap geliefert), „ruht seit“-Datum, „neu seit letztem Besuch“, Liste hinter jeder Kopfzahl, aufklappbare Prognose-Basis über die einzeilige Angabe hinaus. Releases stehen als geordnete Liste, nicht maßstäblich auf einer Zeitachse.
  • Bedienung: Richtungsfilter ist eine Einfachauswahl (kein Mehrfach-Chip), die Ebenen-Überschriften in „Abhängigkeiten“ bleiben stehen, wenn der Filter alle ihre Karten ausblendet. Navigation ist die Abschnittsleiste plus die Standard-Tabfolge der details-Elemente; kein Pfeiltasten-Roving.
  • Nicht gemessen: Kontrastwerte (Farben kommen unverändert aus den Tokens; bekannte Lücken stehen bei DS-POLISH), Screenreader, 200 %-Zoom, Lade- und Offline-Zustände (der Baustein ist rein; „Plan nicht lesbar“ gibt es nur als Hinweis bei leerem Plan).
  • Die 12-Stunden-Schwelle für „veraltet“ ist meine Annahme (gleich wie das Gate plan-stale) und greift nur, wenn der Aufrufer options.now übergibt.
  • Der Baustein kann nicht erkennen, ob buildRoadmap ohne PR-Liste aufgerufen wurde: dann steht „Offene Paket-PRs 0“ als gelieferte Zahl da. Der spätere Aufrufer muss PRs und Releases wirklich laden.
  • Formen der optionalen Eingaben, die der spätere Aufrufer erfüllen muss: releases = Ausgabe von gh release list --json tagName,publishedAt,isDraft,isPrerelease; findings = Ergebnis von checkPlan (kind,id,file,line,detail,pr); changes = [{ date, text }] (oder subject statt text).
  • Kein Aufrufer, keine Ausgabedatei, kein Hosting (außerhalb des Auftrags). docs/PLAN.md: die eigenen Zeilen ROADMAP-1b und ROADMAP-1 dieses PR tragen den Stand nach dem Merge (siehe Fix round 2); keine Zeile wird später von Root ergänzt.

NICHT ABGEDECKT

  • Windows-Hälfte: Linux-Lauf, #[cfg(windows)]-Tests und Windows-Arme von clippy nicht geprüft; die Windows-Bahn läuft in der Merge-Queue. Dieses Paket enthält keinen plattformabhängigen Code.
  • Kein Firefox/WebKit, kein echtes Handy, nur Chromium im Fenster 390 und 1440 px.
  • Browser-Smoke, Frontend-Build und Workflow-Gates der Bahn linux (nicht in prepush).

Review: ausstehend (Stufe B). Root bestellt einen unabhängigen Prüfer aus einer nicht-Anthropic-Familie; Autor ist Claude, keine Selbstfreigabe. Kein review-ok, kein Label, kein Merge von mir.

Fix round 1 (NACHBESSERN)

Source: independent Codex gpt-6.1-sol review of head c621479f (REQUEST CHANGES). Plan-ID: ROADMAP-1b. This section supersedes three statements above: "nur zwei neue Dateien, 227 Zeilen" (now three files, 268 lines against main, below the 300-line limit, so no overrun), "docs/PLAN.md ist nicht angefasst" (the ROADMAP-1b and ROADMAP-1 rows are updated, see R1597-P1) and "greift nur, wenn der Aufrufer options.now übergibt" (see R1597-F1).

ID Source Severity Finding Disposition
R1597-F1 Codex gpt-6.1-sol medium renderRoadmap(data) without options.now compared against new Date(undefined) (NaN), so an old stand showed no banner Accepted. Red test ec0b769c, fix ff001324: a missing or unparsable now falls back to the real clock.
R1597-F2 Codex gpt-6.1-sol medium With the direction filter set, a matching card behind the closed "weitere n anzeigen" overflow stayed hidden and the count included filtered-out cards Accepted. Red test ec0b769c, fix ff001324: the filter opens overflow lists that hold a match, hides overflow lists without a match and rewrites the count to the matching cards. Header numbers stay unchanged.
R1597-P1 Codex gpt-6.1-sol medium No own PLAN row for Plan-ID: ROADMAP-1b Accepted, commit 68b07446. After merging origin/main, the row ROADMAP-1b already existed with "Geplant"; it now reads "In Prüfung: #1597 …" (never "Erledigt" for itself), and ROADMAP-1 records "teilweise erledigt: Daten #1580, Renderer #1597 in Prüfung; Aufrufer und automatische Neuerzeugung offen". The Plan-ID: ROADMAP-1b line of this PR is unchanged and correct.

No finding was rejected.

New head: 68b074463e3e036a9f5b4e8cdedf055dfaf1d319 (git ls-remote origin claude/roadmap-page-1 confirms it). Commits since c621479f: 846010b3 merge of origin/main (reason: PLAN rows changed on main; merge, no rebase), ec0b769c failing tests, ff001324 fix, 68b07446 PLAN rows.

Evidence (own worktree, Linux)

Command Result
node --test scripts/lib/roadmap-page.test.mjs at ec0b769c (tests only) Exit 1: 2 new tests red (no veraltet banner; 0 visible Beta cards), 11 old tests green
node --test scripts/lib/roadmap-page.test.mjs scripts/lib/roadmap-data.test.mjs at 68b07446 Exit 0, 27 of 27 green
RF_BASE_BRANCH=main bash scripts/ci/red-first.sh Exit 0: both new tests red/missing at the merge base, green at the head
npm run plan:check Exit 1 from findings that already exist on main; none mentions ROADMAP (--json grep count 0). Not caused by this PR: rows PLAN-CLEAN-1 (#1591) and PLAN-CLEAN-2 (#1592) still read "In Prüfung"/"Geplant" although both PRs are merged; their owner has to update them.
bash scripts/ci/secret-scan.sh Exit 0 (also in the precommit hooks of all three commits)
node scripts/ci/architecture-drift.mjs check and git diff --check origin/main...HEAD Exit 0 each
bash scripts/ci/gates.sh lane prepush at 68b07446 Exit 0 (all gates green incl. fe-test, hq-test, denkraum, clippy, rust-suite)
Throwaway Chromium check outside the repo (9 packages of one level, filter Beta) Exit 0: before 7 Alpha / 0 Beta visible; filter Beta: 0 Alpha / 1 Beta visible, summary "weitere 1 anzeigen"; cleared: 7 Alpha, "weitere 2 anzeigen"; no console or CSP errors

Architecture drift: no finding, nothing added to the allowlist.

NICHT ABGEDECKT

  • Windows half: Linux run only; #[cfg(windows)] tests and Windows arms are not checked, the Windows lane runs in the merge queue. This package has no platform-dependent code.
  • The committed regression test for F2 runs in jsdom, which does not enforce the page's CSP meta; CSP behaviour was only observed in the throwaway Chromium run above (Chromium only, one window size).
  • No Firefox/WebKit, real phone, screen reader, contrast or 200 % zoom measurement; the lane linux workflow gates are not part of prepush.
  • The 12-hour stale threshold remains my assumption (same as gate plan-stale).

Review: pending, Root commissions the delta review (tier B fix round: one outside reviewer, non-Anthropic family). No review-ok, no label, no ready, no merge from me.

🤖 Generated with Claude Code on the ProjectA server worker

Fix round 2 (NACHBESSERN)

Source: independent Codex gpt-6.1-sol delta review of head 68b07446 (APPROVE WITH CONDITIONS, condition R1597-P1). Plan-ID: ROADMAP-1b. This section supersedes the R1597-P1 line of fix round 1 ("In Prüfung: #1597 …") and the statement in the report above that the state of ROADMAP-1b belongs to Root: the PR's own PLAN rows carry the state after the merge, so no row is added later.

ID Source Severity Finding Disposition
R1597-P1 Codex gpt-6.1-sol medium docs/PLAN.md rows ROADMAP-1b and ROADMAP-1 still said "In Prüfung" / "Renderer #1597 in Prüfung", which is stale after the merge (AGENTS.md review rule: the PR's own row states what is true after merge) Accepted, commit 5177034e. ROADMAP-1b now reads "Teilweise erledigt: eigenständiger HTML-Renderer scripts/lib/roadmap-page.mjs mit Merge von #1597 geliefert (16.10.); offen bleiben Aufrufer, automatische Neuerzeugung bei jedem Merge, Hosting und Root-Browserabnahme". ROADMAP-1 now reads "teilweise erledigt: Daten #1580 und HTML-Renderer mit Merge von #1597 geliefert; Aufrufer und automatische Neuerzeugung offen; Aufteilung in ROADMAP-1a und ROADMAP-1b bleibt bestehen". The wording follows the reviewer's proposal; the row is not "Erledigt" because callers, regeneration and hosting stay open.

No finding was rejected. Code, tests and trailers are unchanged since 68b07446 (diff of this round: 2 lines in docs/PLAN.md; total against main unchanged at 268 lines, below 300).

New head: 5177034e07e346564361ff7ff313e908113e59d0 (git ls-remote origin claude/roadmap-page-1). Commit since 68b07446: 5177034e (docs only, No-Test: plan status row).

Evidence (own worktree, Linux)

Command Result
node scripts/plan-check.mjs --json before and after the edit Exit 1 both times (findings that already exist on main); count 33 before, 33 after; no finding mentions ROADMAP or #1597
node --test scripts/lib/roadmap-page.test.mjs scripts/lib/roadmap-data.test.mjs Exit 0, 27 of 27 green
bash scripts/ci/secret-scan.sh Exit 0 (also in the precommit hook)
bash scripts/ci/gates.sh lane prepush at 5177034e07e346564361ff7ff313e908113e59d0 Exit 0, 450 s, all gates green (also in the pre-push hook; push exit 0)

Architecture drift: no finding, nothing added to the allowlist.

NICHT ABGEDECKT

  • Windows half: Linux run only; #[cfg(windows)] tests and Windows arms are not checked, the Windows lane runs in the merge queue. This round changes only a docs table row.
  • Round 2 changes no renderer code; the browser evidence of fix round 1 (Chromium only) is unchanged and not repeated.
  • The plan:check findings that remain (duplicate IDs, PLAN-CLEAN-1/-2 status rows, unknown v2 dependencies, PRs without a Plan-ID) exist on main and are not caused by this PR.

Review: pending, Root commissions the delta review (tier B fix round; docs-only delta). No review-ok, no label, no ready, no merge from me.

🤖 Generated with Claude Code on the ProjectA server worker

Second review (Root acceptance, 16.10.2026 ~04:05 MESZ)

Reviewer Family Head Verdict Findings / disposition
Codex gpt-6.1-sol (server) OpenAI 5177034 APPROVE R1597-P1, F1, F2 closed (see above)
OpenRouter google/gemini-3.8-flash Google 5177034 (full PR diff) APPROVE none
Tier B: two families other than the author's (Anthropic). Root accepts head 5177034.

Cuarroc and others added 7 commits October 16, 2026 01:46
The renderer module does not exist yet, so the whole file is red on the
merge base. The tests pin the public renderRoadmap contract: escaping,
section order, supplied stand and numbers, honest empty/stale states,
Hängt without actions, direction lanes, package details, a standalone
page and the real buildRoadmap output.

Plan-ID: ROADMAP-1b
Test-First: scripts/lib/roadmap-page.test.mjs::hostile strings from every input stay inert text
Test-First: scripts/lib/roadmap-page.test.mjs::sections follow the reading order and directions list Jetzt before Später
Test-First: scripts/lib/roadmap-page.test.mjs::head shows the supplied stand and exactly four supplied numbers
Test-First: scripts/lib/roadmap-page.test.mjs::missing facts read Unbekannt instead of a number or an invented date
Test-First: scripts/lib/roadmap-page.test.mjs::an empty plan and a stale stand and absent auxiliary sources do not pass as proof
Test-First: scripts/lib/roadmap-page.test.mjs::Hängt shows the five fields without action controls and keeps every row
Test-First: scripts/lib/roadmap-page.test.mjs::directions keep every lane and status and show only the supplied forecast
Test-First: scripts/lib/roadmap-page.test.mjs::package details name source line and PR and unresolved dependencies with g-st state forms
Test-First: scripts/lib/roadmap-page.test.mjs::page is standalone without external references or animation under a strict policy
Test-First: scripts/lib/roadmap-page.test.mjs::inputs stay unmodified and css cannot close the style element
Test-First: scripts/lib/roadmap-page.test.mjs::real buildRoadmap output renders with its owner and package facts

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
renderRoadmap(data, options) turns buildRoadmap output (plus optional
releases, plan findings and plan changes) into one self-contained HTML
string. Sections in order: Hängt, Zeitleiste, Richtungen, Abhängigkeiten,
Plan-Mängel, Plan-Änderungen. It recomputes nothing: forecast, state,
version and dates are shown as supplied, missing facts read Unbekannt
and absent auxiliary sources read "noch nicht verbunden". All input is
escaped, the page carries a strict CSP (script by hash), no external
assets, no animation, native details/select controls only.

Plan-ID: ROADMAP-1b
Test-First: scripts/lib/roadmap-page.test.mjs::hostile strings from every input stay inert text
Test-First: scripts/lib/roadmap-page.test.mjs::sections follow the reading order and directions list Jetzt before Später
Test-First: scripts/lib/roadmap-page.test.mjs::head shows the supplied stand and exactly four supplied numbers
Test-First: scripts/lib/roadmap-page.test.mjs::missing facts read Unbekannt instead of a number or an invented date
Test-First: scripts/lib/roadmap-page.test.mjs::an empty plan and a stale stand and absent auxiliary sources do not pass as proof
Test-First: scripts/lib/roadmap-page.test.mjs::Hängt shows the five fields without action controls and keeps every row
Test-First: scripts/lib/roadmap-page.test.mjs::directions keep every lane and status and show only the supplied forecast
Test-First: scripts/lib/roadmap-page.test.mjs::package details name source line and PR and unresolved dependencies with g-st state forms
Test-First: scripts/lib/roadmap-page.test.mjs::page is standalone without external references or animation under a strict policy
Test-First: scripts/lib/roadmap-page.test.mjs::inputs stay unmodified and css cannot close the style element
Test-First: scripts/lib/roadmap-page.test.mjs::real buildRoadmap output renders with its owner and package facts

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
PLAN rows changed on main; merge (no rebase) so the ROADMAP-1b row can be added on a current PLAN.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
R1597-F1: without options.now the stale-stand comparison used
new Date(undefined) (NaN), so a 2000 stand showed no warning.
R1597-F2: with the direction filter set, a matching card behind the
closed "weitere n anzeigen" overflow stayed hidden and the count still
included filtered-out cards.

Plan-ID: ROADMAP-1b
Test-First: scripts/lib/roadmap-page.test.mjs::a missing or unusable options.now still warns about an old stand
Test-First: scripts/lib/roadmap-page.test.mjs::the direction filter opens overflow hits and counts only the cards that match

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
R1597-F1: a missing or unparsable options.now now falls back to the
real clock, so an old stand always shows the "veraltet" banner.
R1597-F2: the direction filter now opens every overflow list that holds
a matching card, hides overflow lists without a match and rewrites the
"weitere n anzeigen" count to the cards that match.

Plan-ID: ROADMAP-1b
Test-First: scripts/lib/roadmap-page.test.mjs::a missing or unusable options.now still warns about an old stand
Test-First: scripts/lib/roadmap-page.test.mjs::the direction filter opens overflow hits and counts only the cards that match

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
R1597-P1: the package row ROADMAP-1b now states what is true after this
PR is opened (renderer in review, caller/regeneration/hosting open) and
ROADMAP-1 records the partial state (data #1580, renderer #1597).

Plan-ID: ROADMAP-1b
No-Test: documentation only

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The PR's own PLAN rows must describe what is true after the merge
(AGENTS.md review rule), not "in review". Both rows now say the
standalone HTML renderer is delivered with the merge of #1597 and keep
callers, automatic regeneration, hosting and Root's browser acceptance
as open.

Fixes R1597-P1.

No-Test: plan status row

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@Cuarroc
Cuarroc marked this pull request as ready for review October 16, 2026 01:49
@Cuarroc Cuarroc added the review-ok Pipeline: review disposition complete, no open high finding label Oct 16, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 16, 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-16T01:51:36.185114Z 5177034 Draft marked ready
ℹ️ 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.

@Cuarroc

Cuarroc commented Oct 16, 2026

Copy link
Copy Markdown
Owner Author

Root: head 5177034 accepted (Codex + Gemini APPROVE on this head), required checks pass. @Mergifyio queue

@Cuarroc

Cuarroc commented Oct 16, 2026

Copy link
Copy Markdown
Owner Author

Root auto-queue: head 5177034 unchanged since review-ok, all checks green. @Mergifyio queue

@mergify
mergify Bot merged commit 648fba4 into main Oct 16, 2026
25 checks passed
@mergify

mergify Bot commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

Merge Queue Status

This pull request spent 18 minutes 19 seconds in the queue, including 13 minutes 20 seconds running CI.

Required conditions to merge

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

Labels

review-ok Pipeline: review disposition complete, no open high finding

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant