Repository navigation
Customer builds: build a service for a customer environment from its build profile, tested and verified (plan) #1177
Description
This is the throwaway plan. It is regenerated from the spec, the handbook proposal Customer builds, by contract, whenever the spec changes. Comment here; review the spec on its PR.
Goal
Build Antoine Toussaint's customer build command for the Go and Python agents, adaptation included, exactly as his design describes. Done: the design's three acceptance runs pass on a NYL-shaped fixture with Docker Hub and public indexes unreachable.
Where we are (2026-10-26)
Codefly builds from the agent's recipe and tests separately; none of the design's operations exists. Recipe contract v6 merged 23 October. Antoine's announced update was never posted.
Decisions
| Question | Options | Decision | Why |
|---|---|---|---|
| Build or reuse? | a new build path · extend core and cli where the design says | Extend what the design names (2026-10-23) | Design: "Reuse Builder.Build, DockerBuildPlan and Runtime.Test" |
| Who builds it? | Antoine Toussaint · Cris Fiorini, then hands to Antoine | Cris builds, hands to Antoine (Cris, 2026-10-22) | earlier records name Antoine; he settles it in review |
| What is in this slice? | one agent, no adaptation · all of section 09 | All of section 09: both languages, with adaptation (2026-10-23) | Design footer: "NEXT ENGINEERING SLICE / ONE END-TO-END COMMAND" |
| How are base images bound? | the agent writes them from bindings · the cli swaps them | The agent writes, the cli checks (2026-10-23) | Design: "Agent renders FROM and external COPY references from those bindings" |
| NYL's base image? | a Wolfi variant in each agent · today's Alpine and Debian | A Wolfi variant in each agent (2026-10-23) | Design: "The fix belongs in the Go/Python agent template" |
| Recipe contract version? | share v6 · the next one | The version after v6 (2026-10-23) | Saurabh Maheshwari's merged work took v6 |
Reasoning: the proposal, sections 2b, 2c, 2g, 4 and 5.
Plan
Each step ends with a proof; the next starts only when it holds.
- 1. Open the proposal for both halves. Proof: the PR is open; handbook checks pass.
- 2. Add the design's contracts to core: describe inputs, resolve, the resolved-build bundle, image bindings, recipe capabilities. Proof: core tests pass; an agent lacking the capability is refused before any download.
- 3. In the cli, load the profile, describe, check through obinctl, resolve and seal the bundle. Needs the infra-base profile. Proof: a fixture run seals a bundle or lists gaps; checkout unchanged.
- 4. In the cli, adapt, test the candidate, build from the bundle, verify, push only to the output registry. Proof: egress blocked, the fixture builds; evidence names every digest.
- 5. Teach the Go and Python agents to describe, resolve, adapt and build a Wolfi variant. Proof: each agent's tests pass; its recipes name only approved digests.
- 6. Run the design's three acceptance checks on a NYL-shaped fixture; hand Antoine the PRs. Proof: all three pass; Antoine has every PR.
Operator commands and gotchas per step (for whoever runs it)
- All Codefly steps. One branch and one PR per repository (codefly-dev/core, cli, service-go, service-go-grpc, service-python, service-python-fastapi); no stacked PRs, no force-push, never self-merge. Read each repo's
AGENTS.mdand its development contract first. The handbook caps a task at about 500 hand-written lines and stops at 2,000: a PR heading past 2,000 stops for a decision. Facts below were read at core4c895eeand clic6dfaf5; main is now core8af4b78and cli2b804f1, with build files changed by core#832 and cli#1106, so re-read before editing. - 1. Shared with the infra-base plan; see its step 1.
- 2.
proto/codefly/services/builder/v0/builder.proto: addDescribeBuildInputsandResolveBuildand their messages, named as design section 08; addResolvedBuildwith section 08's six lines; carry its reference inBuildRequestand in runtimeInitRequestandTestRequest(proto/codefly/services/runtime/v0/runtime.proto) — "Adding a field only to BuildRequest leaves the original problem unsolved." Negotiate throughBuildCapabilitiesResponse.execution_contracts(builder.proto:961). Recipe contract: the version after v6 indocker.proto. Coordinate with Gael's open core#804 (image identity). - 3. Entry
initBuildService(cmd/build/service.go,--envat:173). The environment inworkspace.codefly.yamlnames the profile underbuild_profile(location and digest); refuse a mismatch. Callobinctl build-assessandbuild-preparewith JSON on stdin (infra-base plan step 5); pass outcome classes through. Go: reusegoModulePrefetch(pkg/orchestration/build_go_modules.go) with the profile's proxy and checksum policy and no,direct. - 4. Reuse
Runtime.Testorchestration, recipe verification and execution (pkg/orchestration/build_recipe.go,build_plan.go) and base-image resolution (image_cache.go) to check the emitted plan agrees with the bindings. Pull credentials through Docker or BuildKit, never build args. Refuse--orgoverriding the profile's output repository. Egress proof as in cli#1003. The build cache's input digest (getting-started/codefly.md, "Stale build or wrong build") is a reuse candidate for the recipe's identity. - 5. service-go-grpc pins
FROMby digest intemplates/builder/Dockerfile.tmpl:10,100; replace with values rendered from the bundle's bindings; declare roles (Go compiler, runtime base) and platforms. service-python-fastapi routes no package index; add uv resolution against the profile's PyPI source and locked installation in service-python. Wolfi variant per agent; refuse unsupported variants. - 6. Acceptance 01–03 from the proposal's section 2c. The live NYL run is the infra-base plan's step 6.
Acceptance detail for each step: the proposal's sections 2b and 2c.
Needs
| Need | Holder | Gates |
|---|---|---|
| Build profile and obinctl checks | the infra-base plan | steps 3, 6 |
| Antoine's updated design, if it exists | Antoine Toussaint | step 2 |
| Review, or takeover | Antoine Toussaint | step 6 |
| A builder inside NYL | Drew Maring | live run |
Links
- Spec: the proposal; Antoine's design text is its sidecar
- infra-base half: obin-ai/infra-base#1485
- Related: feat(builder): a recipe declares the locked git sources it fetches (contract v6) core#832, feat(build): fetch declared git sources on the host and hand the build a mirror context #1106, feat(runtime): request native image preparation and pin executed image identity core#804, feat(evidence): export canonical workspace selections and configuration sources #930, feat(build): the builder applies the environment's registry mirror to BuildKit and to base-image resolution (#1002) #1003
Activity
crisfiorini-oss commentedon Oct 26, 2026
Merged into a single plan for both halves: https://github.com/obin-ai/infra-base/issues/1485