Repository navigation
fix(cli): preserve verbatim contract bytes when splitting apply documents - #3233
Conversation
AI Session Analysis
|
| Status | Attribution | File | Lines |
|---|---|---|---|
| created | ai | app/cli/pkg/action/apply_test.go |
+110 / -0 |
| modified | ai | app/cli/pkg/action/apply.go |
+37 / -16 |
| modified | ai | app/controlplane/pkg/biz/workflowcontract.go |
+3 / -1 |
Policies (4)
| Status | Policy | Material | Messages |
|---|---|---|---|
| ✅ Passed | ai-config-ai-agents-allowed |
ai-coding-session-606de1 |
- |
| ✅ Passed | ai-config-no-dangerous-commands |
ai-coding-session-606de1 |
- |
| ✅ Passed | ai-config-no-secrets |
ai-coding-session-606de1 |
- |
| ✅ Passed | ai-config-mcp-servers-allowed |
ai-coding-session-606de1 |
- |
Powered by Chainloop and Chainloop Trace
migmartri
left a comment
There was a problem hiding this comment.
I don't know, this looks strange, shouldn't we take a look at why different clients produce different outputs? at the end, we have the raw content.
Also, does this mean that if I add a comment now in the yaml it will not be saved because the marshalled output is the same?
e569b5a to
9b292af
Compare
…ents The batch `apply` path re-serialized each YAML document through a yaml.v3 Node, which re-indented and reflowed the content. This produced different bytes than `wf contract apply` (which sends the file verbatim), so the server's raw-byte change detection reported spurious contract revisions and false drift on `apply --dry-run` for a contract that had not changed. SplitYAMLDocuments now splits the stream on document markers and keeps each document's original bytes verbatim, so every apply path sends exactly what the user authored. Re-applying the same file is idempotent regardless of path, while genuine edits (including comment or formatting changes) still produce a new revision. Assisted-by: Claude Code Signed-off-by: Javier Rodriguez <javier@chainloop.dev> Chainloop-Trace-Sessions: 606de1a5-e4ab-480b-8009-722416f5e18d
9b292af to
24f9d89
Compare
Thanks for the pushback @migmartri — you were right on both counts, so I've reworked the PR to fix it client-side instead of changing the server comparison. On "why do different clients produce different outputs? at the end we have the raw content": it wasn't really two different clients — it was the same file serialized two ways by the CLI. On "if I add a comment now, will it not be saved because the marshalled output is the same?": exactly the reason I dropped the semantic-comparison approach. That would have ignored comment/formatting-only edits and skipped the revision. We don't want that. New approach:
Added CLI unit tests covering verbatim single/multi-document preservation, comment-only-document skipping, and the missing PTAL when you get a chance. |
|
looks good! |
chainloop-cli 1.104.0 Created-by: HarmonybrewBot Commit-by: HarmonybrewBot Merged-by: HarmonybrewBot Description: Created by `brew bump` --- Created with `brew bump-formula-pr`.<details> <summary>release notes</summary> <pre>## What's Changed * Bump Helm Chart and Dagger Version => v1.103.1 by @github-actions[bot] in chainloop-dev/chainloop#3259 * fix(ci): align secrets-scan material name with contract by @migmartri in chainloop-dev/chainloop#3262 * fix: harden GitHub Actions workflows against zizmor findings by @migmartri in chainloop-dev/chainloop#3260 * feat: add opencode chainloop-trace plugin by @migmartri in chainloop-dev/chainloop#3267 * ci: bump docker/login-action to v4.4.0 by @matiasinsaurralde in chainloop-dev/chainloop#3261 * fix(controlplane): restrict owner-role invitations to org owners (CP-1) by @migmartri in chainloop-dev/chainloop#3263 * feat: introduce PR mode for attestations by @migmartri in chainloop-dev/chainloop#3268 * docs: fix broken GUAC integration link in README by @tknura in chainloop-dev/chainloop#3272 * fix(cli): correct registered integration add usage string to --opt by @tknura in chainloop-dev/chainloop#3271 * fix: upgrade extras/dagger deps to resolve 4 security advisories by @migmartri in chainloop-dev/chainloop#3277 * fix(crafter): surface auto-discovery validation errors by @waveywaves in chainloop-dev/chainloop#2983 * docs: regenerate CLI reference for registered integration add usage by @matiasinsaurralde in chainloop-dev/chainloop#3279 * fix: upgrade Go toolchain to 1.26.5 for GO-2026-4970-stdlib by @chainloop-platform[bot] in chainloop-dev/chainloop#3278 * feat(cli): explode archive materials in chainloop att add by @javirln in chainloop-dev/chainloop#3254 * fix(materials): do not record container image digest as tag by @tknura in chainloop-dev/chainloop#3281 * fix(cli): accept matching --name and metadata.name in contract commands by @tknura in chainloop-dev/chainloop#3282 * fix(dispatcher): improve fanout delivery timeouts and retry budget by @migmartri in chainloop-dev/chainloop#3270 * refactor: remove the public attribute from workflows by @matiasinsaurralde in chainloop-dev/chainloop#3283 * fix(cli): preserve verbatim contract bytes when splitting apply documents by @javirln in chainloop-dev/chainloop#3233 **Full Changelog**: https://github.com/chainloop-dev/chainloop/compare/v1.103.1...v1.104.0</pre> <p>View the full release notes at <a href="https://github.com/chainloop-dev/chainloop/releases/tag/v1.104.0">https://github.com/chainloop-dev/chainloop/releases/tag/v1.104.0</a>.</p> </details> <hr> See merge request: Harmonybrew/homebrew-core!14158
Description
After a clean apply, re-running
chainloop apply -f <contracts> --dry-runreported a contract as "would be updated" even though nothing changed, whilechainloop wf contract applycorrectly reported it "unchanged".The cause was entirely client-side: the batch
applypath re-serialized each YAML document through a yaml.v3 Node (yaml.Marshal(&node)), which re-indented and reflowed the content. That produced different bytes thanwf contract apply, which sends the file verbatim. Since the server detects changes by comparing the stored raw bytes against the incoming ones, the reformatted bytes always looked like a change.SplitYAMLDocumentsnow splits the stream on document markers and keeps each document's original bytes verbatim, so every apply path sends exactly what the user authored. Re-applying the same file is idempotent regardless of path, and genuine edits — including comment or formatting-only changes — still produce a new revision. No server-side change is needed; raw-byte change detection is left as-is.Closes PFM-6465
AI disclosure
Claude Code assisted in producing this change.