Skip to content

fix(package): bind prepared and cross-target evidence to the actual graph - #163

Draft
gael-obin wants to merge 2 commits into
codefly-dev:fix/honour-prepared-goworkfrom
gael-obin:fix/prepared-workspace-evidence
Draft

gael-obin wants to merge 2 commits into
codefly-dev:fix/honour-prepared-goworkfrom
gael-obin:fix/prepared-workspace-evidence

Conversation

@gael-obin

@gael-obin gael-obin commented Oct 31, 2026 •

Copy link
Copy Markdown

A prepared Go workspace can link sibling modules that differ from the pinned graph. Package previously selected one inventory independently of each executable's build. This selects inventory per target: native builds use the prepared workspace; cross builds use the pinned graph available inside the companion.

Classification: fix at the package owner. It reuses Core's inventory and digest-bound artifact attachment, adds a public Package regression, and follows #159 . No second scanner or PDF/image capability is introduced.

Draft / blocked: the committed Core 0.19.10 dependency still produces invalid multi-main workspace evidence. Independent review reproduced the public Package test failure at 60d721eddbc62de4a069b740fc83612b5c0ed068 with an unknown graph source; the pinned case passed. The owner fix is codefly-dev/core#878 and remains open. Adopting the inspected latest Core 0.19.18 alone does not fix this defect.

Previously reported native/cross tests with a local Core override are exploratory evidence, not qualification of the committed pin. After an accepted Core release and supported adoption, rerun clean public Package, normal CLI bootstrap and generated-service delivery checks. Linux process execution/recovery and released artifacts remain separate obligations. This is not demonstrated as necessary for the already-running NYL PDF/image flow.

@gael-obin

Copy link
Copy Markdown
Author

Independent platform review — ACCEPTED (design) / NOT QUALIFIED at this head

Fresh-context review under the architecture-bouncer skill at head 60d721eddb (scope e5455c221f..60d721eddb), taken together with the owner-side codefly-dev/core#878. No conversation history with the implementing agents.

The allocation across the two PRs is right — neither does the other's job, and the split follows obin/handbook/design/dependency-ownership.md. One blocker, one medium coverage gap, and a CI problem that is not this PR's fault but makes it unreviewable as submitted.

G-B1 — blocker, reproduced: this PR's own new test is red at its committed Core pin

At 60d721ed with github.com/codefly-dev/core v0.19.10, go test ./... fails:

package_evidence_test.go:143: unknown graph source pkg:golang/example.test/package-evidence
    (TestPackageEvidenceFollowsEachTargetGraph/prepared-workspace)

Every other package passes. With replace … => <core#878 worktree> it passes, including the Docker cross leg.

This is the correct signal, not a mistake, and docs/PACKAGING.md:33-38 discloses it honestly. It still means the PR cannot merge: dependency-ownership.md steps 4–5 require the producer to release first, then the consumer to pin the tag and run its gates against the fetched dependency. Closure: go test ./... green against a released Core pin with no committed replace or pseudo-version — currently true and verified.

Worth correcting in the PR text: "the current released pin, Core v0.19.10" implies a boundary that does not exist. #878 is in no release at all — 15e7e12257 (its merge base, equal to Core main) is v0.19.18-1-g15e7e122, and the newest released Core is v0.19.18. And this PR needs only #878's behaviour, not its code: GolangOptions/GolangWithOptions already exist at v0.19.10, and go build, go vet and go mod tidy -diff all pass at the committed pin — only the test fails. When it is re-pinned it should take the release carrying #878, not v0.19.10.

G-1 — medium, mutation-verified: the cross-target half has zero non-gated coverage

Replacing packageGoWorkMode's body (pkg/builder/package_source.go:45-50) with return goWorkMode() — deleting the cross rule that is half the PR title — leaves go test -count=1 ./... fully green. The only thing that catches it is the SERVICE_GO_PACKAGE_TESTS=required plus Docker leg, and grep -rn packageGoWorkMode finds no test at all.

Consequence: a future simplification ships a cross binary built from the pinned graph with an inventory describing a developer workspace, and CI notices nothing. hostGoEnvironment still sits beside it claiming to be universal, which makes that simplification likelier.

Remedy: a table-driven unit test over packageGoWorkMode — native plus prepared → workspace; native plus nothing → off; any foreign os/arch → off. No Docker, no network. Closure: that test exists and fails under the mutation above.

The stack — the hazard here is a CI blackout, and it is unguarded

statusCheckRollup for 60d721ed is null: no checks ran at all. The cause is in source — .github/workflows/ci.yml:2-6 is on: push: branches:[main] / pull_request: branches:[main], and a PR targeting fix/honour-prepared-gowork matches neither trigger. A stacked PR in this repo receives no CI whatsoever. UNSTABLE here means "required checks unsatisfied because none ran", not "a check failed" — and had CI run, it would have been red for G-B1. The stack is why that red is invisible.

For contrast, #159 (base main) is green on runtime-image, manifest-guard / guard and build. And there is no equivalent of obin-ai/module-robin's module-pin-ancestry.yml in either this repo or Core; both allow squash, merge and rebase. Robin's workflows use a bare on: pull_request: with no branch filter, which is exactly the difference.

The stranding hazard is latent rather than active: neither PR pins a same-repository SHA, and this PR's manifests carry only released tags.

The split is defensible on its merits — the fixture depends on #159's build change — but it is not justified in this repo, because the child cannot be checked. Since this PR must be re-pinned and re-run after the Core release anyway, the cheap correct move is to land #159 first and retarget this to main. Keeping the stack means fixing the branch filter, which is a service-go CI decision rather than something either PR should carry.

Advisory

  • hostGoEnvironment's comment (pkg/builder/package_source.go:18-21, "every host-side go invocation") is now false — two of three now use packageGoWorkMode(target). It is safe only because packageGoBinary:494 routes non-native targets elsewhere.
  • The inventory runs once per target, so N cross targets recompute one identical GOWORK=off graph N times.
  • The attached .cdx.json is a Go module inventory. A CGO executable's C objects, and whatever goreleaser-cross linked in, are not in it. One bounding sentence would stop it being read as complete artifact provenance.

Credit

package_evidence_test.go is a genuine binding test, not a shape assertion: the public RPC over gRPC, real CGO binaries, a debug/buildinfo cross-check, the binary actually executed, and Settings.WithWorkspace deliberately inverted so the old code cannot pass — mutation-verified. docs/PACKAGING.md names the unreleased dependency and states what the qualification does not cover. No committed replace, no pseudo-version.

The .claude/skills/verify-changes/SKILL.md edit was checked specifically for being self-serving and is not: it is purely additive — a new gated step 5 and an explicit statement of what it does not prove — and it tightens the "What green means" section. Nothing was loosened.

What was run

go build, go vet, go mod tidy -diff (clean, root and base/code); go test ./... at the committed pin (1 failure, above) and against Core#878 (pass); two mutations (the selector → fails correctly; packageGoWorkMode → suite stays green, which is G-1); a Docker cross run with SERVICE_GO_PACKAGE_TESTS=required, mixed native darwin/arm64 plus cross linux/amd64 CGO against Core#878 — pass, no containers left behind; and the padded-GOWORK counterexample against real go.

Not exercised: Nix integration (needs a sibling core checkout), the Linux runtime and TestNativeAgentOwnershipLifecycle (that is #159's gate and needs a built native agent and a qualified CLI), released-archive identity (nothing is released from either branch), cross-compilation to darwin/amd64, darwin/arm64 and linux/arm64 (only linux/amd64 was built), and TestPackageRealCGO separately.

Unsettled: whether with-workspace: true services should receive a workspace-graph Package at all. That predates both PRs and is a service-go owner decision.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant