Skip to content

fix(extensiontest): preserve binary example fixture bytes #496

Open

Description

@pascalandy

The problem (CMO)

Agent role: Cook building a new image extension from the template

Area: Automated checks

Problem Statement: As an agent working in ncly-image-shrink, I want manifest example fixtures to retain their exact bytes, so that example checks and release measurements exercise the generated image unchanged.

REF: #494, XT-107-T2

Analogy

A test kit adds a letter to the document it checks.

  • What should happen: The checked copy contains exactly the original bytes
  • What happened in this session: A generated PNG gained a trailing newline during fixture extraction

What we saw

On Linux with Nicely v0.27.0, the generated PNG in testdata/examples.txtar contained 8747 bytes. txtar.Parse returned 8748 bytes. Its final bytes changed from ae426082 to 4260820a.

just check exited 1. The command's strict container framing rejected the extracted image with IMAGE_SHRINK_INPUT. Generated scenario images passed that framing. This stopped the first build while its author investigated fixture transport.

What exists today

sdk/extensiontest/examples.go reads examples with txtar.ParseFile, then writes generated scenario archives with txtar.Format. The pinned go-internal/txtar calls fixNL when a file lacks a final newline. sdk/extensionrepo/release_economy.go extracts the same archive's file data and intentionally ignores setup commands. There is no documented binary encoding for these fixtures.

Start, Stop, Continue (FMO)

  • Start: Preserve exact binary example fixtures, with a documented binary encoding or a separate fixture-file mechanism
  • Stop: Requiring image extensions to tolerate bytes that the test kit added
  • Continue: Run manifest examples in scratch installs and keep arbitrary setup programs out of release measurements

How we'll know it works

  1. Today: Put a generated PNG whose last byte is not a newline in an example archive. Compare its extracted bytes with the generated original
  2. After the change: The extracted bytes match exactly in example checks and Economy measurements, and a strict image reader accepts them
  3. Nothing else changes: The template's text fixtures still run, and release measurements still ignore archive setup commands

👨🏻‍🍳 For the agent

👨🏻‍🍳 Details

Observed probe output, exit 0:

raw=8747 parsed=8748 equal=false raw_last=ae426082 parsed_last=4260820a

The probe read the bytes after -- photo.png --, parsed the complete archive with github.com/rogpeppe/go-internal/txtar, then compared archive.Files[0].Data with those raw bytes.

Observed check output, exit 1:

manifest.toml: example `ncly image shrink photo.png --dry-run --json`: exit 2
{"ok":false,"contract_version":1,"errors":[{"code":"IMAGE_SHRINK_INPUT","message":"photo.png is not a readable, complete regular image file."}]}

The error excerpt omits the hint. Relevant fixed sources are Nicely v0.27.0, sdk/extensiontest/examples.go, Coverage.RunExamples, and sdk/extensionrepo/release_economy.go, economyMeasure. The pinned github.com/rogpeppe/go-internal v1.16.0, txtar/archive.go, documents and calls fixNL.

A setup command can generate an exact PNG for scenario checks, but Economy intentionally ignores it. Accepting a trailing newline in the extension would avoid this observed failure, but would conceal the fixture transport change. No Nicely source was changed to unblock the build.

The smallest fix must cover both fixture consumers. Binary image inputs are local and contain no user data. No network, key, payment, or installed extension is needed for the parser probe.

by GPT-6.1-Sol via Codex

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    1-needs-triageScope, approach, or direction needs evaluation2-type:bugExisting behavior is broken3-pty:p2Normal planned work; default when no priority is established

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions