LearnNewsExamplesServices
Frontmatter
id18999
titleNo documented path from a clone of the engine to a running checkout
stateClosed
labels
documentationenhancementai
assigneesneo-opus-vega
createdAtSep 19, 2026, 9:08 PM
updatedAtSep 19, 2026, 10:00 PM
githubUrlhttps://github.com/neomjs/neo/issues/18999
authorneo-opus-vega
commentsCount0
parentIssue18985
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtSep 19, 2026, 10:00 PM

No documented path from a clone of the engine to a running checkout

Closed v13.2.0/archive-v13-2-0-chunk-22 documentationenhancementai
neo-opus-vega
neo-opus-vega commented on Sep 19, 2026, 9:08 PM

Context

Leaf of #18985 (AC-4), authored here rather than under it because the measurement is mine and a ticket has to be one-PR-resolvable. Refs #18985. @neo-opus-ada keeps AC-2 (topics), AC-3 (curation) and AC-5 (review/label/spam path), and marked this one as going first: twenty curated issues behind a setup path a clean clone cannot follow is twenty curated bounces.

Hacktoberfest starts October 1. The contributor this door is for has a fork, Node and an evening.

The Problem

Every published door routes a would-be engine contributor into the consumer scaffold instead, and the loop that actually works is written down nowhere.

Door What it documents What an engine contributor gets
README.md:152 → "Getting Started" neomjs.com/#/learn/gettingstarted/Setup → the row below
learn/gettingstarted/Setup.md npx neo-app@latest — scaffolds a workspace that consumes neo.mjs as a dependency the engine in node_modules, which is not a checkout you can change
CONTRIBUTING.md issue etiquette and PR rules no build, no server, no test command

CONTRIBUTING.md contains exactly one command in the whole file — npm ci or npm install at §3.7 — and it is justified there as "register the Husky hooks", not as setup. README.md names no install step at all.

Two further staleness defects in the same file, both verified:

  • **§3.4 says "create PRs for the dev branch and not for master".** git ls-remote --heads origin answers dev and main. master does not exist.
  • **§3.1 leads with "always create a new issue inside our Issues Tracker first and wait for approval".** That is the wrong first instruction in a month when twenty curated issues are waiting to be taken.

The Architectural Reality

Measured on a genuinely clean clone — git clone --depth 1 --branch dev, then every command run through /usr/bin/env -i with only HOME, PATH, USER, TMPDIR and LANG, so no NEO_*, MCP_*, ANTHROPIC_* or CLAUDE_* variable from a maintainer shell could reach it:

Step Result
git clone --depth 1 --branch dev 338 MB on disk
npm install exit 0, 3 s, 589 packages, 0 vulnerabilities
↳ postinstall → neo-agent-skills-materialize succeeds with no Agent OS present: symlinks 37 skills into .claude/skills and prints that the directory is a projection artifact
↳ prepare → buildScripts/util/prepare.mjs runs; Husky pre-commit and pre-push are registered, so §3.7's claim is accurate
npm run test-unit -- test/playwright/unit/util 87 passed in 671 ms
↳ with HOME pointed at an empty directory 87 passed again — and ~/.cache/ms-playwright does not exist on the measuring host at all
npm run server-start binds :8082 and serves / and /apps/portal/index.html at 200, with no build step first
🔴 npm run test-unit (no path — the whole suite) exit 1, ZERO tests selected. 41 lines of Cannot find module '<repo>/dist/marked.mjs' imported from src/component/Markdown.mjs, and the same for dist/parse5.mjs from src/functional/util/HtmlTemplateProcessor.mjs
↳ after npm run bundle-browser-deps (6 s, exit 0) 4305 tests selected, 4302 passed
npm run test-components -- test/playwright/component/button exit 1 — browserType.launch: Executable doesn't exist, "Please run: npx playwright install"
↳ after npx playwright install (18 s, 1.1 GB) 15 passed

Two corrections to my own premise, both from measurement rather than reading.

The scary one was wrong. I filed this expecting the Agent-OS postinstall to block an outside install. It does not — it symlinks and exits clean with no Agent OS present.

The one I did not expect is real, and it is not documentation. dist/ is git-ignored (.gitignore:68), so no clone has dist/marked.mjs, dist/parse5.mjs or dist/mermaid.mjs — and src/component/Markdown.mjs and src/functional/util/HtmlTemplateProcessor.mjs import them at load. The result is not a failing test; it is zero tests selected, which reads like a broken checkout rather than a missing step. npm run bundle-browser-deps fixes it in six seconds.

Every maintainer's working checkout already has dist/, built at some point and never removed. That is exactly why this has survived: the one condition that exposes it is the one condition no maintainer is ever in.

One real wrinkle, worth a line and not a gate: npm install emits npm warn EBADENGINE on Node v25.9.0 for a dependency wanting ^22.22.3 || ^24.15.0 || >=26.0. The repository's own engines.node is >=24.0.0, and CONTRIBUTING.md names no Node requirement anywhere.

The scripts a contributor needs already exist in package.json and none of them is mentioned in CONTRIBUTING.md: server-start, test-unit, test-components, test-e2e, build-all, build-themes.

The Fix

Rewrite CONTRIBUTING.md so the contributor loop comes first and the etiquette follows it:

  1. A "Set up the engine from a clone" section at the top, with the verified loop: Node >=24, git clone, npm install, npm run bundle-browser-deps, npm run server-start, and the test commands — each exactly as measured above, including which suites need npx playwright install and which do not.
  2. Separate the two audiences explicitly. Building an app with Neo? → npx neo-app@latest and the portal Setup guide. Changing the engine itself? → this loop. Today the file silently assumes the second and documents neither.
  3. §3.1's approval-first sentence gains its exception: an issue already labelled good first issue or help wanted is claimable by comment, no prior approval round.
  4. §3.4's master → dev.
  5. A Node-version line, since engines.node is >=24.0.0 and nothing says so.

README.md's "Getting Started" link keeps pointing at the app-user path — that is correct for its audience — and gains a sibling line pointing contributors at CONTRIBUTING.md.

Acceptance Criteria

  • AC-1 — CONTRIBUTING.md opens with the engine-contributor loop, and every command in it is one this ticket measured on a clean clone.
  • AC-1b — the loop names bundle-browser-deps and says why it exists (dist/ is git-ignored), so a contributor who skips it can recognise the zero-tests-selected symptom rather than concluding the checkout is broken.
  • AC-1c — the test section states the browser prerequisite per suite, because the three differ: test-unit needs none, test-components needs npx playwright install (~1 GB, bundled Chromium), and test-e2e is pinned to channel: 'chrome' (playwright.config.e2e.mjs:69, :118) so it needs system Google Chrome, which a default npx playwright install does not provide. The two live exemplars #18995 / #18996 are unit tests and must not appear to carry any of it.
  • AC-1d — the loop builds the development theme CSS (npm run build-themes -- -n -e dev -t all) before the first server-start, and says why: dist/ is git-ignored, so a fresh clone renders unstyled and the server only warns. Added 2026-09-19 from @neo-gpt-emmy's review of PR #19000 — the original loop omitted it, and my own first clean-clone run could not catch it because the CSS in that tree had been written as a side effect of a test-components invocation that failed.
  • AC-1e — the "no build needed" claim is scoped to JavaScript; SCSS is stated as compiling into dist/development/css with build-themes / watch-themes named.
  • AC-2 — the file distinguishes the app-building audience (npx neo-app@latest) from the engine-changing audience, and routes each.
  • AC-3 — master no longer appears; the named branch is dev.
  • AC-4 — the approval-first rule states its good first issue / help wanted exception.
  • AC-5 — the Node requirement is stated and matches package.json's engines.node.
  • AC-6 — README.md carries one line routing contributors to CONTRIBUTING.md, leaving its app-user link intact.
  • AC-7 — the documented loop is re-verified end to end on a fresh clone with a scrubbed environment, and the run is reported in the PR body. This is the AC that makes the others true; a prose review does not satisfy it.
    • ⚠️ Sharpened 2026-09-19, because the first attempt satisfied the letter and missed the defect. Two method rules, both earned:
      1. The clone must be uncontaminated by the verification itself. A failed test-components run builds theme CSS as a side effect before it fails, so any tree that has seen one is no longer a clean rig. Re-verify on a clone that has run only the documented commands, in order.
      2. Assert on the artifact the step produces, never on a status code downstream of it. GET / returned 200 with every stylesheet missing. The passing form asserts the stylesheet itself (GET /dist/development/css/src/Global.css → 200, non-zero bytes).
    • ⚠️ A host-provided dependency cannot be verified away by scrubbing. test-e2e resolves system Google Chrome, which this host has and env -i does not hide — so a green e2e run here would say nothing about a contributor's machine. Where the loop depends on something installed outside the repo, the AC is satisfied by reading the config that requires it (channel: 'chrome') and documenting it, not by a local pass.

Out of Scope

  • Curating the issues themselves (#18985 AC-3, @neo-opus-ada) and the review/label/spam path (AC-5).
  • The hacktoberfest topic on any repository (#18985 AC-2).
  • .github/AI_QUICK_START.md and the agent-facing §5 of CONTRIBUTING.md. They address a reader who has the Agent OS; this ticket is about the reader who does not, and the two must not be merged into one path.
  • The 338 MB clone. Repository weight is #17238 / #17376 territory, not a documentation fix.
  • Any change to learn/gettingstarted/Setup.md. It is correct for the audience it serves.

Avoided Traps

  • ⛔ Do not document a loop you have not run. This ticket earned that twice. The premise it was filed on (the Agent-OS postinstall blocks an outside install) was wrong, and the step that actually blocks one (bundle-browser-deps) was absent from the premise entirely. A draft of the fix that listed test-components alongside test-unit was written before either suite had been run on a cold cache; running them is what caught both.
  • ⛔ Do not delete the agent-facing section to make room. Agent-assisted contributors are explicitly in scope for Hacktoberfest 2026 (@tobiu, 2026-09-19, #18985): neo-agent-skills is a published package, so an outside agent can use the skills with no Knowledge Base and no Memory Core.
  • ⛔ Do not add a per-event rule to CONTRIBUTING.md. 2025 needed #7304 to take a temporary protocol back out; what lands here has to be true in November too.

Related

#18985 (parent; this is its AC-4) · #18995 · #18996 (the two live exemplars, both unit-test tickets — the loop above is exactly what they need) · #14230 · #7296 · #7304

Live latest-open sweep: latest 20 open issues in neomjs/neo at 2026-09-19T19:07Z — no equivalent; #18985 is the parent and the only adjacent filing. A2A in-flight sweep: @neo-opus-ada's 19:00Z message assigns this AC to me and names the three she keeps, so the lane is de-conflicted at source. Memory Core rationale sweep on the symptom: the only prior CONTRIBUTING.md work is the 2026-03 addition of the agent-facing §5; no prior decision on the contributor setup loop. Own open assignments in this repository (#18532, #17918, #16358, #16212, #15202): none on this surface.

Decision Record impact: none

Origin Session ID: 3c85c7c8-8961-43cc-b331-a053ea1d46d5 Retrieval Hint: "engine contributor clean clone setup loop CONTRIBUTING no build or test command, every door routes to npx neo-app scaffold"