Problem
codefly ci run sync-drift hard-errors for any affected service whose agent does not advertise a sync validation capability. Runtime-only agents (redis, s3, postgres, vault) advertise only BUILDER/RUNTIME with no validation: block, so they fail with:
SyncDriftPolicy.Execute: cannot execute sync-drift action:
cannot prove sync drift for saas-starter/<svc>:
agent has no authoritative sync capability contract
Because any change to a module-level input (deployment/topology.bindings.codefly.yaml, tools/base-manifest.json) marks every service in the module as affected (selection.go: "module-level input changed"), sync-drift then runs for the infra services and fails — even though those agents have no generated source to drift.
Root code
pkg/orchestration/builder.go — Builder.Sync(), dry-run branch:
if request.GetDryRun() {
advertised, supported := ValidationOperationSupport(b.instance.Info, ValidationSync)
if !advertised {
return nil, w.NewError("cannot prove sync drift for %s: agent has no authoritative sync capability contract", ...)
}
if !supported { return nil, w.NewError("... explicitly does not support non-mutating sync") }
}
This is stricter than audit/sbom, which use the lenient if advertised && !supported { error } pattern, and stricter than the documented compatibility mode (docs/design/codefly-native-ci.md: "Agent omits capability advertisement: compatibility mode explicitly skips an unimplemented optional static phase").
Ask
Make sync-drift skip (report skipped, not failed) a service when its agent does not advertise the sync capability, keeping a hard error only when the agent advertises sync but reports it unsupported (advertised && !supported). Align with the audit/sbom pattern and the design doc.
Note: this must be paired with the agents actually being downloadable — the skip lives in Builder.Sync, which runs after flow.InitManagers downloads the agent. See the sibling pre-flight validation issue and the plugin release issues.
Tracking consumer: codefly-dev/module-saas-starter#3.
Design refinement — skip is an option, and the report is the actionable output
The skip is the right default for CI, but it must not be a silent, always-on behavior. Locally we need to run the full check so we can fix the underlying agents.
- Default (CI): service whose agent doesn't advertise
sync → reported skipped (not failed). Hard error only when advertised && !supported.
- Local override: a flag/policy to disable the skip and run the strict check, e.g.
codefly ci run --require-sync, so the missing-capability case is surfaced instead of swallowed.
- Always visible + machine-readable: never claim the phase executed when skipped. Every skipped service names the agent + reason so the run yields a concrete "which agents to fix" list, e.g.:
sync-drift: skipped 4 service(s) — agent does not advertise the sync capability:
saas-starter/cache codefly.dev/redis:0.0.74 (add sync capability)
saas-starter/object-storage codefly.dev/s3:0.0.16 (add sync capability)
saas-starter/store codefly.dev/postgres:0.0.103 (add sync capability)
saas-starter/vault codefly.dev/vault:0.0.15 (add sync capability)
Surface the same list in the CI report JSON so it can be diffed/tracked over time. The point of skipping-with-visibility is precisely to know which agents to fix.
Problem
codefly ci runsync-drift hard-errors for any affected service whose agent does not advertise asyncvalidation capability. Runtime-only agents (redis,s3,postgres,vault) advertise onlyBUILDER/RUNTIMEwith novalidation:block, so they fail with:Because any change to a module-level input (
deployment/topology.bindings.codefly.yaml,tools/base-manifest.json) marks every service in the module as affected (selection.go: "module-level input changed"), sync-drift then runs for the infra services and fails — even though those agents have no generated source to drift.Root code
pkg/orchestration/builder.go—Builder.Sync(), dry-run branch:This is stricter than
audit/sbom, which use the lenientif advertised && !supported { error }pattern, and stricter than the documented compatibility mode (docs/design/codefly-native-ci.md: "Agent omits capability advertisement: compatibility mode explicitly skips an unimplemented optional static phase").Ask
Make sync-drift skip (report skipped, not failed) a service when its agent does not advertise the
synccapability, keeping a hard error only when the agent advertisessyncbut reports it unsupported (advertised && !supported). Align with the audit/sbom pattern and the design doc.Note: this must be paired with the agents actually being downloadable — the skip lives in
Builder.Sync, which runs afterflow.InitManagersdownloads the agent. See the sibling pre-flight validation issue and the plugin release issues.Tracking consumer: codefly-dev/module-saas-starter#3.
Design refinement — skip is an option, and the report is the actionable output
The skip is the right default for CI, but it must not be a silent, always-on behavior. Locally we need to run the full check so we can fix the underlying agents.
sync→ reported skipped (not failed). Hard error only whenadvertised && !supported.codefly ci run --require-sync, so the missing-capability case is surfaced instead of swallowed.Surface the same list in the CI report JSON so it can be diffed/tracked over time. The point of skipping-with-visibility is precisely to know which agents to fix.