---
id: 11973
title: Bump SourceParser acorn ecmaVersion to support ES2025 import attributes
state: CLOSED
labels:
  - bug
  - ai
assignees:
  - neo-opus-ada
createdAt: '2026-05-25T13:12:01Z'
updatedAt: '2026-05-25T13:56:08Z'
githubUrl: 'https://github.com/neomjs/neo/issues/11973'
author: neo-opus-ada
commentsCount: 0
parentIssue: null
subIssues: []
subIssuesCompleted: 0
subIssuesTotal: 0
blockedBy: []
blocking: []
closedAt: '2026-05-25T13:56:08Z'
---
# Bump SourceParser acorn ecmaVersion to support ES2025 import attributes

## Context

Operator-flagged KB-sync regression surfaced after restarting the orchestrator (`npm run ai:orchestrator` → `[ProcessSupervisor] knowledge base sync stderr`):

```
[WARN] Failed to parse source file ai/scripts/maintenance/downloadKnowledgeBase.mjs: Unexpected token (5:48)
[WARN] Failed to parse source file ai/scripts/maintenance/uploadKnowledgeBase.mjs: Unexpected token (5:48)
```

## The Problem

`ai/services/knowledge-base/parser/SourceParser.mjs:58` hardcodes `acorn.parse(content, {sourceType: 'module', locations: true, ecmaVersion: 2022})`. Both failing files use ES2025 import-attribute syntax at line 5 column 48:

```js
import packageJson from '../../../package.json' with {type: 'json'};
```

Acorn `8.16.0` (currently pinned in `package.json`) supports `import ... with {type: 'json'}` only under `ecmaVersion: 2025` or `ecmaVersion: 'latest'`. `ecmaVersion: 2022` does not recognize the `with` keyword as an import attribute.

## The Architectural Reality

Primary surfaces:

- [`ai/services/knowledge-base/parser/SourceParser.mjs:58`](ai/services/knowledge-base/parser/SourceParser.mjs#L58) — single hardcoded `ecmaVersion: 2022`.
- Two source files using the modern syntax that get silently dropped from KB chunks: [`ai/scripts/maintenance/downloadKnowledgeBase.mjs`](ai/scripts/maintenance/downloadKnowledgeBase.mjs#L5) and [`ai/scripts/maintenance/uploadKnowledgeBase.mjs`](ai/scripts/maintenance/uploadKnowledgeBase.mjs#L5).
- Verified locally:
  - `acorn.parse(..., {ecmaVersion: 'latest'})` → parses cleanly
  - `acorn.parse(..., {ecmaVersion: 2025})` → parses cleanly
  - `acorn.parse(..., {ecmaVersion: 2022})` → `Unexpected token (1:23)`

**Provenance**: The `with` syntax was introduced 2026-05-23 in commit `e6c9df098` (#11848/#11853 buildScripts/ai → ai/scripts collapse refactor). KB-sync has been silently dropping these chunks since then; today's orchestrator restart triggered a full re-parse and surfaced the WARN.

**Blast scope**: WARN only — KB sync completes; the 2 affected files just don't contribute source chunks to the knowledge base. Agents querying the KB about `downloadKnowledgeBase`/`uploadKnowledgeBase` get no source-level results. Not a stop-the-world but degrades agent-facing observability.

## The Fix

Single-line change at `SourceParser.mjs:58`:

```diff
- ast = acorn.parse(content, { sourceType: 'module', locations: true, ecmaVersion: 2022 });
+ ast = acorn.parse(content, { sourceType: 'module', locations: true, ecmaVersion: 'latest' });
```

`'latest'` is acorn's documented sentinel for "the most recent ECMA version this acorn release supports" — auto-tracks new syntax as acorn is upgraded, without further hardcoded version bumps required when new TC39 features land.

## Acceptance Criteria

- [ ] `SourceParser.mjs:58` uses `ecmaVersion: 'latest'` (no hardcoded year).
- [ ] New unit test in `test/playwright/unit/ai/services/knowledge-base/parser/SourceParser.spec.mjs` (or equivalent canonical location) parses a fixture containing `import x from 'y.json' with {type: 'json'}` without warning.
- [ ] After `npm run ai:orchestrator` triggers a KB sync, no `Failed to parse source file` warnings for `downloadKnowledgeBase.mjs` or `uploadKnowledgeBase.mjs` appear in the daemon log.
- [ ] No regression in existing KB-sync chunk counts (parser was permissive enough before; bumping the floor doesn't change behavior on files already parseable under 2022).

## Out of Scope

- Migrating the 2 files back to `fs.readJson` (would lose the static-import benefit; we want the parser to handle modern syntax, not constrain authoring).
- Bumping acorn itself — `8.16.0` already supports `'latest'`.
- Auditing for other parsers in the codebase that may have the same hardcoded-year issue (file as follow-up if any are found).

## Avoided Traps

- Do NOT switch `ecmaVersion: 2025` instead of `'latest'` — the literal year locks future agents into another hardcoded bump when ES2026+ syntax lands. `'latest'` auto-tracks.
- Do NOT add a fallback `try { 'latest' } catch { 2022 }` block — defensive code that never fires is noise. Acorn's contract is documented; trust it.
- Do NOT touch the 2 files using `import with` — they're authoring the canonical modern shape; the parser is the surface to fix.

## Related

- #11848 / #11853 — refactor that introduced the `import with` syntax in the 2 maintenance scripts
- Operator-reported regression 2026-05-25 via orchestrator daemon log

Handoff Retrieval Hint: "SourceParser acorn ecmaVersion 2022 import attribute with type json regression".

## Timeline

- 2026-05-25T13:12:02Z @neo-opus-ada assigned to @neo-opus-ada
- 2026-05-25T13:12:03Z @neo-opus-ada added the `bug` label
- 2026-05-25T13:12:03Z @neo-opus-ada added the `ai` label
- 2026-05-25T13:14:05Z @neo-opus-ada cross-referenced by PR #11974
- 2026-05-25T13:34:39Z @neo-opus-ada referenced in commit `ef30ce3` - "test(kb): strengthen SourceParser regression oracle to fail under pre-fix parser (#11973 cycle-2)

Resolves @neo-gpt cycle-1 review on #11974 — false-positive regression test.

The cycle-1 spec asserted only `Array.isArray(chunks)`, which is true on
both the pre-fix path (`ecmaVersion: 2022` → catch-branch returns `[]` after
the warn) and the fixed path. The oracle would pass even if the underlying
bug were never fixed.

Empirical V-B-A on this PR cycle:

  - Strengthened spec + `ecmaVersion: 2022` (pre-fix): test FAILS with
    `Expected length: 1, Received length: 0` — exactly the warn-catch
    returns-`[]` path GPT flagged.
  - Strengthened spec + `ecmaVersion: 'latest'` (post-fix): test PASSES
    (3/3 in 504ms).

## Strengthened oracles

1. **ES2025 import-attribute test**: asserts `chunks.length === 1`,
   `chunks[0].kind === 'module-context'`, `chunks[0].source` matches the
   fixture filename, and `chunks[0].content` contains the literal
   `with {type: 'json'}` payload. Only the success-path produces a chunk
   array of length 1; the failure-path returns `[]`.

2. **Shebang test**: asserts `chunks.length > 1`, `kinds` contains both
   `module-context` AND `class-config`, plus a method chunk is present.
   Pre-fix shebang+modern-syntax mixed fixtures would have returned `[]`;
   post-fix produces the multi-chunk decomposition.

3. **Malformed-source test**: unchanged — still asserts `chunks=[]` because
   the catch-branch contract is preserved across the ecmaVersion bump.
   This test pins the warn-not-throw shape so future parser changes don't
   silently start throwing on malformed input.

## Comment hygiene

Inline JSDoc + body comments updated to remove the misleading "doesn't
emit chunks for a plain module" claim (the parser DOES emit a single
`module-context` chunk for the no-class branch). New wording explains the
false-positive trap so future readers don't recreate the weak oracle."
- 2026-05-25T13:56:09Z @tobiu referenced in commit `426baf2` - "fix(kb): bump SourceParser acorn ecmaVersion to 'latest' for ES2025 import attributes (#11973) (#11974)

* fix(kb): bump SourceParser acorn ecmaVersion to 'latest' for ES2025 import attributes (#11973)

Operator-flagged KB-sync regression — daemon log emitted:

    [WARN] Failed to parse source file ai/scripts/maintenance/downloadKnowledgeBase.mjs: Unexpected token (5:48)
    [WARN] Failed to parse source file ai/scripts/maintenance/uploadKnowledgeBase.mjs: Unexpected token (5:48)

Root cause: `SourceParser.mjs:58` hardcoded `acorn.parse(..., {ecmaVersion: 2022})`.
Both files use ES2025 import-attribute syntax at line 5:

    import packageJson from '../../../package.json' with {type: 'json'};

Acorn 8.16 supports this under `ecmaVersion: 'latest'` or literal `2025`,
but rejects it under the older `2022` pin.

Fix: switch to `ecmaVersion: 'latest'` so acorn auto-tracks its highest-supported
syntax without future literal-year bumps when ES2026+ features land.

Blast scope: WARN-only — KB sync continued past the warnings but silently
dropped source chunks for those 2 files. Agents querying the KB about
download/upload knowledge-base scripts got zero source-level matches.

Test evidence: new `SourceParser.spec.mjs` covers (1) ES2025 import attribute
parsing, (2) shebang-prefixed entry scripts, (3) malformed-source warn-not-throw
contract. 3/3 PASS.

* test(kb): strengthen SourceParser regression oracle to fail under pre-fix parser (#11973 cycle-2)

Resolves @neo-gpt cycle-1 review on #11974 — false-positive regression test.

The cycle-1 spec asserted only `Array.isArray(chunks)`, which is true on
both the pre-fix path (`ecmaVersion: 2022` → catch-branch returns `[]` after
the warn) and the fixed path. The oracle would pass even if the underlying
bug were never fixed.

Empirical V-B-A on this PR cycle:

  - Strengthened spec + `ecmaVersion: 2022` (pre-fix): test FAILS with
    `Expected length: 1, Received length: 0` — exactly the warn-catch
    returns-`[]` path GPT flagged.
  - Strengthened spec + `ecmaVersion: 'latest'` (post-fix): test PASSES
    (3/3 in 504ms).

## Strengthened oracles

1. **ES2025 import-attribute test**: asserts `chunks.length === 1`,
   `chunks[0].kind === 'module-context'`, `chunks[0].source` matches the
   fixture filename, and `chunks[0].content` contains the literal
   `with {type: 'json'}` payload. Only the success-path produces a chunk
   array of length 1; the failure-path returns `[]`.

2. **Shebang test**: asserts `chunks.length > 1`, `kinds` contains both
   `module-context` AND `class-config`, plus a method chunk is present.
   Pre-fix shebang+modern-syntax mixed fixtures would have returned `[]`;
   post-fix produces the multi-chunk decomposition.

3. **Malformed-source test**: unchanged — still asserts `chunks=[]` because
   the catch-branch contract is preserved across the ecmaVersion bump.
   This test pins the warn-not-throw shape so future parser changes don't
   silently start throwing on malformed input.

## Comment hygiene

Inline JSDoc + body comments updated to remove the misleading "doesn't
emit chunks for a plain module" claim (the parser DOES emit a single
`module-context` chunk for the no-class branch). New wording explains the
false-positive trap so future readers don't recreate the weak oracle.

---------

Co-authored-by: tobiu <tobiasuhlig78@gmail.com>"
- 2026-05-25T13:56:09Z @tobiu closed this issue

