Skip to content

ci: make the Astryx surface inventory a regenerate-and-diff gate - #3078

Merged
Astro-Han merged 2 commits into
apache:mainfrom
1625567290:fix/astryx-surface-inventory-ci
Aug 16, 2026
Merged

Astro-Han merged 2 commits into
apache:mainfrom
1625567290:fix/astryx-surface-inventory-ci

Conversation

@1625567290

Copy link
Copy Markdown
Contributor

Summary

The surface inventory is a generated pair of files. The old check only asserted disk → .paths, did not fail a Markdown row whose file was gone, and was not on any CI path.

The check now regenerates both artifacts in memory and compares them to the committed files. A deleted surface, a hand-edited half, or column drift all fail the same way. npm run astryx:surface-inventory:write is the fix.

CI runs that check on a cheap astryx_surface job when renderer/UI product files or the inventory scripts/artifacts change. Docs-only inventory edits also select it; a runtime-only change does not.

Fixes #3064

Verification

  • npm run astryx:surface-inventory — ok (186 files, 1 exclusion)
  • Appending a missing path to .paths fails with in .paths but not on disk
  • planTests(['docs/astryx-surface-file-inventory.md']) → astryxSurface: true, code: false
  • planTests(['apps/desktop/src/renderer/app-shell.tsx']) → astryxSurface: true
  • planTests(['packages/runtime/src/agent-run.ts']) → astryxSurface: false
  • planTests(['packages/ui/src/__tests__/foo.test.ts']) → astryxSurface: false

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope:

Grok authored the implementation and this PR description.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

The check only compared disk to .paths and never ran in CI, so a
deleted surface could linger in the Markdown table and a new file
could miss both halves. Compare committed artifacts to a fresh
generator run and schedule that check when surface files or the
inventory move.

Fixes apache#3064

Generated-by: Grok
@coderabbitai

coderabbitai Bot commented Aug 15, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 76a351f6-fa1f-43cd-bcd2-74c1bce9972e

📥 Commits

Reviewing files that changed from the base of the PR and between 790a9bd and a36b0ba.

📒 Files selected for processing (2)
  • .github/workflows/ci.yml
  • scripts/generate-astryx-surface-inventory.mjs
🚧 Files skipped from review as they are similar to previous changes (2)
  • scripts/generate-astryx-surface-inventory.mjs
  • .github/workflows/ci.yml

📝 Walkthrough

What this solves

The PR replaces the one-directional Astryx inventory check with a regenerate-and-compare check. It detects:

  • Deleted surfaces listed in .paths or Markdown.
  • Manually edited inventory artifacts.
  • Column or formatting drift.
  • Extra or missing generated paths.

It adds astryx:surface-inventory for validation and astryx:surface-inventory:write for regeneration. CI runs the check when relevant renderer, UI product, inventory, or inventory documentation files change. Runtime-only and unrelated UI test changes do not trigger the job.

Source of truth

This extends the existing inventory generator. renderAstryxSurfaceInventory(repoRoot) produces both artifacts in memory. The check compares that output byte-for-byte with the committed files. It does not create a parallel inventory path.

The generator now accepts an explicit repoRoot, so CI analysis uses the checkout supplied by the caller instead of a module-global checkout path.

Scope and complexity

The solution is the smallest coherent approach described by the current diff. It reuses the existing generator for both writing and validation. The in-memory render avoids temporary file writes during checks and keeps both artifacts under one source of truth.

The CI change adds targeted path detection, a conditional astryx_surface job, Node.js 24 setup, and the required read-only checkout permissions. The job also avoids persisted checkout credentials.

The removed dynamic-import, subprocess, required-surface, Markdown-row, and family-batch checks should remain deleted because generated-artifact comparison covers the resulting files directly. No further deletion is evident without reducing regression coverage.

Risks and validation

Byte-for-byte comparison makes generator ordering, formatting, column, and path changes visible. Contributors must regenerate the committed artifacts after intended inventory changes.

The path classifier must include renderer and UI product sources, inventory scripts, inventory artifacts, and inventory documentation. It must exclude runtime-only and unrelated UI test changes as intended.

The CI job uses contents:read and avoids persisted checkout credentials. These settings reduce credential exposure but still require review of the workflow permissions and checkout behavior.

The available evidence confirms the new npm scripts, renderer export, comparison logic, path classification, and conditional CI job in the current diff. Required check results remain unverified without direct CI output.

Review-relevant risks

No protected-area effect was identified in the current diff. The changes affect CI configuration, inventory tooling, generated artifacts, and developer-facing npm scripts. The person performing the merge must review the final diff, and a maintainer makes the final determination.

Walkthrough

The PR centralizes Astryx inventory rendering, adds byte-for-byte artifact validation, detects relevant changes in CI planning, and runs the check in a conditional GitHub Actions job.

Changes

Astryx inventory enforcement

Layer / File(s) Summary
Render and validate inventory artifacts
scripts/generate-astryx-surface-inventory.mjs, scripts/check-astryx-surface-inventory.mjs
The generator exposes rendered Markdown, paths, file lists, exclusions, and severity totals. The checker compares both generated artifacts with committed files and reports drift.
Detect relevant changes and expose the CI flag
scripts/ci-test-plan.mjs, package.json
Test planning detects Astryx surface changes and emits astryx_surface. NPM scripts run the inventory check or write the generated artifacts.
Run the inventory check in CI
.github/workflows/ci.yml
The changes job exposes the inventory flag. A conditional Node.js 24 job runs npm run astryx:surface-inventory when the flag is true.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to a36b0

The PR makes the generated Astryx surface inventory fail CI when it is stale or inconsistent and runs the check for relevant changes; no actionable merge-blocking risk remains beyond normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant ChangedFiles
  participant ci-test-plan
  participant GitHubActions
  participant checkAstryxSurfaceInventory
  participant renderAstryxSurfaceInventory

  ChangedFiles->>ci-test-plan: classify changed paths
  ci-test-plan-->>GitHubActions: emit astryx_surface
  GitHubActions->>checkAstryxSurfaceInventory: run when astryx_surface is true
  checkAstryxSurfaceInventory->>renderAstryxSurfaceInventory: render inventory artifacts
  renderAstryxSurfaceInventory-->>checkAstryxSurfaceInventory: return Markdown and paths
  checkAstryxSurfaceInventory-->>GitHubActions: pass or report artifact drift
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: enforcing the Astryx surface inventory through CI regeneration and diffing.
Description check ✅ Passed The description includes the required summary, issue reference, verification results, AI disclosure, checklist, and behavior change.
Linked Issues check ✅ Passed The changes satisfy #3064 by adding symmetric byte-for-byte validation, an npm check script, and changes-gated CI execution.
Out of Scope Changes check ✅ Passed The changes remain within the inventory validation and CI objectives, including related permissions, credential, and repository-root fixes.
Ai Use Disclosure ✅ Passed The PR selects substantive generative use and names Grok and its scope. Both introduced commits have standalone Generated-by: Grok trailers.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai 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.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 02b1bf28-70c3-413c-abc4-b6c63aab633f

📥 Commits

Reviewing files that changed from the base of the PR and between 64dfd6d and 790a9bd.

📒 Files selected for processing (5)
  • .github/workflows/ci.yml
  • package.json
  • scripts/check-astryx-surface-inventory.mjs
  • scripts/ci-test-plan.mjs
  • scripts/generate-astryx-surface-inventory.mjs

Comment thread .github/workflows/ci.yml
Comment thread scripts/generate-astryx-surface-inventory.mjs
Give the inventory job contents:read and stop persisting checkout
credentials. Analyze files from the repoRoot passed to the renderer
instead of the module-global checkout path.

Generated-by: Grok
@likun666661

Copy link
Copy Markdown
Member

I think the problem statement needs one more step before we add enforcement.

The issue demonstrates that the generated inventory can drift, but it does not demonstrate that this drift causes an observable failure: who consumes this inventory, what decision or gate depends on it, and what concrete cost or risk follows when it is stale? “A generated file is inconsistent” is a state; “the check is not wired into CI” is a missing control. Neither is necessarily a product or engineering problem unless the artifact has a clear consumer and correctness requirement.

That distinction matters here because .paths appears to have no in-repository consumer other than the generator/checker themselves. From first principles, the source files and generator are authoritative; both Markdown and .paths are derived views. From an Occam razor perspective, the options should be evaluated in this order:

  1. If the inventory has no active consumer or decision value, delete it.
  2. If only human-readable documentation is needed, keep one generated artifact and remove the duplicate .paths representation.
  3. If the inventory really drives an audit, migration plan, release decision, or other governance process, document that consumer and failure cost; then a regenerate-and-diff CI gate is justified.

The implementation is a clean solution to “how do we prevent inventory drift,” but the PR/issue should first establish “why is preventing this drift worth permanent CI and maintenance cost?” Without that evidence, this risks enforcing the consistency of an artifact that may not need to exist.

@1625567290

Copy link
Copy Markdown
Contributor Author

Checked the consumer question against the current tree.

.paths is only read by scripts/generate-astryx-surface-inventory.mjs and scripts/check-astryx-surface-inventory.mjs. Nothing in runtime, tests, or CI (before this PR) imports it. The Markdown file is cited as review prior art in docs/astryx-alignment-inventory.md and docs/frontend-architecture-astryx-review-2026-08-09.md; it is not a gate any product path consults.

So the issue showed two derived artifacts disagreeing, not an observable product failure. Source files plus the generator are the authority. A regenerate-and-diff job is a control for that derived pair, not a bug fix.

If maintainers want a living human audit, one generated Markdown file is enough and .paths can go. If there is no ongoing audit consumer, both artifacts can go. I will not treat this PR as merge-required until that consumer is named.

Generated-by: Grok

@Astro-Han Astro-Han 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.

Fast-path self-merge per AGENTS.md: low impact, easy to reverse, does not touch protected areas (Runtime Host execution authority, @maka/eval semantics, public Eval CLI, security, licensing, releases, governance), and passes all required checks. Human contributor yuhan reviewed the final diff and chose the fast path.

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.

Astryx surface inventory check is one-directional and not wired into CI

3 participants