LearnNewsExamplesServices
Frontmatter
id17421
titleRemove apps/devindex, its guides, SCSS and tests from the neo repo
stateClosed
labels
enhancementaiarchitecturetech-debt
assigneesneo-opus-grace
createdAtAug 20, 2026, 5:07 PM
updatedAtAug 24, 2026, 10:39 PM
githubUrlhttps://github.com/neomjs/neo/issues/17421
authorneo-opus-grace
commentsCount6
parentIssue17238
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 24, 2026, 10:39 PM

Remove apps/devindex, its guides, SCSS and tests from the neo repo

Closed Backlog/active-chunk-18 enhancementaiarchitecturetech-debt
neo-opus-grace
neo-opus-grace commented on Aug 20, 2026, 5:07 PM

Context

Operator, 2026-08-20, after testing the app from dev: "tested the devindex app after pulling from dev => works fine. first real friction item with the new repo => it will stay broken there, until the next neo release. on the bright side: we can now remove the app, its learn items, scss, and tests from the neo repo (vba if all tests (not just unit) are there)."

This is the terminal step of neomjs/neo#17238. neomjs/devindex owns the app, its Data Factory and its own tickets and PRs; what remains here is a copy that is behind the destination (config.publishedWorkingSet exists only there — see neomjs/neo#17238's revision comment).

The requested V-B-A came back negative. Recorded here as the ticket's own precondition rather than discovered mid-removal.

Live latest-open sweep: latest 20 open issues at 2026-08-20T14:45Z, no equivalent. A2A in-flight claim sweep over the last 30 messages: no overlapping [lane-claim].

The Problem — the tests are NOT all there

suite in neo in neomjs/devindex gap
unit (unit/app/devindex/) 9 9 not the same 9
e2e 5 0 no e2e harness exists there at all

Unit — one spec exists only here. StoragePublishedIndex.spec.mjs (8 tests) covers neomjs/neo#17374's published-artifact read path: fetched-vs-checkout record parity, the single declared config URL, fallback-with-disclosure on failure, non-2xx handling, an unparseable body on the bootstrap run, digest mismatch, absence-of-provenance, and curated files untouched.

neomjs/devindex has a spec neo does not — StorageWriteDirectory.spec.mjs — but it is a different subject (atomic write, parent-dir creation, temp-file cleanup, the empty-index door). The two do not overlap. Deleting neo's copy drops the read-path coverage entirely, and that path is exactly the mechanism neomjs/neo#17394 is about.

E2E — none of the five have a home. neomjs/devindex has one playwright config (playwright.config.unit.mjs) and one script (test-unit). There is no e2e config, no e2e directory, no test-e2e.

All five drive /apps/devindex/ exclusively — not one has an alternative target:

spec devindex-specific dependency
grid/ThumbDragDevIndex.spec.mjs the app itself; named for it
grid/ThumbDrag.spec.mjs devindex-stop-stream-button
grid/ThumbDragPause.spec.mjs 50,000 rows
benchmarks/GridScrollBenchmark.spec.mjs devindex-stop-stream-button
benchmarks/GridProfile.spec.mjs devindex-stop-stream-button

So this is not a goto rewrite. Three of the five click a control that only that app has, and examples/grid/bigData (20,000 rows / 50 columns) is not row-comparable with DevIndex's 50,000.

The Architectural Reality

Removal surface, measured on origin/dev:

area count note
apps/devindex/** 49 files, 27 MB incl. the 23 MB still-tracked users.jsonl
resources/scss/**/devindex/** 14 8 src + 3 dark + 3 light
learn/guides/devindex/** 27 plus 30 learn/tree.json entries
tests 14 9 unit + 5 e2e
apps/portal registration 6 4 examples_*.json + sitemap.xml + llms.txt
buildScripts + ai/scripts 6 webpack appworker dev/prod, esmodules, dataSyncPipeline, check-package-contents, retry-bound-registry
package.json 6 scripts `devindex:add

resources/content/** carries 0 devindex entries, so the generated mirror needs no prune.

The Fix

Remove in one PR, with the four decisions below resolved rather than discovered.

D1 — port StoragePublishedIndex.spec.mjs to neomjs/devindex first. The code it covers lives only there. Order matters: port and prove green in the destination before deleting here, so the coverage is never absent from both.

D2 — ThumbDragDevIndex.spec.mjs follows the app. It is devindex-specific by construction. That requires standing up an e2e harness in neomjs/devindex (config + script + fixture), which is the larger half of this ticket and may deserve its own leaf.

D3 — the three stream-dependent specs retarget to a neo-owned fixture. bigData loads synchronously and has no stream, so the devindex-stop-stream-button step is not replaced — it is unnecessary there and drops out. The benchmark series re-baselines at the cut (50k→20k rows, 37→50 columns): the numbers before and after are not comparable and must not be read as a regression. That discontinuity is the real cost of the removal and is recorded here deliberately rather than left to be discovered as a mystery drop in a future comparison.

D4 — the public URL is an operator call. apps/devindex is a registered portal example with its own sitemap.xml entry at https://neomjs.com/apps/devindex/index.html and an llms.txt listing. Deregistering removes a live public URL; a redirect to the app's new home is the obvious disposition, but changing a published URL is not mine to decide unilaterally.

Acceptance Criteria

  • StoragePublishedIndex.spec.mjs runs green in neomjs/devindex before its removal here (D1)
  • apps/devindex/**, its 14 SCSS files, its 27 learn guides and the 30 learn/tree.json entries are gone, and npm run build-themes plus the learn-tree lint both pass
  • The three retargeted specs pass against a neo-owned fixture with no devindex-* selector remaining anywhere in test/**
  • No apps/devindex reference survives outside deliberately-retained history — git grep -l 'apps/devindex' returns only files this ticket consciously keeps
  • The six devindex:* npm scripts are gone and npm run still resolves
  • The portal no longer registers the app, and D4's redirect disposition is recorded on this ticket before merge
  • Full unit + e2e suites are re-run and every delta against the pre-removal baseline is accounted for

Out of Scope

  • Reclaiming the 23 MB from history — that is neomjs/neo#17376 and needs the one-shot rewrite; this ticket only stops the working tree carrying it
  • neomjs/devindex#1 (column resize) — that app stays broken until a neo.mjs release, which the operator has explicitly accepted as the trade for removing now
  • Standing up the devindex e2e harness, if D2 is split into its own leaf

Avoided Traps

Do not delete the tests and "port them later." The unit gap above is exactly how that ends: StoragePublishedIndex would be the only record of neomjs/neo#17374's read-path contract, and it would be deleted from the one repo that has it while the code it covers lives in the other.

Do not silently retarget the benchmarks. A benchmark whose fixture changed is a new series. Renaming the target without recording the discontinuity produces a future "performance regression" that is really a fixture change.

Related

  • neomjs/neo#17238 — the epic this closes out
  • neomjs/neo#17376 — history reclaim (the other half of the size problem)
  • neomjs/neo#17394 — the read-path defect StoragePublishedIndex covers
  • neomjs/devindex#1 — why the destination app is currently broken

Origin Session ID: 3e4f33e0-fb23-4a61-a2a0-7f396950f3d6

Handoff Retrieval Hints: query_raw_memories("remove apps/devindex from neo test parity e2e harness"). Anchors: StoragePublishedIndex.spec.mjs, devindex-stop-stream-button, learn/tree.json.

tobiu closed this issue on Aug 20, 2026, 9:41 PM