Skip to content

Latest commit

 

History

History
23 lines (19 loc) · 7.21 KB

lint.md

File metadata and controls

23 lines (19 loc) · 7.21 KB

crw flow lint

crw flow lint checks scripts for what the engine cannot refuse early. It reads the text of each script (the body parsed with its scopes resolved) and runs it on the fake backend, reading the journal; a finding both find is reported once. It exits 0 when every script is clean, 1 when one has a finding or does not load, 2 for a command line it cannot use. --no-dry-run checks the text only; --args gives the dry run its args. A dry run that ends in an error of the script's own (it reads an arg it was not given, it calls a crw.* operation this build does not have) is a note in the report, not a finding.

Rule What it finds
lifecycle_land_twice, lifecycle_land_without_review, lifecycle_order A lifecycle automaton per executor node and per function that calls crw.commit, crw.verify, crw.review, crw.unitCheck, crw.land or a land release: build once (a rebuild is allowed until the node has landed), then rounds of commit, verify, review, then land at most once, in one of two ways: from a completed review, or, the second way, from verified when a completed unit check of the node's current tree stands (build, unit check, commit, verify, land; also release(land), verify, unit check, land). A crw.unitCheck is legal while the node is built (before the commit, also after a fix) or verified (a committed head) and changes no phase: it sets the node's checked flag (in the journal only a completed crw.unitCheck row of role unit-check whose state is ok with a verdict: a check held for the tool's quota or a blank answer judged nothing), which a build, a resumed executor call of the node (a fix changes the tree) and a land release clear and a commit and a verify keep; where paths meet, a node is checked only when it is checked on every path. A land release is a crw.release whose fourth argument is an object literal with a land key (in the journal, a completed crw.release row with kind land and released true): land-head checks out a committed head, so it moves a node before the build or built to committed; any other release is no event, and an identifier as the fourth argument is none either. A call starts its event where it runs and completes where its promise is used: awaited, returned, passed on or kept by the expression around it (the right side of &&, `
reviewer_family_same Legacy diagnostic retained for old lint records. New lint does not diagnose a review because its model family matches an author; model family is provenance. A separately invoked tool review has no agent thread id. If an agent review's same thread is actually observed, it is a warning recorded in the run and does not block.
label_duplicate A label used twice on one path, or on a call that a loop with at least two rounds shown by the text (for (let i = 0; i < 3; i++), for (const x of [..])) runs every round: no break, continue, return or throw in the loop, and no condition between the loop and the call. The first round of a do … while counts as one run, so do { … } while (false) uses its labels once. Any other repeat is judged by the dry run, which sees whether the call really repeats. Calls without a label do not count.
executor_t1_without_step_decision An executor-t1 call without a stepDecision, or whose stepDecision is not the id crw.tierStep returned earlier on the same path and not overwritten since (the walk follows assignments through branches and loops). A plain function call stays on its caller's path, so a helper that reads the id from its closure or a parameter is left to the dry run; a function given to parallel, pipeline or crw.dag runs on a child path, and a decision it reads from the function that starts it is refused. A continuation inherits it from its handle. The dry run refuses an id that no crw.tierStep returned on the path.
classify_arg, resume_arg crw.classify(...) or resume: given something other than an agent.call result or its handle: the output of agent(), a .output, a bare value.
determinism_stub Date.now(), Math.random(), new Date() and Date() of the engine; a name the header imports (import { now as Date } from './clock.js') is the script's own binding and is not judged as a global.
lane_reads_mutable_let A crw.dag lane function or onSignal function that reads an outer let binding that is assigned again anywhere.
alias_ambiguous A haiku call without isolation, with the two fixes in the message.
call_refused, path_concurrency, load, parse The dry run's own findings: a call the engine refused, a second outstanding call on a path; a script that does not load.

The static rules see the text only: a role that depends on a variable is judged on the dry-run trace.