ReviewOS

craft-native/craft

~38 places where Zig is deliberately stricter than the spec — keep and document, or match exactly?

#117
Closed glennmichael123 opened this 10 days ago ·
10 days ago

A 33-agent audit compared every .live Zig action's reply against the Swift arm the seam (#103) now displaces: 80 actions, 61 observable differences, each confirmed by two independent refuters.

The eight that changed what a page observes were fixed in #105 and #110 — wrapper shapes, the Siri duplicate key, recognizeText, saveHealthWorkout, badge authorization. This issue is the remaining ~38, which were left alone deliberately.

They are all the same shape: Zig is stricter than the spec.

  • rejects strings containing an embedded NUL, where Swift silently truncates at the NUL
  • validates filenames against /, . and .., where Swift joins the page's string straight onto documentsPath
  • refuses a second overlapping picker call, where Swift overwrites the shared pendingCallbackId and abandons the first caller
  • refuses a non-numeric startDate, where Swift's as? Double yields nil and silently uses a default window
  • rejects a malformed data: URL before writing, where Swift writes a truncated file and resolves

Every one of these is Zig declining to do something the spec does badly. Several are security-relevant — the filename one is path traversal.

The question

They are still divergences. A page written against the spec can observe them, and "the migration made my app stricter" is a real thing to be surprised by, even when the strictness is right.

  • Keep them — document each in the module that makes the choice, and note the class in the SDK docs so it is discoverable rather than a surprise at runtime.
  • Match the spec exactly — much larger, and it means reintroducing a path traversal on purpose. I would argue against.

My read is keep-and-document, but it is a product call about a published surface, not a mechanical one, which is why this is an issue rather than a PR.

The full per-action list is in the audit output; I can paste any subset into this issue on request.

Related: #116 and #115 are cases where the spec is the one behaving badly.

10 days ago

Product decision (October 1, 2026): keep Zig’s stricter, fail-closed behavior. Do not reintroduce embedded-NUL truncation, path traversal through saved-file names, dropped picker filters, overlapping-callback loss, or silent timestamp/data-URL fallbacks just to match the legacy Swift shim. The SDK migration guide at docs/api/mobile/runtime-compatibility.md documents these classes; 0870b52 also fixes the invalid public.pdf picker example and explains unmappable filters in the public type docs. Keeping this issue open while the remaining per-action audit is checked against the module-level notes, rather than treating sign-off alone as completion.

10 days ago

Decision resolved: keep the safer Zig-native validation. The SDK compatibility guide in docs/api/mobile/runtime-compatibility.md documents the failure classes, module-level notes explain the implementation choices, and 0870b52 corrects the picker example and public type guidance. This closes the product decision, not a claim that the historical ~38 count has been independently reproduced. #329 tracks the missing checked-in per-action conformance table.

Sign in to comment on this issue.