Skip to content

fix(doctor): the bindings check takes a naming scope, and --json keeps stdout for the document - #1255

Merged
antoinetoussaint-byte merged 1 commit into
mainfrom
fix/doctor-naming-scope-and-json-stdout
Oct 30, 2026
Merged

antoinetoussaint-byte merged 1 commit into
mainfrom
fix/doctor-naming-scope-and-json-stdout

Conversation

@antoinetoussaint-byte

Copy link
Copy Markdown
Contributor

Two defects in codefly doctor workspace (#1254)

obin-ai/platform-core's composition gate (scripts/composition-check.sh) found both.

1. The runnable-bindings check used a naming scope it could not be told

CheckRunnableBindings (added in #1209) prepares the expected bindings with env.NamingScope, the environment's declared scope. The gate generates the bindings with --naming-scope composition-gate, as run and generate runnable-bindings both allow, so the addresses differ and doctor reported runnable-bindings is out of date (required by runtime/worker, robin/chat). On the same file, generate runnable-bindings --naming-scope composition-gate --check passes.

Fix: doctor workspace --naming-scope <scope> applies the scope to the selected environment the same way run/generate runnable-bindings do: if the flag is omitted, doctor uses the environment's declared scope; if it is passed empty, doctor clears it. The bindings check then compares against a run in that scope. The remedy text now comes from the generator's own runnableBindingsRegenerate (exported as RunnableBindingsRegenerateCommand), so it includes --naming-scope when one applies. Without the flag, behaviour is unchanged.

2. --json printed log lines on stdout before the report

Core's configuration reader logs composed modules disagree … configuration=fixture-composition on cmd.Context(), which carries no wool provider. The line therefore went to wool's fallback Console, which writes to stdout.

Fix: reuse cli.ProtectResultStream, the guard the composition verbs already use for JSON on stdout. It now also points wool's fallback logger at stderr and restores it afterwards. doctor workspace --json installs the guard. With --json, stdout carries only the report and every log line goes to stderr.

Reused: cli.ProtectResultStream (stream guard), runnableBindingsRegenerate (remedy), and the run/generate naming-scope semantics. Not built: a second stdout guard, or a doctor-specific logger.

Classification

Fix at the owning place. Doctor owns its flags and its JSON contract. The stream guard owns keeping result streams clean.

Gate reproduction: fresh clone of platform-core #119 at 58b1903

Ran the gate's steps from the start through codefly generate runnable-bindings --env local --naming-scope composition-gate (materialize, config generate, hop seed, model installation; the delivery-key step was skipped). Output: Bound 182 runnable operation(s). No services were started.

Before (v0.1.230, 03a6994b), codefly doctor workspace --json:

stdout line 1-2: (WARN) (configurations.composedModuleOffers.resolve) composed modules disagree on a workspace configuration; … configuration=fixture-composition
jq: parse error: Invalid numeric literal at line 1, column 7
JSON part: not_ready — configuration_invalid: cannot use generated runnable bindings: runnable-bindings is out of date: run `codefly generate runnable-bindings --env local` (required by runtime/worker, robin/chat)

After (this branch), codefly doctor workspace --json --naming-scope composition-gate:

exit 0; stdout parses with jq; status: ready
no fail checks; runnable-bindings listed among the 15 configurations under configurations/local-fixture
stderr: the two (WARN) fixture-composition lines

After, without --naming-scope: same configuration_invalid … out of date as before (default behaviour kept).

Tests

  • TestDoctorChecksRunnableBindingsInTheNamedScope: bindings generated under scope gate-x pass with gate-x. They report configuration_invalid (stale) without a scope or under gate-y, and each remedy names its scope. The test fails when the scope is not applied.
  • TestDoctorWorkspaceJSONKeepsStdoutForTheReport: uses a two-module fixture-composition workspace that produces the real warning. stdout unmarshals as the report, and the warning is on stderr. The test fails without the fallback redirect.
  • The ProtectResultStream test now also logs a record with no provider and asserts that stdout stays empty.
  • go build ./..., go test ./cmd ./cmd/generate/... ./cmd/composition/... ./cmd/deploy/... ./pkg/cli/..., and make lint (0 issues) all pass. docs/cli-reference.md was regenerated.

Not verified

  • I did not run the full go test ./pkg/.... The only pkg package touched is pkg/cli.
  • I did not run the gate's later steps (codefly run service …).
  • workspaceReadinessOptions is now passed by pointer, because the gocritic hugeParam check flagged it at 80 bytes.

Closes #1254

🤖 Generated with Claude Code

…s stdout for the document

`doctor workspace` compared runnable-bindings with the preparation in the
environment's declared naming scope only. Bindings generated for a run under
`--naming-scope` resolve other addresses, so a workspace that runs under a
scope could never pass doctor. Doctor now takes `--naming-scope`, read as
`run` and `generate runnable-bindings` read it (omitted keeps the
environment's, empty clears it), and the remedy names the scope.

With `--json`, core's configuration reader logged its warnings on a context
without a CLI logger, so they reached wool's fallback Console on stdout ahead
of the report. `ProtectResultStream`, the guard the composition verbs already
use, now also points wool's fallback at stderr, and doctor installs it under
`--json`.

Closes #1254

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@antoinetoussaint-byte
antoinetoussaint-byte added this pull request to the merge queue Oct 30, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 30, 2026
@antoinetoussaint-byte
antoinetoussaint-byte added this pull request to the merge queue Oct 30, 2026
Merged via the queue into main with commit fe40688 Oct 30, 2026
19 checks passed
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.

doctor workspace: runnable-bindings checked in the wrong naming scope, and --json stdout carries log lines

1 participant