Skip to content

chore: add frontend architecture governance baseline - #667

Merged
Astro-Han merged 3 commits into
devfrom
codex/frontend-architecture-governance
May 16, 2026
Merged

chore: add frontend architecture governance baseline#667
Astro-Han merged 3 commits into
devfrom
codex/frontend-architecture-governance

Conversation

@Astro-Han

@Astro-Han Astro-Han commented May 16, 2026

Copy link
Copy Markdown
Owner

Topology Update (2026-05-16)

Final base: dev.
Dependency status: foundation governance PR; no code PR needs to be stacked on this branch after the topology rewrite.
Review order: review first as the governance/report baseline, then review flat PRs and the single message-timeline stack.
Verification update: after review fixes, the reproducible inventory baseline is generated at 5da4d3d61 (fix: harden frontend inventory classification). Counts changed from the earlier draft because the script now includes root-level src/*.ts(x) files and keeps logic-bearing index.ts / pure-config candidates in the production ratchet set.


Summary

Add the frontend architecture governance baseline for packages/app/src and packages/ui/src:

  • canonical manifest home: .github/frontend-architecture-manifest.md
  • repeatable warn-only inventory script: script/frontend-inventory.mjs
  • root commands for the report: frontend:inventory and frontend:inventory:json

This PR does not refactor UI code, move imports, or change public runtime behavior.

Why

The UI rewrite work needs a shared, reviewable source of truth before more architecture slices start. The manifest captures the file-size baseline, owner lanes, exception schema, ratchet stages, and first PR stack boundaries so the next agent does not need chat context to continue.

Related Issue

Related to #599. Also references #601, #604, #605, #606, #595, #615, and #638 as owner lanes.

Architecture Boundary

Owner lane: #599 mainline / governance.

Base: dev.

Depends on: none.

Touched files:

  • .github/frontend-architecture-manifest.md
  • script/frontend-inventory.mjs
  • package.json

Architecture effect:

  • boundary created
  • owner map established
  • report schema documented
  • warn-only file-size ratchet command added
  • approved-exception schema documented

Behavior unchanged: yes. This is governance/reporting only.

Public write status: PR body only. No issue body/comment was created or updated.

Human Review Status

Pending. A human should make the final merge decision after reviewing the final diff and verification evidence.

Review Focus

  • Is .github/frontend-architecture-manifest.md acceptable as the canonical tracked home, given docs/ is local-only in this checkout?
  • Are the owner-lane heuristics conservative enough for a warn-only baseline?
  • Does the PR stay within the Governance PR boundary and avoid business UI changes?

Risk Notes

Low runtime risk. The script is warn-only and is not wired into CI as a hard gate. The main risk is classification drift; the manifest records schema version 1 and says future metric changes must use a new schema version instead of mixing baselines.

How To Verify

node --check script/frontend-inventory.mjs: ok
bun run frontend:inventory: ok, warn-only summary produced; totalTrackedTsTsx=682, production=356, over500=26
node script/frontend-inventory.mjs --format json: ok; baseline commit `5da4d3d61`, totalTrackedTsTsx=682, production=356, productionOver200=80, productionOver500=26; packages/ui/src/pierre/index.ts is production, packages/app/src/index.ts and packages/ui/src/theme/index.ts remain facade
bun run frontend:inventory -- --format markdown --max-rows nope: ok, invalid max-rows falls back to default
pure-config audit: ok, no pure-config records contain => or function
git diff --check: ok
bun run typecheck: ok, 8 packages successful

Screenshots or Recordings

Not applicable. No visible UI changes.

Checklist

  • Human review status is stated above as pending, approved, or not required
  • I linked the related issue, or stated why there is no issue
  • This PR has type, primary area, and priority labels, or I requested maintainer labeling
  • I described the review focus and any meaningful risks
  • I listed the relevant verification steps and the key result for each
  • I did not introduce unrelated refactors, dependencies, generated files, or file changes beyond the stated scope
  • I manually checked visible UI or copy changes when needed, with screenshots or recordings
  • I considered macOS and Windows impact for platform, packaging, updater, signing, paths, shell, or permissions changes
  • I called out docs, release notes, dependencies, permissions, credentials, deletion behavior, generated content, or local file changes when relevant
  • I reviewed the final diff for unrelated changes and suspicious dependency changes
  • I am targeting dev, and my PR title and commit messages use Conventional Commits in English

Summary by CodeRabbit

Release Notes

  • New Features

    • Added frontend:inventory and frontend:inventory:json npm scripts to generate reports on frontend file metrics, classifications, and ownership assignments.
  • Documentation

    • Added frontend architecture governance manifest defining baseline metrics, owner responsibilities, and workflow guidelines.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 16, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@Astro-Han has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 23 minutes and 16 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8f281946-0762-4590-a1d6-c5da87e8b0d8

📥 Commits

Reviewing files that changed from the base of the PR and between d45ab7b and 57032bf.

📒 Files selected for processing (3)
  • .github/frontend-architecture-manifest.md
  • package.json
  • script/frontend-inventory.mjs
📝 Walkthrough

Walkthrough

This PR establishes a frontend architecture governance system by introducing a canonical manifest that specifies inventory rules, schema, metrics, and owner lanes, paired with a CLI tool that scans TypeScript/TSX files, classifies them by production vs. visibility-only status, assigns owner lanes, and generates JSON or markdown inventory reports.

Changes

Frontend Architecture Governance Inventory

Layer / File(s) Summary
Frontend Architecture Governance Manifest
.github/frontend-architecture-manifest.md
Defines governance baseline (status, baseline commit, default branch, master owner, closed-area constraints), inventory command behavior and warn-only mode, JSON report schema with versioning and field meanings, baseline metrics with production burn-down tables, owner-lane definitions and ratchet stages/guards, exception schema requirements, and PR stack/handoff rules for sequencing work.
Inventory Tool Implementation and Registration
script/frontend-inventory.mjs, package.json
CLI script scans repo frontend files via git, reads contents, classifies each file as production or visibility-only based on regex and content heuristics (test/spec, storybook, i18n, generated assets, pure config, facade exports), assigns owner lanes (or defers to "other/deferred" if no match), calculates physical LOC, derives status buckets, aggregates per-lane counts, and outputs JSON, markdown table (limited by --max-rows), or console summary with stderr warning for files over 500 LOC. Two npm scripts expose the tool: frontend:inventory and frontend:inventory:json.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A manifest springs forth, so crisp and fair,
With lanes and rules laid plainly in the air.
The scanner hops through files with care,
Counting lines and sorting debt with flair—
hop hop to governance, beyond compare! 🏗️

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'chore: add frontend architecture governance baseline' clearly and concisely summarizes the main change—adding governance documentation and baseline tooling for frontend architecture.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description comprehensively covers all required template sections with detailed context, verification steps, and risk assessment.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/frontend-architecture-governance

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 and usage tips.

@github-actions github-actions Bot added the documentation Improvements or additions to documentation label May 16, 2026

@github-actions github-actions 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.

Suggested priority: P2 (includes non-doc, non-test paths outside the low-risk bucket).

P1/P0 are reserved for maintainer confirmation. Please relabel manually if this is a release blocker, security issue, data-loss risk, or updater/runtime failure.

@Astro-Han Astro-Han added task Narrow execution, audit, spike, migration, tracking, or upstream follow-up work tech-debt Supplemental cleanup, maintainability, architecture, test, or quality debt context app Application behavior and product flows ui Design system and user interface P2 Medium priority labels May 16, 2026

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request establishes a frontend architecture governance framework by introducing a manifest document and an inventory script to track file sizes and ownership across the project. The feedback provided focuses on improving the accuracy of the inventory script's file classification logic. Specifically, suggestions were made to refine the comment-stripping regex to handle trailing comments, broaden the detection of import statements in facade files, and strengthen the logic-detection heuristics to ensure that files containing functional code are not misclassified as pure configurations.

Comment thread script/frontend-inventory.mjs
Comment thread script/frontend-inventory.mjs Outdated
Comment thread script/frontend-inventory.mjs Outdated
@Astro-Han

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 16, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
script/frontend-inventory.mjs (2)

335-335: ⚡ Quick win

Consider adding error handling for git and file operations.

The script uses execFileSync and readFileSync without try/catch blocks. If git is unavailable, the repo isn't checked out, or a file is deleted between listing and reading, the script will crash with an uncaught exception.

For a warn-only governance tool this is acceptable, but adding graceful error handling would improve the developer experience.

♻️ Proposed error handling

Wrap the git command:

 function listFrontendFiles() {
+  try {
     const stdout = execFileSync("git", ["ls-files", ...FRONTEND_PATHS], { encoding: "utf8" }).trim()
     return stdout ? stdout.split("\n").filter(Boolean).sort() : []
+  } catch (err) {
+    console.error("Error: git ls-files failed. Ensure you are in a git repository.")
+    console.error(err.message)
+    process.exit(1)
+  }
 }

And wrap file reads:

 const records = files.map((path) => {
+  try {
     const content = readFileSync(path, "utf8")
+  } catch (err) {
+    console.error(`Error reading ${path}: ${err.message}`)
+    return null
+  }
     // ... rest of mapping
-})
+}).filter(Boolean)

Also applies to: 342-342

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@script/frontend-inventory.mjs` at line 335, Wrap the execFileSync call that
runs git ls-files (the line calling execFileSync with FRONTEND_PATHS) in a
try/catch so failure to run git returns an empty string or list and logs a
console.warn (or processLogger.warn) instead of throwing; likewise wrap
subsequent readFileSync calls that read each listed file in try/catch so a
missing/deleted file logs a warning and is skipped. Ensure you only call .trim()
if stdout is a string, and propagate an empty array/result when git or file
reads fail so the script continues gracefully.

157-160: ⚡ Quick win

Consider validating numeric arguments.

If a non-numeric value is passed to --max-rows, Number() will return NaN, which could cause unexpected behavior in slice(0, maxRows) on line 431.

🛡️ Proposed validation
 if (arg === "--max-rows") {
-  out.maxRows = Number(argv[index + 1] ?? out.maxRows)
+  const val = Number(argv[index + 1] ?? out.maxRows)
+  out.maxRows = Number.isNaN(val) ? out.maxRows : val
   index += 1
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@script/frontend-inventory.mjs` around lines 157 - 160, The code sets
out.maxRows = Number(argv[index + 1] ?? out.maxRows) without validating, which
can produce NaN and break later slice(0, maxRows); change the parsing to
explicitly parse and validate the next argv token (e.g., use parseInt/Number)
and check Number.isFinite or !Number.isNaN and positive integer before assigning
to out.maxRows (otherwise keep the previous value or throw a clear error);
update the argument-handling block that references arg, argv, index and
out.maxRows so invalid inputs are rejected or defaulted safely prior to the
later slice usage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@script/frontend-inventory.mjs`:
- Line 335: Wrap the execFileSync call that runs git ls-files (the line calling
execFileSync with FRONTEND_PATHS) in a try/catch so failure to run git returns
an empty string or list and logs a console.warn (or processLogger.warn) instead
of throwing; likewise wrap subsequent readFileSync calls that read each listed
file in try/catch so a missing/deleted file logs a warning and is skipped.
Ensure you only call .trim() if stdout is a string, and propagate an empty
array/result when git or file reads fail so the script continues gracefully.
- Around line 157-160: The code sets out.maxRows = Number(argv[index + 1] ??
out.maxRows) without validating, which can produce NaN and break later slice(0,
maxRows); change the parsing to explicitly parse and validate the next argv
token (e.g., use parseInt/Number) and check Number.isFinite or !Number.isNaN and
positive integer before assigning to out.maxRows (otherwise keep the previous
value or throw a clear error); update the argument-handling block that
references arg, argv, index and out.maxRows so invalid inputs are rejected or
defaulted safely prior to the later slice usage.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 98d1e51f-5f68-4554-be57-aae374b8a902

📥 Commits

Reviewing files that changed from the base of the PR and between eb80bed and d45ab7b.

📒 Files selected for processing (3)
  • .github/frontend-architecture-manifest.md
  • package.json
  • script/frontend-inventory.mjs

@Astro-Han

Copy link
Copy Markdown
Owner Author

Handled the 2 CodeRabbit nitpicks in 5da4d3d: --max-rows now ignores invalid values instead of passing NaN into slicing, and inventory git/file read failures now exit with a clear error message. I kept failures as nonzero exits instead of returning an empty report so the governance baseline cannot silently report incomplete data.

@Astro-Han

Copy link
Copy Markdown
Owner Author

Fixed the baseline mismatch in 57032bf. The manifest now marks 5da4d3d61 as the baseline commit, which is the commit where the corrected inventory script generated the 682/356/80/26 counts. The manifest also explains why this replaces the earlier eb80bed96 draft baseline: the review fix expanded root-level src/*.ts(x) coverage and moved logic-bearing index.ts / pure-config candidates back into the production ratchet set. Re-verified node script/frontend-inventory.mjs --format json, bun run frontend:inventory, git diff --check, and bun run typecheck.

@Astro-Han
Astro-Han merged commit e738e43 into dev May 16, 2026
25 of 27 checks passed
@Astro-Han
Astro-Han deleted the codex/frontend-architecture-governance branch May 16, 2026 07:50
Astro-Han added a commit that referenced this pull request May 16, 2026
Goal:
Add a shared UI tool-name contract so app and ui code stop duplicating high-risk tool id literals while preserving current rendering behavior.

Scope:
- Add @opencode-ai/ui/tool-contract exports for current shared tool names and the legacy agent name.
- Replace duplicated tool-name literals in UI message/tool rendering and app status extraction paths.
- Add app/ui contract tests for public import compatibility and opencode tool id drift.
- Keep behavior unchanged for legacy "task" rendering and current agent/web/todo/question tool names.
- Update the CI workflow structure test to account for the existing unit-ui-focused blocking aggregate job introduced on dev.

Verification:
- bun test src/components/tool-contract.test.ts
- bun test src/ui-tool-contract.test.ts
- bun test test/github/ci-workflow.test.ts
- bun run typecheck
- git diff --check
- Temporary Tool.define drift check: changing Tool.define("todowrite") while keeping permission "todowrite" makes the contract test fail, then passes after revert.
- GitHub checks green, including ci, unit-opencode, unit-ui-focused, desktop smoke, e2e artifacts, perf-probe-baseline, CodeQL, and CodeRabbit.
- reviewThreads unresolved = 0

Review follow-ups:
- Addressed CodeRabbit nitpick by making tool id matching quote-agnostic.
- Tightened the same test beyond raw string matching so permission or copy strings cannot mask Tool.define/id drift.
- Fixed the CI workflow test drift exposed after rebasing on #667.

Residual risk:
- The contract test is still source-based because opencode does not expose stable tool ids as an importable test surface yet.
Astro-Han added a commit that referenced this pull request May 16, 2026
Goal:
Extract the timeline staging owner out of MessageTimeline as the first #601 message-flow stack root.

Scope:
- Move createTimelineStaging into packages/app/src/pages/session/session-timeline-staging.ts.
- Keep MessageTimeline wired with the same sessionKey, turnStart, renderedUserMessages, and { init: 10, batch: 3 } config.
- Add browser-condition staging tests for non-windowed render, staged batches, active-session message growth, completed-session backfill, and session switch rAF cancellation.
- Preserve active staging when the same session receives more messages mid-stage so the historical window does not pop to full render.
- Add the concrete #670 boundary to the frontend architecture manifest.

Verification:
- bun --cwd packages/app test --preload ./happydom.ts src/pages/session/session-timeline-staging.test.ts src/pages/session/use-session-history-window.test.ts src/pages/session/session-timeline-scroll-controller.test.ts src/pages/session/session-timeline-scroll-anchors.test.ts -> 1110 pass / 2674 expects
- bun run typecheck -> 8 successful tasks
- git diff --check
- GitHub checks green, including ci, unit-app, unit-opencode, unit-desktop, unit-ui-focused, desktop smoke, e2e artifacts, perf-probe-baseline, CodeQL, and CodeRabbit.
- reviewThreads unresolved = 0

Review follow-ups:
- Fixed Gemini staging-pop thread and resolved it after replying in-thread.
- Added the missing manifest entry that the PR body claimed.
- Refreshed PR body verification after #667 and #669 landed on dev.

Residual risk:
- Electron manual verification was not run because this is scoped to behavior-preserving extraction plus tests, with no visible UI or copy change.
@coderabbitai coderabbitai Bot mentioned this pull request May 17, 2026
11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation P2 Medium priority task Narrow execution, audit, spike, migration, tracking, or upstream follow-up work tech-debt Supplemental cleanup, maintainability, architecture, test, or quality debt context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant