Skip to content

[V2:14] Add Editorial Command Integration#28

Open
ritorhymes wants to merge 11 commits into
eips-wg:masterfrom
ritovision:v2/14-editorial-integration
Open

[V2:14] Add Editorial Command Integration#28
ritorhymes wants to merge 11 commits into
eips-wg:masterfrom
ritovision:v2/14-editorial-integration

Conversation

@ritorhymes

@ritorhymes ritorhymes commented May 5, 2026

Copy link
Copy Markdown
Contributor

Part of V2: Multi-repo local build system.

Summary

This PR adds the first user-facing consumer of the proposal-selection foundation: build-eips editorial lint and build-eips editorial check. Editorial commands require exactly one selector mode. Explicit targets and --batch files resolve strictly through proposal numbers or repo-relative paths and reject invalid number-like inputs as editorial errors, while --working-tree/--against-upstream are non-strict modes that filter changed paths down to supported proposal markdown.

The editorial lint command and the editorial-selected lint phase of editorial check run eipw against the prepared merged source tree, so cross-repo EIP/ERC references resolve the same way they do during local builds. Normal build, check, and serve commands do not accept eipw source or rule flags; prepared runtime source setup merges the local active checkout with selected sibling sources without fetching the active upstream. The PR does not add --only rendering or [render].only, so the meaningful review surface is selector semantics, strict versus non-strict target handling, prepared-source linting, workspace-local sibling policy, eipw ownership, active-upstream fetch boundaries, and the runtime handoff for check.

  • Add build-eips editorial lint and build-eips editorial check.
  • Add editorial selectors for explicit proposal targets, --batch, --working-tree, and --against-upstream.
  • Require exactly one editorial selector mode per command.
  • Add editorial.rs to resolve, normalize, dedupe, and validate editorial proposal targets.
  • Resolve numeric editorial selectors through the proposal path helpers from V2:13.
  • Support batch files with blank lines and comments.
  • Run editorial lint through eipw using selected repo-relative proposal paths in the prepared merged source tree.
  • Run the editorial-selected eipw lint phase before markdown preprocessing or Zola.
  • Resolve cross-repo EIP/ERC proposal references through the merged EIPs/ERCs content tree.
  • Treat local editorial lint and editorial check as workspace-local sibling workflows by default.
  • Prepare explicit, batch, and working-tree editorial lint without fetching the active upstream; keep upstream fetch for --against-upstream.
  • Prepare runtime build, check, and serve sources from the local active checkout plus sibling merge without fetching the active upstream.
  • Keep active-upstream fetches in changed-file comparison and editorial --against-upstream target selection.
  • Keep --remote-siblings as a sibling-source override without forcing clean active-repo materialization.
  • Run editorial check by linting selected targets, then re-entering the prepared runtime check pipeline.
  • Reject untracked explicit or batch targets that are not materialized into the prepared source tree.
  • Scope eipw source and rule selection to editorial commands; normal build, check, and serve do not accept eipw flags.
  • Accept linked-worktree repo roots where .git is a file.
  • Add editorial CLI, execution-policy, selector, prepared-source, and runtime materialization handoff tests.

Review Notes

This PR is the first user-facing consumer of the proposal-selection foundation from V2:13. It adds editorial commands but does not add --only rendering or [render].only; targeted rendering remains scoped to V2:15-V2:16.

Editorial selectors are intentionally strict when the user provides explicit targets or a batch file. Numeric selectors such as 4, 004, or 0004 resolve to the actual proposal markdown path in the active repo. Repo-relative paths are canonicalized and must stay inside the active repo. Invalid number-like selectors such as 0, +4, or 4,5 fail with an editorial-specific error instead of being treated as paths.

--working-tree and --against-upstream are non-strict selector modes. They collect candidate changed paths first, then filter to supported proposal markdown paths. If no proposal files are selected in non-strict mode, editorial lint logs that result and skips eipw; explicit-target and batch modes still error when nothing resolves. For editorial check, a no-target non-strict selector skips the eipw lint step but still runs the prepared site check.

Editorial commands require a workspace-local theme because eipw reads its configuration from the local theme checkout. The lint phase prepares the active repo with sibling repos and runs eipw against that prepared source tree. Preparation fetches the active upstream only for --against-upstream target selection. Explicit, batch, and working-tree lint merge local sibling sources without fetching the active upstream.

Execution policy treats both local editorial lint and editorial check as workspace-local sibling workflows. The lint phase prepares and merges the active repo with sibling repos, then runs eipw against that prepared source tree. This keeps eipw as a single-tree linter while allowing EIP-to-ERC and ERC-to-EIP references to resolve consistently with local builds. --remote-siblings only overrides sibling source selection; it does not force clean active-repo materialization. Sibling repository fetches still happen during merge; with workspace-local siblings these are local file:// reads, while --remote-siblings continues to fetch sibling repos over the network.

editorial lint stops after source preparation and eipw. It does not run proposal metadata generation, markdown preprocessing, content pruning, Zola check, or Zola build. editorial check uses the same prepared-source lint phase for user-selected targets, then continues into the existing prepared site check pipeline from V2:10. The site check phase prepares runtime sources, preprocesses markdown, and runs Zola without an additional eipw pass.

Because eipw reads from the Git-materialized prepared source tree, untracked explicit or batch targets are rejected with a clear error instead of being linted directly from the raw working tree. Tracked dirty files are materialized into the prepared tree.

Linked-worktree roots are accepted when .git is a file, not only when .git is a directory. That keeps editorial commands usable from git worktree add checkouts, where .git points back to the parent Git directory.

The eipw wrapper does not own user source selection or the --no-lint kill switch. lint::eipw receives an explicit source list from its caller, and lint::CmdArgs keeps only output format and rule-level filters: --no-default-lints, --deny, --warn, and --allow.

Shared eipw args do not accept positional source paths. Editorial lint targets come from editorial selector modes, and normal build, check, and serve commands do not expose eipw source or rule flags.

Verification

  • Review src/cli.rs for the editorial lint and editorial check command surface, selector args, runtime operation mapping, and rejected command/flag forms.
  • Review src/editorial.rs for selector-mode validation, batch parsing, numeric selector normalization, path canonicalization, strict versus non-strict validation, working-tree selection, upstream selection, lint dispatch, and runtime handoff.
  • Review src/execution.rs for editorial theme requirements and the local-first execution policy used by editorial lint and editorial check.
  • Review src/lint.rs for the eipw API accepting caller-provided sources, plus the absence of positional source args and --no-lint.
  • Review src/main.rs for editorial command dispatch, lint execution, and prepared-check handoff.
  • Review src/pipeline.rs for Prepared::prepare using clone_src().merge() without fetching active upstream or running eipw.
  • Review src/git.rs for SourceOnly::merge, shared sibling merge behavior, local +HEAD sibling fetches, and ignored-path protection.
  • Review editorial tests for explicit numeric selectors, batch files, repo-relative paths, invalid number-like selectors, non-strict filtering, and working-tree runtime materialization.
  • Review prepared-source editorial tests for cross-repo EIP/ERC reference resolution, sibling-only target rejection, untracked target handling, and dirty materialization.
  • Review no-fetch editorial tests using the unreachable-upstream fixture: explicit lint, batch lint, and working-tree lint succeed without fetching the active upstream; --against-upstream still fails at upstream fetch.
  • Review prepared-runtime no-fetch tests for build/check/serve source preparation, remote-sibling source preparation, and the editorial-check site phase.
  • Review control tests showing changed and editorial --against-upstream still require active upstream, while normal build/check/serve reject eipw-only flags.
  • Manually verified editorial lint content/07713.md -D markdown-refs -D markdown-link-status passes with cross-repo ERC references resolved and emits no fetching latest <title> repository active-upstream log during the lint phase.
  • Manually verified editorial check content/07713.md -D markdown-refs -D markdown-link-status reaches the prepared-source lint path and passes on this branch.

Closes ethereum/EIPs#8689.

@SamWilsn

Copy link
Copy Markdown
Contributor

No code review yet, but from today's demo:

Would ./build-eips editorial lint 1234 make sense as ./build-eips lint --only 1234 for consistency with serve?

@ritorhymes

Copy link
Copy Markdown
Contributor Author

No code review yet, but from today's demo:

Would ./build-eips editorial lint 1234 make sense as ./build-eips lint --only 1234 for consistency with serve?

I think there are two separate questions here:

  1. Should lint should require the editorial prefix?
  2. Should the proposal number be positional or passed through --only?

For the first question, I think the canonical command makes sense under the editorial prefix because editorial lint belongs next to editorial check, and the shared prefix gives us a clean namespace for editorial operations without inventing separate top-level names like editorial-check to avoid collision with check. It also reflects that editorial commands are a different workflow from site build/serve commands, rather than just another way to build the site.

That said, EIP linting frequency is likely going to be common enough to justify a top-level convenience shortcut. So I like the idea of having ./build-eips lint 1234 as shorthand for ./build-eips editorial lint 1234, while keeping the editorial namespace as the canonical structure.

For the second question, I don't think requiring the --only flag makes sense here because the scope is basically the opposite from the site build process. For site building, everything is included by default so --only is used to move against that premise and become selective. For linting, it's selective by default already and targets a specific proposal or small set of proposals, so adding the flag is redundant.

However, because EIP linting is a special case in that it may be used with routine frequency (it may honestly be the only command many people run after setting up the workspace), it may be worth making the parser forgiving here in case there is confusion with the site building --only flag. We could accept --only as an alias for the positional proposal selector, so ./build-eips lint --only 1234 behaves the same as ./build-eips lint 1234. I would not make that the documented form; it would mostly be there so users carrying over the site-building mental model do not hit an unnecessary error.

I think those aliases would be good to include. What do you think of that?

Add workspace-local `.build-eips.toml` loading and starter configuration. Introduce `config::ActiveRepo` to load the selected checkout’s `Build.toml`, validate explicit `-C` roots, and expose active repository context to later commands. Keep source materialization, initialization, and diagnostics in their owning later branches.
Add clean and dirty source materialization for the active repository and sibling content. Use `config::RepositoryUse` throughout the runtime path, preserve tracked working-tree materialization and `index_path`, and reject dirty active manifests in clean modes. Build, check, and serve prepare sources without fetching the active upstream; `changed` retains upstream fetching for comparison.
Add workspace initialization from the selected active `Build.toml`. Clone missing sibling repositories from declared locations and initialize a missing theme checkout from the manifest repository and pin. Preserve existing usable checkouts and fail without deleting unusable paths. Write `.build-eips.toml` only when absent and generate `WORKSPACE.md` for the initialized workspace.
Add `build-eips doctor` for validating workspace configuration, active `Build.toml`, managed sibling repositories, the local theme checkout, and required tools. Report ok/warn/fail diagnostics; invalid active manifests and unusable theme configuration fail, while expected sibling and theme-pin conditions can warn. Keep diagnostics read-only and leave execution and runtime behavior to later branches.
Resolve build, check, and serve source policy around local active sources, clean mode, remote siblings, build roots, and base URL precedence. Keep `--clean` and `--remote-siblings` as source controls and limit `--only` to supported local dirty modes. Route runtime commands through one resolved execution policy.
Run Zola with the editable `workspace/theme` checkout. Materialize tracked local theme files into prepared `themes/eips-theme`, load Zola and eipw configuration from that local checkout, and keep runtime commands independent of manifest network access.
Add prepared runtime build pipeline. Materialize active and sibling sources according to resolved execution policy, preprocess merged proposal content, prepare the local theme mount, and invoke runtime checks and rendering from `pipeline.rs`. Keep serve watch and sync behavior in the serve runtime branch.
Add server binding resolution and serve-only host/port flags for local Zola serve commands.

Run Zola serve with the resolved server binding, optional base URL override, fast/force serve flags, and generated output directory.

Add dirty serve watching for dirty active-repo paths and local theme changes. Clean mode disables active-repo sync but keeps theme sync.
Add build-eips preview for serving the existing resolved output directory without rebuilding or starting dirty sync.

Reuse server binding resolution and preview-only host/port flags, and report missing output before binding the local server.

Add a tiny_http static file server with safe path resolution, index-file fallback, basic content types, and preview path tests.
Add proposal number parsing, proposal path classification, and content-path helpers for flat and directory proposal layouts.

Introduce the proposal-selection data needed by later editorial and targeted-rendering commands while leaving user-facing render selection, render-plan construction, and targeted rendering behavior to their owning later branches.
Add `build-eips editorial lint` and `build-eips editorial check` as the first user-facing proposal-selection commands.

Keep eipw options scoped to editorial lint/check. Normal build, check, and serve prepare runtime sources, preprocess markdown, and run Zola without carrying eipw source-selection flags.

Run editorial-selected eipw lint against the prepared merged source tree so cross-repo EIP/ERC references resolve through the same content layout used by local builds.

Prepare runtime sources from the local active checkout, merge sibling repositories, and keep active-upstream fetches in changed-file comparison and editorial `--against-upstream` target selection.
@ritorhymes ritorhymes force-pushed the v2/14-editorial-integration branch from a4577b6 to c811fe8 Compare June 21, 2026 22:41
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.

Links from EIPs to ERCs cause eipw to fail

2 participants