Skip to content

Lint: add standalone diagnostic command#80800

Closed
giodl73-repo wants to merge 2 commits into
openclaw:mainfrom
giodl73-repo:lint-diagnostics-command
Closed

Lint: add standalone diagnostic command#80800
giodl73-repo wants to merge 2 commits into
openclaw:mainfrom
giodl73-repo:lint-diagnostics-command

Conversation

@giodl73-repo

@giodl73-repo giodl73-repo commented May 11, 2026

Copy link
Copy Markdown
Contributor

Branch: lint-diagnostics-command
Base: upstream/main
Head: f3131a2dd0

Summary

This is an alternate shape for the lint work in
#80055.

Instead of adding openclaw doctor --lint, this draft adds a top-level
openclaw lint command for read-only diagnostics.

The command runs the migrated core diagnostic checks without prompting, loading
plugins, repairing config, or rewriting state. It is meant for CI, preflight,
policy checks, and review gates where operators need structured findings rather
than guided doctor output.

Out of the box, this draft runs the same first migrated core checks:

  • core/lint/gateway-config
  • core/lint/command-owner
  • core/lint/workspace-status
  • core/lint/skills-readiness
  • core/lint/final-config-validation

Motivation

OpenClaw already has multiple adjacent surfaces:

  • openclaw doctor for guided inspection and repair
  • openclaw health for a running Gateway health snapshot
  • policy and preflight workflows that need read-only workspace diagnostics

A top-level openclaw lint keeps those responsibilities explicit:

  • doctor remains the human repair path
  • health remains the runtime/Gateway status path
  • lint becomes the read-only diagnostic path for automation

That gives maintainers a cleaner option if doctor --lint feels like it makes
doctor responsible for too many modes.

Related issue signal:

  • #79166: asks for a
    doctor dry-run/diff mode because doctor --fix applies changes without a
    structured preview.
  • #77802: doctor --fix
    reports repairs, then fails validation and the same stale findings return on
    the next run.
  • #78217: doctor --fix
    partially runs against a live gateway and exits abruptly, leaving the user
    unsure what was applied.
  • #62261: update preflight
    already treats lint as a gate, but operators need clearer machine-readable
    diagnostics when a gate fails.

This draft does not claim to close those issues. It adds a stable read-only
diagnostic command that gives current and follow-up checks a consistent
reporting surface.

Maintainer Input Requested

  1. Should lint be a core command, an extension command, or part of doctor?

    This draft uses openclaw lint. The paired doctor-integrated draft uses
    openclaw doctor --lint: Doctor: add health-check contract and --lint validation #80055

    The core question is where maintainers want this surface to live:

    • core command: always available, works before extension/plugin loading
    • bundled extension command: cleaner extension boundary and easier to
      evaluate experimentally
    • doctor mode: keeps health detection and repair under one existing command
  2. If lint starts as an extension, how should it handle plugin/extension
    failures?

    The reason this draft currently implements lint in core is reliability:
    diagnostics are most useful when config, plugin loading, or extension startup
    is already degraded. If maintainers prefer an extension-first shape, what is
    the expected bootstrap model?

    Possible shapes:

    • a bundled lint extension that loads through a minimal safe path
    • a small core diagnostic runner with extension-provided rules
    • extension-only lint, accepting that it cannot diagnose extension-loading
      failures
    • a future promotion path where the extension proves the surface before
      moving into core
  3. Is "diagnostics" the right internal framing?

    The public command is lint, but the intent is broader than formatting or
    source linting. These are structured workspace diagnostics with stable check
    ids, severities, source locations, and fix hints.

    This avoids overloading the existing openclaw health runtime command while
    still giving future policy and preflight work a common reporting model.

  4. Should this stay in src/flows for now?

    The draft keeps the diagnostic runner near existing doctor flow machinery to
    minimize movement. If maintainers expect this to become part of a broader
    capability ownership model, the same runner could move under a clearer
    diagnostics or capability home later.

What Changed

  • Added top-level openclaw lint.
  • Added --json, --severity-min, --skip, and --only.
  • Kept lint plugin-free at CLI startup so diagnostics can still run when plugin
    loading is broken.
  • Added a dedicated lint docs page and linked it from the CLI index.
  • Updated doctor docs to point automation users at openclaw lint.
  • Added a small diagnostic registry and runner for the built-in lint checks.
  • Reused the same first core checks from the doctor lint work, but named them
    as core/lint/* diagnostics in this standalone variant.
  • Left openclaw doctor --fix as the repair surface.

Behavior

Human output:

openclaw lint: ran 5 check(s), 1 finding(s)
  [warning] core/lint/gateway-config gateway.mode - gateway.mode is unset; gateway start will be blocked.
    fix: Run `openclaw configure` and set Gateway mode (local/remote), or `openclaw config set gateway.mode local`.

JSON output:

{
  "ok": false,
  "checksRun": 5,
  "checksSkipped": 0,
  "findings": [
    {
      "checkId": "core/lint/gateway-config",
      "severity": "warning",
      "message": "gateway.mode is unset; gateway start will be blocked.",
      "path": "gateway.mode",
      "fixHint": "Run `openclaw configure` and set Gateway mode (local/remote), or `openclaw config set gateway.mode local`."
    }
  ]
}

Exit codes:

  • 0: no findings at or above the selected threshold
  • 1: one or more findings met the selected threshold
  • 2: command/runtime failure before findings could be emitted

Selection examples:

openclaw lint
openclaw lint --json
openclaw lint --severity-min warning
openclaw lint --only core/lint/gateway-config --json
openclaw lint --skip core/lint/skills-readiness

Review Notes

This is not a replacement for openclaw doctor.

openclaw lint is read-only and automation-friendly. It does not prompt,
repair, migrate config, start services, restart services, or load plugins. This
standalone variant uses diagnostic naming in code and does not introduce a
repair() contract or openclaw/plugin-sdk/health surface.

Doctor remains the command operators use when they want guided inspection and
repair. The useful part of this draft is the CLI boundary: diagnostics have a
dedicated command, while repairs stay with doctor.

Real Behavior Proof

Behavior addressed: openclaw lint should be a standalone, read-only diagnostic command backed by a registry/flow for structured checks. Core checks should register once, --only should narrow execution, findings should be structured, thrown checks should become sanitized error findings, and --severity-min should control exit-code thresholds.

Real environment tested: Clean WSL detached worktrees for upstream/main and PR #80800 head. The source-level probe imported the PR-head lint diagnostic modules through the same tsx loader used by the repo tests.

Exact steps or command run after fix:

  1. Created a clean upstream/main worktree and a clean PR-head worktree at Lint: add standalone diagnostic command #80800 head.
  2. In each worktree, ran node --import ./node_modules/tsx/dist/loader.mjs probe-lint-diagnostics.mjs.
  3. Verified the new command, registry, flow, core diagnostics, docs, and maintenance command wiring exist.
  4. Registered core diagnostic checks and captured their stable IDs.
  5. Ran runLintChecks() with onlyIds for core/lint/gateway-config and core/lint/command-owner.
  6. Ran a synthetic throwing check to prove lint converts check exceptions into sanitized error findings.
  7. Evaluated exitCodeFromFindings() and severity parsing behavior.

Evidence before fix: Upstream/main has no src/commands/lint.ts, no lint flow, no diagnostic registry, no core diagnostic checks, no docs/cli/lint.md, no lint command catalog/maintenance wiring, and no lint execution surface to register or run checks.

Evidence after fix:

Fresh before/after proof for standalone lint diagnostics

Observed result after fix: PR #80800 registers five core lint checks, --only runs 2 checks and skips 3, emits structured core/lint/gateway-config and core/lint/command-owner findings, converts a thrown check into probe/thrown-check with sanitized diagnostic check threw: boomsecret-control, and returns severity-threshold exit codes info=1, warning=1, error=0.

What was not tested: This proof does not exercise every built-in diagnostic check against every possible config shape; it verifies the command/engine contract and representative core check behavior.

Testing

  • vitest run src/commands/lint.test.ts src/flows/lint-flow.test.ts src/flows/core-diagnostics.test.ts src/cli/program/register.maintenance.test.ts src/cli/program/preaction.test.ts src/cli/command-path-policy.test.ts
  • oxlint src/cli/command-catalog.ts src/cli/command-path-policy.test.ts src/cli/program/command-registry-core.ts src/cli/program/core-command-descriptors.ts src/cli/program/preaction.test.ts src/cli/program/preaction.ts src/cli/program/register.maintenance.test.ts src/cli/program/register.maintenance.ts src/commands/lint.ts src/commands/lint.test.ts src/flows/core-diagnostics.ts src/flows/core-diagnostics.test.ts src/flows/diagnostics.ts src/flows/diagnostic-registry.ts src/flows/lint-flow.ts src/flows/lint-flow.test.ts
  • tsgo:core

Follow-Up

If maintainers prefer this shape, the existing policy drafts can point at
openclaw lint as the read-only validation surface instead of
openclaw doctor --lint.

Related stacked drafts:

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation gateway Gateway runtime cli CLI command changes scripts Repository scripts commands Command implementations size: XL maintainer Maintainer-authored PR labels May 11, 2026
@clawsweeper

clawsweeper Bot commented May 11, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge.

Summary
Review failed before ClawSweeper could summarize the requested change.

Reproducibility: unclear. The review failed before ClawSweeper could establish a reproduction path.

Real behavior proof
Not applicable: Real behavior proof was not assessed because the Codex review failed.

Next step before merge
Review did not complete, so no work-lane recommendation was made.

Review details

Best possible solution:

Retry the Codex review after fixing the execution failure.

Do we have a high-confidence way to reproduce the issue?

Unclear. The review failed before ClawSweeper could establish a reproduction path.

Is this the best way to solve the issue?

Unclear. Retry the review first so ClawSweeper can evaluate the actual issue and fix direction.

What I checked:

  • failure reason: codex execution failed.
  • codex failure detail: Codex review failed for this PR with exit 1.
  • codex stdout: Per-item Codex failure; continuing with the rest of the shard.

Likely related people:

  • unknown: Codex failed before it could trace repository history. (role: review did not complete; confidence: low)

Remaining risk / open question:

  • No close action taken because the review did not complete.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 9f112a1a7a40.

@giodl73-repo giodl73-repo force-pushed the lint-diagnostics-command branch from 4aae278 to f3131a2 Compare May 11, 2026 23:27
@openclaw-barnacle openclaw-barnacle Bot added size: L and removed scripts Repository scripts size: XL labels May 11, 2026
@giodl73-repo giodl73-repo force-pushed the lint-diagnostics-command branch from f3131a2 to a0e7859 Compare May 12, 2026 03:52
@giodl73-repo

Copy link
Copy Markdown
Contributor Author

Updated latest push/body for the review nits: added docs nav coverage, fixed the command path policy assertion to cover lint, and replaced the pending proof text with copied live output from the source CLI entry for openclaw lint.

@giodl73-repo

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@giodl73-repo giodl73-repo force-pushed the lint-diagnostics-command branch from a0e7859 to 78931e4 Compare May 12, 2026 13:40
@giodl73-repo giodl73-repo force-pushed the lint-diagnostics-command branch from 78931e4 to 3cf7250 Compare May 12, 2026 18:10
@clawsweeper clawsweeper Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 12, 2026
@giodl73-repo giodl73-repo force-pushed the lint-diagnostics-command branch 2 times, most recently from 0e7eb60 to 3d43c37 Compare May 13, 2026 04:51
@giodl73-repo

Copy link
Copy Markdown
Contributor Author

Rebased on current origin/main (e643890) and removed the unrelated generated plugin SDK baseline delta from the branch diff.\n\nChecks:\n- node scripts/test-projects.mjs src/commands/lint.test.ts src/flows/lint-flow.test.ts src/flows/core-diagnostics.test.ts src/cli/program/register.maintenance.test.ts src/cli/program/preaction.test.ts src/cli/command-path-policy.test.ts --reporter=verbose\n- node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.core.test.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core-test.tsbuildinfo\n- node scripts/check-changed.mjs\n- git diff --check\n\n@clawsweeper re-review

@giodl73-repo giodl73-repo force-pushed the lint-diagnostics-command branch 4 times, most recently from 2dca6bc to b7f6b73 Compare May 16, 2026 06:19
@giodl73-repo giodl73-repo force-pushed the lint-diagnostics-command branch 4 times, most recently from a0bbfb5 to 3081cac Compare May 16, 2026 14:17
@giodl73-repo

Copy link
Copy Markdown
Contributor Author

Fresh deterministic proof image for #80800 is published and the PR body now points at it.

Image: https://raw.githubusercontent.com/giodl73-repo/openclaw/proof-artifacts/pr-80800-fresh/pr-80800/pr-80800-lint-diagnostics-command-before-after-proof.png

This replaces the older proof with a clean upstream/main vs PR-head probe showing the new lint diagnostic command surfaces and engine behavior.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. P2 Normal backlog priority with limited blast radius. labels May 16, 2026
@giodl73-repo giodl73-repo force-pushed the lint-diagnostics-command branch from 3081cac to 5f45fee Compare May 17, 2026 02:14
@clawsweeper clawsweeper Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 17, 2026
@giodl73-repo

Copy link
Copy Markdown
Contributor Author

Closing this alternate standalone lint-command draft in favor of #80055.

After working through the migration shape, the cleaner path is to avoid a second health surface and keep lint/detection integrated with doctor's health-check contract. I am keeping #80055 as the active proposal, with follow-up conversions staged as small area-specific PRs on top.

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

Labels

cli CLI command changes commands Command implementations docs Improvements or additions to documentation gateway Gateway runtime maintainer Maintainer-authored PR P2 Normal backlog priority with limited blast radius. size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant