Skip to content

fix(miner): cross-repo evaluation manifest size guard checks UTF-16 length, not UTF-8 bytes #7223

Description

@JSONbored

Context

packages/loopover-miner/lib/cross-repo-evaluation.js's doc comment for parseCrossRepoEvaluationManifest states it's a "tolerant JSON manifest parser (#4788)... mirroring the fleet-run-manifest / miner-goal-spec convention." The size guard at lines 33 and 128:

export const MAX_CROSS_REPO_MANIFEST_BYTES = 65_536;
...
if (trimmed.length > MAX_CROSS_REPO_MANIFEST_BYTES) {
  return cloneEmptyManifest([
    `CrossRepoEvaluationManifest exceeded ${MAX_CROSS_REPO_MANIFEST_BYTES} bytes; ignoring the file.`,
  ]);
}

uses String.prototype.length (UTF-16 code units), while the constant name and warning message both say "bytes." The three siblings this file's own comment claims to mirror all compute a genuine UTF-8 byte count via a local utf8ByteLength helper before comparing to their own MAX_*_BYTES constant:

  • packages/loopover-engine/src/fleet-run-manifest.ts:121-130 (helper), :173 (utf8ByteLength(content) > MAX_FLEET_RUN_MANIFEST_BYTES)
  • packages/loopover-engine/src/miner-goal-spec.ts:325 (helper), :419 (same pattern)
  • packages/loopover-engine/src/ams-policy-spec.ts:203 (helper), :261 (same pattern)

Because JS string .length under-counts true UTF-8 byte size for any multi-byte character (up to 4x for characters outside the BMP), a manifest containing non-ASCII content (e.g. in stackHint/fixturePath free-text fields) can have an actual UTF-8 byte size well above the documented 64KB cap while still passing this check — the guard silently admits payloads larger than what it claims to enforce. The existing test (test/unit/miner-cross-repo-evaluation.test.ts:83-86, "rejects oversize manifests") only pads with ASCII spaces, where .length and byte-length coincide, so it doesn't catch this.

Requirements

  • parseCrossRepoEvaluationManifest's size guard must measure genuine UTF-8 byte length against MAX_CROSS_REPO_MANIFEST_BYTES, not String.prototype.length, matching the byte-accuracy of fleet-run-manifest.ts/miner-goal-spec.ts/ams-policy-spec.ts that this file's own doc comment claims to mirror.
  • Add a local utf8ByteLength helper to cross-repo-evaluation.js mirroring the existing (currently duplicated, not shared) implementation in the three engine files cited above — introducing a new shared export is out of scope for this fix; matching the established duplication pattern is sufficient and lower-risk.
  • The behavior for ASCII-only content (the common case, and the only case the current test covers) must not change.

Deliverables

  • parseCrossRepoEvaluationManifest in packages/loopover-miner/lib/cross-repo-evaluation.js measures true UTF-8 byte length before comparing to MAX_CROSS_REPO_MANIFEST_BYTES.
  • A regression test asserting a manifest whose UTF-16 .length is under MAX_CROSS_REPO_MANIFEST_BYTES but whose true UTF-8 byte size exceeds it (e.g. padded with multi-byte characters) is rejected exactly like the existing ASCII oversize test.
  • A regression test asserting a manifest at/near the boundary with only ASCII content still behaves exactly as today (no regression on the existing "rejects oversize manifests" test).

Test Coverage Requirements

99%+ Codecov patch coverage (branch-counted) on the changed lines in packages/loopover-miner/lib/cross-repo-evaluation.js, covering both the new UTF-8 byte-counting helper and both size-guard branches (under/over the cap) with non-ASCII input.

Expected Outcome

The cross-repo evaluation manifest's documented 64KB cap is enforced against actual UTF-8 byte size, consistent with every sibling manifest/spec parser in the codebase and with this file's own doc comment, so a manifest with non-ASCII content can no longer silently exceed the size the guard claims to bound.

Links & Resources

  • packages/loopover-miner/lib/cross-repo-evaluation.js:33,114-116,121-145 (the guard and its "mirrors the convention" claim)
  • packages/loopover-engine/src/fleet-run-manifest.ts:121-130,173 (byte-accurate sibling)
  • packages/loopover-engine/src/miner-goal-spec.ts:325,419 (byte-accurate sibling)
  • packages/loopover-engine/src/ams-policy-spec.ts:203,261 (byte-accurate sibling)
  • test/unit/miner-cross-repo-evaluation.test.ts:82-86 (existing ASCII-only oversize test to extend)

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:bugGittensor-scored bug fix — scores a 0.05x multiplier.help wantedExtra attention is needed

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions