Skip to content

Define a canonical manifest parsing profile for Swift and C# #12

Description

@tuki0918

Summary

The normative manifest contract is not precise enough to make Swift and C# accept and reject the same JSON documents.

Confirmed or high-confidence differences include:

  • Swift .iso8601 rejects fractional seconds that C# DateTimeOffset.TryParse can accept.
  • Swift JSONDecoder accepts UTF-8 BOM and UTF-16 or UTF-32 input even though the format says UTF-8.
  • Duplicate JSON keys may resolve differently.
  • C# can treat a missing files[].size constructor value as zero, allowing a malformed zero-byte entry that Swift rejects.
  • The required-key, nullable-value, and unknown-field policies are not fully documented.

Impact

A package can be valid on one platform and invalid on the other. Ambiguous duplicate keys and defaulted required fields also weaken the format as an independently implementable contract.

Evidence

  • Docs/FORMAT.md:25-43
  • macOS/BundlePack/Shared/ZipArchiveInspector.swift:84-87
  • macOS/BundlePack/Shared/PackageManifest.swift:165-254
  • Windows/BundlePack.Core/BundlePackJson.cs:11-43
  • Windows/BundlePack.Core/Models.cs:5-54
  • Windows/BundlePack.Core/BundlePackArchive.Validation.cs:336-358

Reproduction cases

  • createdAt: "2026-07-21T00:00:00.123Z"
  • a manifest encoded as UTF-16LE
  • a UTF-8 manifest with BOM
  • two formatVersion keys with different values
  • a zero-byte payload whose manifest entry omits size
  • missing, null, negative, overflow, and wrong-type values for each required field

Windows runtime confirmation is still needed for the exact duplicate-key and required-constructor behavior.

Proposed change

  • Require strict UTF-8 and explicitly decide whether BOM is accepted.
  • Define one RFC 3339 timestamp grammar for readers; keep the current UTC whole-second writer output as canonical.
  • Reject duplicate keys at every object level.
  • Define a versioned field-presence and nullability matrix.
  • Make C# required constructor members explicit instead of accepting CLR defaults.
  • Continue ignoring unknown fields for known format versions.

Acceptance criteria

  • A language-neutral manifest corpus records accept or reject and a stable error category.
  • Swift and C# produce identical outcomes for the corpus.
  • Missing files[].size is always rejected, including for zero-byte files.
  • Writer output remains deterministic UTC UTF-8 JSON.
  • Tests cover field order and files array order without treating either as semantic.

Compatibility constraints

Keep unknown-field tolerance for known versions, reject unknown format versions, preserve current canonical writer timestamps, and do not make JSON object-key order or manifest file-list order semantically significant.

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