@sunstack/cli 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.0
4
+
5
+ Release date: 2026-11-06.
6
+
7
+ - Filters now use named questions and the shared decision-tree walker, with
8
+ declared label endings or unsure. The old single-question filter shape is refused.
9
+ - Rule and filter reference material reaches request state unchanged. Questions
10
+ name their input fields; location is sent only when a rule question reads it.
11
+ Reserved state names and missing reference paths are refused at load.
12
+ - The mechanical `complete` check guards cut or unresolved text. Skill-name loads
13
+ include their opening and cut metadata, as path loads do; unavailable inputs
14
+ remain explicit and a question requiring them ends incomplete.
15
+ - Human lint output uses short numbered warnings, unsure/gap lines and a filter
16
+ summary. `--report FILE` retains exact requests, all answers, model receipts,
17
+ source contents and hashes; `lint show FILE ID` explains one saved result.
18
+ - `lint cases FILE [--set SET]` checks revision-bound rule and filter cases through
19
+ ordinary lint on whole-repository copies with today's rulebook overlaid. It
20
+ reports per-owner counts, stale/unmatched/excluded cases and unassessed bars,
21
+ without changing files used by ordinary lint. Selected historical symlink paths
22
+ are listed as not judged, without following them into a different lint scope.
23
+
3
24
  ## 0.7.1
4
25
 
5
26
  Release date: 2026-11-06.
package/README.md CHANGED
@@ -51,11 +51,29 @@ nonmatching sibling. Blank-line and indentation continuation nodes do not stop
51
51
  or count toward the walk. Values stay in source order, including `previous`
52
52
  values. These sources accept only rule references and leave `remainder` intact.
53
53
 
54
- An ask or combine step can add `"uncertain": "verdict"` to route an in-band
55
- answer, or a choice below `min_probability`, to another step. The walk uses
56
- answers from the same request. Omitting the route ends uncertain at that step.
54
+ Every ask or combine step must declare its `uncertain` route: use `"uncertain"`
55
+ as the ending, or name another step such as `"verdict"`. The walk follows it for
56
+ an in-band answer or a choice below `min_probability`, using answers from the
57
+ same request. A missing route is refused when the rulebook loads.
57
58
  Both the `uncertain` and `results` views report the step that ended the walk.
58
59
 
60
+ Filters declare `per`, `reads: {file, kind, fields: [names]}`, `labels`,
61
+ `questions` and `decision`, with optional `reference`. They use the same steps
62
+ as rules and end in `{ "label": "declared-name" }` or `"unsure"`. Question
63
+ option names are not filter endings. All of a folder's questions go in one
64
+ request; a gate uses the resulting label. The old `question`, `reads.field` and
65
+ filter-level `min_probability` shape is refused.
66
+
67
+ Each question names the fields or reference paths it reads with `check`,
68
+ `against` or `context` in its instructions. Fixed `reference` material reaches
69
+ `state.reference` unchanged and counts toward the request-size limit. The names
70
+ `standard`, `where`, `cut-fields`, `unavailable-fields` and `reference` are
71
+ reserved. Rules send `where` only when a question names it; filters send no
72
+ folder location. A question requiring an unavailable field ends incomplete
73
+ before any model call. `mechanical_check: {tool: "complete", field: "targets"}`
74
+ returns yes only for an uncut available field whose loaded targets resolved and
75
+ have uncut openings. A resolved skill-name load now has an opening too.
76
+
59
77
  Rulebook and ast-grep project paths resolve relative to the configuration file.
60
78
  Checked-file globs resolve from its Git repository root, or from the config
61
79
  directory outside Git. Without `--config`, lint searches the current directory
@@ -85,6 +103,44 @@ logical report order. Each entry has the rule's `name` and marker, the piece's
85
103
  file and first and last line, its outcome (`pass`, `finding`, `not_applicable`,
86
104
  `uncertain` or `incomplete`) and its ending `step` (null before any step ran).
87
105
 
106
+ Default output prints short numbered lines and a filter summary. To inspect a
107
+ result later, save the full report and request one id:
108
+
109
+ ```sh
110
+ sunstack lint --all --report run.json
111
+ sunstack lint show run.json 3
112
+ sunstack lint cases cases.json --set development
113
+ ```
114
+
115
+ A saved report contains each request's exact state and questions, every returned
116
+ answer, requested and resolved models, and the contents and hashes of its config
117
+ and rule files. It retains raw piece evidence for mechanical steps. `lint show`
118
+ needs only that saved file; an excluded rule is marked as never asked and cannot
119
+ be re-walked. Unknown ids return an error with the valid range.
120
+
121
+ A case file contains `cases` and `bars`, plus an optional local `repository`
122
+ path (relative to the case file). Each case has a unique `id`, `revision`, `set`
123
+ and `label_from` (`owner-fix` or `blind-agents`). Rule cases add `kind: "rule"`,
124
+ `rule`, `file`, `lines: [first, last]`, `text_sha256`, and `expected: "warn" |
125
+ "pass"`. Filter cases add `kind: "filter"`, `filter`, `folder`, `reads_sha256`
126
+ and `expected_label`. Line hashes retain line endings. Filter hashes cover
127
+ compact JSON of the declared unprojected field values in lexical key order,
128
+ without reference, cut metadata or folder location; normal filter results expose
129
+ the hash. Each recorded bar names `{for, step, bound, value, set_from: [case ids]}`,
130
+ where `bound` is `yes_at_or_above`, `no_at_or_below` or `min_probability`.
131
+
132
+ Case runs archive the whole repository at each revision, initialize Git metadata
133
+ inside each disposable copy so nested configs retain the repository root, overlay
134
+ today's config and rule inputs, and invoke ordinary lint on selected case paths.
135
+ A selected file or folder that is or traverses a historical symlink is listed as
136
+ `not_judged` with reason `selected path is a symlink`, no result link and no crossed
137
+ bars. It never selects the link's target. Context loads retain their usual behavior.
138
+ Rule cases match exactly one piece that overlaps their lines after checking the
139
+ case's own archived line hash.
140
+ Every selected case is counted or listed, with per-rule and per-filter counts,
141
+ result links and crossed bars. A changed or unrecorded bar is unassessed. The
142
+ command writes no adoption state and changes no ordinary lint inputs.
143
+
88
144
  The decision model is always configured and enabled for asking rules; there is
89
145
  no model-off switch. Ordinary runs with asking rules require an OpenRouter
90
146
  credential before checked-file acquisition, even if a later mechanical branch
@@ -19,7 +19,7 @@
19
19
  "hasInstallScript": true,
20
20
  "license": "MIT",
21
21
  "name": "@sunstack/cli",
22
- "version": "0.7.1"
22
+ "version": "0.8.0"
23
23
  },
24
24
  "node_modules/detect-libc": {
25
25
  "engines": {
@@ -48,5 +48,5 @@
48
48
  }
49
49
  },
50
50
  "requires": true,
51
- "version": "0.7.1"
51
+ "version": "0.8.0"
52
52
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "artifactDownloadUrls": [
3
- "https://github.com/ShravanSunder/sunstack-tools/releases/download/v0.7.1"
3
+ "https://github.com/ShravanSunder/sunstack-tools/releases/download/v0.8.0"
4
4
  ],
5
5
  "bin": {
6
6
  "sunstack": "run-sunstack.js"
@@ -88,7 +88,7 @@
88
88
  "zipExt": ".tar.gz"
89
89
  }
90
90
  },
91
- "version": "0.7.1",
91
+ "version": "0.8.0",
92
92
  "volta": {
93
93
  "node": "18.14.1",
94
94
  "npm": "9.5.0"