Skip to content

TOON encoder emits quoted notes[] scalar that its decoder rejects, making valid tracked items unreadable #747

Description

@unbraind

Summary

pm 2026.7.26 can serialize a string containing the literal text notes[] into a quoted TOON scalar, but the same bundled TOON decoder interprets the bracket segment as an array header and rejects the document. A previously valid tracked item then disappears from pm context/search and makes pm validate fail storage integrity.

This is a core pm/SDK storage round-trip issue, not an extension customization.

Minimal reproduction

Environment:

  • @unbrained/pm-cli 2026.7.26
  • bundled @toon-format/toon 2.3.1
  • Node 22+
import { decode, encode } from "@toon-format/toon";

const encoded = encode({ body: "notes[] unioned; pm validate ok:true" });
console.log(encoded);
// body: "notes[] unioned; pm validate ok:true"

console.log(decode(encoded));
// ToonDecodeError: Line 1: Unexpected content "unioned; pm validate ok"
// between bracket segment and colon

The same failure is visible through pm:

pm get <affected-id> --json
item_document_invalid: TOON item document is not valid TOON

pm validate --json
storage_integrity.status: error
unreadable_item_files: [...]

The affected real document is byte-identical to its committed origin/main version and was produced/accepted by an earlier pm release. The failing line is a quoted body: scalar containing ordinary prose with notes[] followed later by a colon.

Expected

Every string emitted by pm's canonical TOON serializer must round-trip through pm's canonical decoder. Literal bracket syntax inside a quoted scalar must remain scalar content. Existing repository items must remain readable across upgrades.

Actual

The encoder emits a quoted scalar, but the decoder parses notes[] ... : inside that quoted value as structural syntax. pm context, pm search, pm get, and history verification can no longer read the item; pm validate correctly reports it as unreadable.

Suggested acceptance criteria

  • Add round-trip regression cases for notes[] unioned; key:value, comments[] ... :, empty brackets, numeric brackets, and ordinary bracketed prose inside every persisted string field.
  • Protect pm independently of the upstream dependency version (escape/encode safely or add a narrowly scoped decoder compatibility path).
  • Demonstrate serializeItemDocument -> parseItemDocument round trips and an on-disk upgrade fixture from an older pm release.
  • Preserve hash/history verification semantics; recovery must not silently rewrite existing item/history data.
  • Provide a supported repair/migration path for already-unreadable tracked items.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions