Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions .changeset/doctor-withholds-checks-over-unexamined-tree.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
---
"@objectstack/cli": patch
---

`os doctor` no longer prints `✓ Test coverage` / `✓ Deprecations` about a tree it
never examined, and no longer warns `@objectstack/spec Not built` about a
workspace that is not part of the tree (#10679).

`findMissingTests()` and `findDeprecatedUsages()` both walk
`<cwd>/packages/spec/src` — a path that exists in this monorepo and in no
application built with the framework. Both answered "that directory is not here"
with the same value they return for "I walked it and found nothing wrong" (an
empty array), so in a stock `create-objectstack -t blank` scaffold every run
printed, verbatim:

```
✓ Test coverage All *.zod.ts files have matching tests
✓ Deprecations No @deprecated tags found
```

about files doctor never opened. The command exits 0 either way, so "no problems
found" and "I never looked" were byte-identical to every downstream reader.

Doctor already refuses to do this one screen down: the ADR-0120 D5e advisory's
`✓ Unique scope` is withheld unless `ledgerReadingIsComplete()` says the ledger
half was read in full. These two checks escaped that discipline; this restores
it, in the same shape #5413 used for the ledger — whether the tree was examined
is now a fact in the return type rather than an absence, so the print site
cannot reach the `✓` from the unexamined arm. Where the tree is absent doctor
prints an informational, named-reason skip instead:

```
ℹ Test coverage Skipped — no packages/spec/src in this directory (monorepo-only check)
ℹ Deprecations Skipped — no packages/spec/src in this directory (monorepo-only check)
```

`--verbose` adds the resolved directory it looked for. The skip is deliberately
not a warning: nothing is wrong in an application that has no
`packages/spec/src`, and withholding a false `✓` must not manufacture a false
`⚠`.

The adjacent `⚠ @objectstack/spec Not built` probe read `<cwd>/packages/spec/dist`
with no check that the workspace it names exists, so in an application it warned
about an absent package and prescribed `pnpm --filter @objectstack/spec build`, a
command that cannot succeed there. It is now gated on `packages/spec/package.json`
being present. Inside the monorepo the row is unchanged; outside it there is no
row, and an application's spec dependency stays covered by the `Dependencies`
check and by the spec-version-gap advisory.

Exit codes are untouched — 1 exactly when an error row exists, warnings never
flip it. One visible consequence: a stock scaffold with no other findings now
ends on `✅ Environment is healthy and ready for development!` instead of
`⚠️ Environment is functional but has some warnings`, because the warning it
used to carry was about a workspace that was never there.
13 changes: 12 additions & 1 deletion packages/cli/src/commands/doctor-env-provenance.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -447,7 +447,18 @@ describe('os doctor, end to end, against a posture that only exists in .env', ()
const healthy = await runDoctor();

expect(healthy.exitCode).toBeUndefined();
expect(healthy.out).toContain('Environment is functional');
// #10679 — this used to read `toContain('Environment is functional')`, and
// it passed for a reason that had nothing to do with #5387: the temp cwd
// has no `packages/spec`, and doctor warned `@objectstack/spec Not built`
// about that absent workspace on every run. Removing that phantom warning
// leaves this cwd with no findings at all, so the summary is now the
// healthy one. What the control actually claims — doctor reached its
// summary and did NOT refuse to call this environment usable — is what the
// matcher says instead, and it still cannot pass for the broken leg below
// (that one prints `Some critical issues found`).
expect(healthy.out).toMatch(
/Environment is (healthy and ready for development|functional but has some warnings)/,
);
expect(healthy.out).not.toContain('Tenancy posture');
// The report says what it read even when everything is fine — that is the
// "not a silent merge" half, and it is only observable on a healthy run.
Expand Down
13 changes: 12 additions & 1 deletion packages/cli/src/commands/doctor-tenancy-posture-report.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -295,8 +295,19 @@ describe('os doctor reports an unrecognized posture and exits non-zero', () => {

// Doctor completes normally. This is the sentence #5382 quoted, and here it
// is CORRECT: this environment really can start.
//
// #10679 — the matcher accepts either non-error summary. The control used
// to pin `Environment is functional but has some warnings` literally, and
// it held only because the temp cwd has no `packages/spec` and doctor
// warned `@objectstack/spec Not built` about that absent workspace every
// time. With that phantom warning gone this cwd has no findings, so the
// summary is the healthy one. Either sentence proves the control's actual
// claim; neither can be produced by the broken leg below, which prints
// `Some critical issues found` and exits 1.
expect(healthy.exitCode).toBeUndefined();
expect(healthy.out).toContain('Environment is functional');
expect(healthy.out).toMatch(
/Environment is (healthy and ready for development|functional but has some warnings)/,
);
expect(healthy.out).not.toContain('Tenancy posture');

// ── The case: one character changed ──────────────────────────────────
Expand Down
Loading
Loading