LearnNewsExamplesServices
Frontmatter
titlefix(portal): restore shared timeline import paths (#12265)
authorneo-gpt
stateMerged
createdAtMay 31, 2026, 8:34 PM
updatedAtMay 31, 2026, 8:53 PM
closedAtMay 31, 2026, 8:53 PM
mergedAtMay 31, 2026, 8:53 PM
branchesdevcodex/12265-portal-timeline-import-paths
urlhttps://github.com/neomjs/neo/pull/12266
Merged
neo-gpt
neo-gpt commented on May 31, 2026, 8:34 PM

Authored by GPT-5 (Codex Desktop). Session 019e7f45-ad55-75e0-bfff-a21c2385df00.

FAIR-band: in-band [12/30]

Resolves #12265

Related: #12204

Restores the shared portal timeline files after their move into apps/portal/view/content/ by correcting their framework import depth. The tickets tab no longer gets stranded at the lazy-module boundary when it imports Portal.view.content.CanvasWrapper and Portal.view.content.TimelineCanvas.

Evidence: L3 (local browser + Neural Link runtime probe on the patched branch) -> L3 required (portal runtime mount + theming/style surface verification). No residuals.

Deltas from ticket

No scope expansion. The fix is exactly the two moved import paths; route config, parser behavior, canvas behavior, and SCSS files are untouched.

Test Evidence

  • node --input-type=module -e "await import('./apps/portal/view/news/tickets/MainContainer.mjs')" now reaches the expected runtime-only Neo is not defined boundary instead of ERR_MODULE_NOT_FOUND for apps/portal/view/content/*.
  • Temporary local server from this branch at http://localhost:63343/apps/portal/index.html#/news/tickets; Neural Link session d4dd45d2-7063-4068-b4b1-be67c2e38d8a showed Portal.view.news.tickets.MainContainer, Portal.view.content.CanvasWrapper, and Portal.view.content.TimelineCanvas mounted.
  • NL console logs on that session contained no runtime errors.
  • Computed styles for Portal.view.content.CanvasWrapper preserved position: relative, overflow: visible, and padding-bottom: 20px; server logs showed src/apps/portal/content/CanvasWrapper.css plus existing ticket component light/dark CSS loading.
  • git diff --check origin/dev..HEAD passed.

Post-Merge Validation

  • Open the operator JetBrains-served portal URL after merge and verify /news/tickets no longer reports Failed to fetch dynamically imported module for tickets/MainContainer.mjs.

Commit

  • 5f65e3c9bfix(portal): restore shared timeline import paths (#12265)
neo-opus-ada
neo-opus-ada APPROVED reviewed on May 31, 2026, 8:51 PM

PR Review Summary

Status: Approved

🪜 Strategic-Fit Decision

Per §9 Strategic-Fit Step-Back:

  • Decision: Approve
  • Rationale: Approve (not Approve+Follow-Up) because the diff is a complete, correct, atomic unblock with no residual defects — the one forward-looking theming note is for other tickets (#12211/#12213), not a gap in this PR. §9.0 Cycle-1 Premise Pre-Flight: premise is valid (real runtime regression, concrete falsifier), source ticket #12265 is fresh and accurate, no ungraduated-upstream/anti-pattern/authority-bypass triggers fire.

Peer-Review Opening: Clean diagnosis and a minimal, correct fix — thank you for resisting the obvious trap (treating the browser's MainContainer.mjs dynamic-import error as a missing-file rather than a transitive 404). I independently reproduced the root cause from a separate angle and it converges exactly with yours. Approving.


🕸️ Context & Graph Linking

  • Target Epic / Issue ID: Resolves #12265 (foundation regression under epic #12204)
  • Related Graph Nodes: #12206 (regression source commit 6ee699b10), #12208 (content/Component.mjs move), portal-news, dynamic-import-regression, relative-import-depth, scss-theme-layering

🔬 Depth Floor

Challenge (follow-up concern, non-blocking): The fix is correct and complete for #12265, but it leaves no standing regression guard against a future move re-introducing the same depth bug. That is acceptable here (the import resolver/build catches it at load), but the upcoming view subs (#12211 Discussions, #12213 PR view) will add new Portal.view.news.* classes with new cls — those PRs must ship matching resources/scss/src/... (+ light/dark only when color-themed) so the rename/move keeps theme files honored. The operator emphasized this twice; flagging here so the epic lane carries it. Not a change request on this PR.

Independent completeness verification: A recursive relative-import scan of apps/portal surfaced exactly the two breaks this PR fixes; git show --stat 6ee699b10 confirms #12206 moved exactly {news/tickets → content}/CanvasWrapper.mjs + TimelineCanvas.mjs; content/Component.mjs (#12208) already imports at the correct depth-4 → no third latent break; reverse-reference grep found no other module importing content/* at a stale depth.

Rhetorical-Drift Audit (per guide §7.4):

  • PR description: framing matches the diff (claims exactly the two moved import paths; no overshoot)
  • Anchor & Echo summaries: no JSDoc changes; existing @class/@member blocks remain accurate
  • [RETROSPECTIVE] tag: none used; no inflation
  • Linked anchors: #12206/#12204 citations are accurate (verified via git history)

Findings: Pass.


🧠 Graph Ingestion Notes

  • [KB_GAP]: None. ESM ../ past-root → Failed to fetch dynamically imported module at the lazy boundary is correctly understood in the ticket + PR.
  • [TOOLING_GAP]: None observed in this PR's lifecycle.
  • [RETROSPECTIVE]: When a foundation sub moves a shared module to a shallower directory, relative framework imports must lose a ../ hop. A cheap, high-value future guard would be a lint/CI check that flags relative imports resolving above the repo root — would have caught this at #12206 time. (hypothesis — needs V-B-A before implementation.)

🎯 Close-Target Audit

  • Close-targets identified: #12265 (PR body Resolves #12265)
  • For each #N: #12265 carries bug, javascript, ai, regression — NOT epic-labeled. Valid leaf close-target. Syntax is newline-isolated. ✓

Findings: Pass.


🪜 Evidence Audit

The close-target ACs include observable runtime mount effect reachable only via a live portal (NL), so the evidence ladder applies.

  • PR body contains an Evidence: declaration line (Evidence: L3 (local browser + Neural Link runtime probe on the patched branch) → L3 required ...)
  • Achieved evidence (L3 NL mount + computed styles + clean console + CSS load) ≥ required (L3 runtime mount). The single residual (operator JetBrains URL post-merge) is correctly listed under ## Post-Merge Validation.
  • Two-ceiling distinction respected: author shipped at L3 by actually probing NL, not by sandbox-ceiling excuse.
  • No evidence-class inflation: I did not promote my own static checks to L3 — see Test-Execution audit below for what I personally ran.

Findings: Pass.


N/A Audits — 📑 📡 🔗

N/A across listed dimensions: pure 2-line app-level relative-import correction — no public/consumed contract surface (📑), no ai/mcp/server/*/openapi.yaml touched (📡), no skill/convention/MCP-tool/AGENTS surface touched (🔗).


🧪 Test-Execution & Location Audit

  • Branch checked out locally: No — I did not run checkout_pull_request. For a relative-import-depth fix the falsifier is deterministic and I verified it statically (import-graph resolution + git move-history), which is conclusive for this bug class; the author already provided L3 NL runtime mount evidence on the branch.
  • Canonical Location: No test files added/moved (none apply to a runtime import-path fix).
  • Code changed: verified no standing unit test covers module-load depth; none is reasonably addable beyond what the build already enforces.

Findings: No automated tests needed for this scope; runtime verification is the right gate and the author supplied it (L3). Honest note: I relied on static + git-history verification + the author's NL evidence rather than re-running NL myself.


📋 Required Actions

No required actions — eligible for human merge.


📊 Evaluation Metrics

  • [ARCH_ALIGNMENT]: 100 — I actively considered route-config drift, timeline-parser coupling, and the canvas-bridge sections-store contract, and confirmed none are touched; the fix only corrects import depth, preserving the #12206 shared-move shape.
  • [CONTENT_COMPLETENESS]: 100 — I considered missing @summary, missing Anchor & Echo, and a bare PR body; none apply — no API/JSDoc change is warranted and the PR body is a complete Fat Ticket (Deltas / Test Evidence / Post-Merge).
  • [EXECUTION_QUALITY]: 95 — 5 deducted: no standing regression guard prevents a future move from re-introducing the depth bug (low-value to add; the build/import resolver catches it). The fix itself is correct, symmetric across both files, and whitespace-aligned.
  • [PRODUCTIVITY]: 100 — all four ticket ACs met or appropriately deferred (the only open item is the correct post-merge operator-URL check); the tickets tab is unblocked.
  • [IMPACT]: 60 — substantive: restores a broken user-facing surface (/news/tickets) and unblocks the #12204 foundation the remaining subs build on; app-level, not framework-core, so below the major-subsystem (80) tier.
  • [COMPLEXITY]: 20 — Low: a 2-line relative-path correction across two app-level files; no new code paths, no cross-substrate integration, minimal cognitive load.
  • [EFFORT_PROFILE]: Quick Win — High ROI (unblocks a whole tab + epic foundation) at low complexity (2-line diff).

Approving. Nicely scoped — the restraint (no route/parser/canvas/SCSS churn) is exactly right for a stabilization fix.

Reviewed by Opus 4.8 (Claude Code)