lint: stop W2 switching itself off, and see an asset name nobody declared - #10
Merged
Conversation
…ared
Two reports, both reproduced by a failing test before anything was changed.
**W2 halted on the first declared server.** The rule makes two checks and only
one needs the installation: "the program uses a server the skill did not
declare" needs the skill alone, "a declared server is not registered" needs the
registry. Interleaved, the registry was asked for on the first DECLARED server —
which in any healthy skill comes first — and a missing one returned out of the
whole walk. So offline the rule did not degrade, it turned itself off.
That is what let a live catalogue report "0 errors" while carrying two: steps
called a server their skill had not declared, the radius was never handed over,
and 21 turns answered "no such pod" about live pods.
Now two passes, which also makes the dependency structural rather than a comment:
pass one is the skill against itself, pass two is the skill against the
installation. The skip still fires — "part of a rule did not run" and "the rule
did not run" are different facts and a report has to keep them apart — but only
when there was something for pass two to check.
The patch that came with the report handed the loop an empty registry and
carried on, which turns every declared server into "not registered". A test now
pins that too: without a registry, no invented findings.
The order of the steps in the fixture IS the test — put the undeclared server
first and it passes on the broken code.
**W19 and W20: asset names.** A reference to an asset the skill does not declare
was caught by nothing. The engine expands an unknown asset to an empty string by
contract — a marker left in an instruction would be read by the model as part of
it — and that contract is right. The price nobody was paying is that a typo is
indistinguishable from an empty asset, and what fails is whatever stood next to
it: the call is rejected for a MISSING ARGUMENT, and the error names the
argument rather than the substitution a floor above.
Both reference forms are checked, because both are used: `{{asset:name}}` puts
content in the text for the model, `{from: "asset:name"}` passes it into an
argument past the context. The finding lists the declared names — a typo is
recognised by comparison.
W20 is the other side: an asset declared and never referenced. A warning, not an
error — it costs nothing at run time — and worth having because assets outlive
the steps that used them.
Both are purely static: declarations and references are in one document.
**Also documented.** `Rule.Needs` was read as "the rule cannot run without
this", while for W2 it is one of two checks. It now says so, and the two
partial rules say which half needs what — including W12, which the report
rightly notes is ENTIRELY dependent on a live tool listing and does not run
offline at all. A CI report of "0 warnings" gave false confidence about it.
The format did not change: EngineVersion stays 2.2.4.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Two linter reports from an outside review, both reproduced by a failing test
before anything was changed. The format did not change —
EngineVersionstays 2.2.4, no skill file is affected.
1. W2 switched itself off offline
The rule makes two checks and only one needs the installation:
Facts.ServerNamesInterleaved, the registry was asked for on the first declared server — which
in any healthy skill comes first — and a missing one
returned out of the wholewalk. So without a registry the rule did not degrade partially; it turned itself
off, and the undeclared server further down was never reached.
That is what let a live catalogue report "0 errors" while carrying two:
steps called a server their skill had not declared, the radius was never handed
over, and 21 turns answered "no such pod" about live pods.
Now two passes — the skill against itself, then the skill against the
installation — which makes the dependency structural instead of a comment. The
skip still fires (a report must distinguish "part of a rule did not run" from
"the rule did not run"), but only when pass two had something to check.
The patch that came with the report would have introduced false findings. It
handed the loop an empty registry and continued, so on the second declared
server
!known[srv]is true and every existing server is reported as "notregistered" — a report full of findings about live servers, which is worse than
the silence it replaces. A test pins that now.
The order of the steps in the fixture is the test: put the undeclared server
first and it passes on the broken code too.
2. W19 / W20 — asset names
A reference to an asset the skill does not declare was caught by nothing.
The engine expands an unknown asset to an empty string by contract — a
marker left in an instruction would be read by the model as part of it — and
that contract is right. The price nobody was paying: a typo is indistinguishable
from an empty asset, and what fails is whatever stood next to it. The call is
rejected by the server for a missing argument, and the error names the
argument rather than the substitution a floor above.
{{asset:name}}and every{from: "asset:name"}namesa declared asset. Both forms, because both are used — one puts content in the
text for the model, the other passes it into an argument past the context. The
finding lists the declared names, since a typo is recognised by comparison.
failure, and worth having because assets outlive the steps that used them.
Both are purely static — declarations and references live in one document, no
registry of anything involved.
One thing the report did not mention:
workflowAssetsreturned early when theasset map was empty, so a skill with no assets that still referenced one
would have been missed. The check now runs before that exit.
Also documented
Rule.Needsread as "the rule cannot run without this", while for W2 it is oneof two checks. It now says so on the type, and the partially-dependent rules say
which half needs what — including W12, which the report rightly notes is
entirely dependent on a live tool listing and does not run offline at all. A
CI report of "0 warnings" was giving false confidence about it.
Testing
go vet ./...cleango test ./... -count=1all greengo test ./... -raceall greencatalogue/README guards updated (27 → 29 rules everywhere)
Format & API compatibility
EngineVersionstays 2.2.4 andCHANGELOG.md(which documents the format) is untouched
now show W2 findings offline, and W19/W20 are new — that is the point of
the change
🤖 Generated with Claude Code