@sunstack/cli 0.2.0 → 0.4.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,46 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.0
4
+
5
+ Release date: 2026-10-30.
6
+
7
+ ### Breaking
8
+
9
+ - Set `within` to a nonempty list of distinct kinds, for example
10
+ `["step", "standards_section"]`. A match counts once inside any listed kind,
11
+ including overlapping containers. Rewrite `"within": "x"` as `"within": ["x"]`.
12
+ A present `null` or any non-list is refused; omit the key for no containment.
13
+
14
+ ### Fixed
15
+
16
+ - Check refusals for undefined kinds, cycles and `within` entries point at the
17
+ actual kind or field, including names with dots. Cycle refusals name and point
18
+ at the first kind in the cycle.
19
+ - Config refusals use the full setting path: `limits.evidence_max_chars`,
20
+ `check.files`, `evidence.kinds`, `evidence.ast_grep`,
21
+ `rulebook.<index>.markdown` and `rulebook.<index>.rules`.
22
+
23
+ ### Internal
24
+
25
+ - Separate child startup waits from active test deadlines (#113).
26
+ - Group Rust crate modules by responsibility (#110).
27
+ - Batch repository metadata reads (#112).
28
+ - Run CI on PRs and main, with cache writes only from main (#109, #111).
29
+
30
+ ## 0.3.0
31
+
32
+ Release date: 2026-10-30.
33
+
34
+ - Add noul-based evidence selection, kind containment, kind-based field sources and
35
+ strict-child remainder exclusions. Selection and rules share model-request limits.
36
+ - Report every asked candidate and per-file/per-kind counts, including files with
37
+ no candidates. Selected kinds require credentials for `--evidence`; `--check`
38
+ remains credential-free. Uncertain and incomplete selection affect run status.
39
+ - Recognize numbered and Step section headings at H2 through H6, excluding H1.
40
+ Configurations using those generic utilities can gain evidence within the new
41
+ sections and changed fields or results that read them.
42
+ - Run the fresh-install smoke in TypeScript with a current rulebook fixture.
43
+
3
44
  ## 0.2.0
4
45
 
5
46
  This pre-1.0 minor release cuts over the lint configuration and rulebook format.
package/README.md CHANGED
@@ -48,9 +48,11 @@ sunstack lint --config sunstack.lint.json --all --format json
48
48
  ```
49
49
 
50
50
  `--check` validates configuration, the rulebook and evidence project, then lists
51
- the assembled rules as JSON. It reads no checked files and sends no model
52
- requests. `--evidence [KIND]` prints picked evidence and its fields as JSON without
53
- asking the model. Both routes work without a credential.
51
+ the assembled rules and selected/contained kinds as JSON. It reads no checked
52
+ files, sends no model requests and needs no credential. `--evidence [KIND]` prints
53
+ picked pieces, selection outcomes and file counts as JSON. It runs evidence
54
+ selection when configured, requiring a credential, but sends no rule questions.
55
+ Without selected kinds, the evidence listing remains credential-free.
54
56
 
55
57
  An ordinary lint run uses changed evidence by default and requires Git for that
56
58
  default scope. Use `--all` for every configured target, `--since REV` for changes
@@ -65,7 +67,9 @@ file and first and last line, its outcome (`pass`, `finding`, `not_applicable`,
65
67
  The decision model is always configured and enabled for asking rules; there is
66
68
  no model-off switch. Ordinary runs with asking rules require an OpenRouter
67
69
  credential before checked-file acquisition, even if a later mechanical branch
68
- would avoid an ask. Mechanical-only rules need no key. Credential lookup and
70
+ would avoid an ask. A selected evidence kind also requires a credential, including
71
+ for `--evidence`, even when the rules are mechanical. With neither selected kinds
72
+ nor asking rules, no key is needed. Credential lookup and
69
73
  saving are described below under the native protocol.
70
74
 
71
75
  Lint exits 0 for clean or nothing selected, 1 for error findings or warnings over
@@ -81,6 +85,94 @@ for a complete test example. Copy the fixture directory to an isolated root to
81
85
  try it; its checked-file globs are relative to that root. The example's
82
86
  skill-specific rules are test content.
83
87
 
88
+ ## Selected and contained evidence
89
+
90
+ Add `select` to an evidence kind to ask one noul question about each mechanical
91
+ candidate. Add `within` to keep a kind's matches only inside or equal to a final
92
+ piece of any listed kind in the same file. `within` is a nonempty list without
93
+ repeated kinds, written as `["workflow_section"]` for one kind. A match inside
94
+ several listed kinds produces one piece. This fragment belongs in `evidence.kinds`;
95
+ the rule IDs must exist in the caller's ast-grep project:
96
+
97
+ ```json
98
+ {
99
+ "workflow_section": {
100
+ "rule": "workflow-candidate",
101
+ "fields": {
102
+ "heading": { "from": "first_line" },
103
+ "body": { "from": "remainder", "exclude": { "rule": "section" } },
104
+ "outline": { "from": "same_file", "rule": "section" }
105
+ },
106
+ "select": {
107
+ "question": {
108
+ "type": "noul",
109
+ "instructions": {
110
+ "check": "body",
111
+ "against": "heading",
112
+ "context": ["outline"],
113
+ "task": "Is this section an ordered workflow?"
114
+ }
115
+ },
116
+ "yes_at_or_above": 0.7,
117
+ "no_at_or_below": 0.3,
118
+ "shared": ["outline"]
119
+ }
120
+ },
121
+ "step": {
122
+ "rule": "step",
123
+ "within": ["workflow_section"],
124
+ "fields": { "body": { "from": "remainder" } }
125
+ },
126
+ "load": {
127
+ "rule": "load",
128
+ "fields": { "step": { "from": "enclosing", "kind": "step" } }
129
+ }
130
+ }
131
+ ```
132
+
133
+ Answers at or above 0.7 select the candidate; at or below 0.3 reject it; values
134
+ between them are uncertain. Only selected candidates become pieces. A failed
135
+ selection remains incomplete; it never falls back to selecting the candidate.
136
+ Kinds build in dependency order before any rules run. Cycles, undefined kinds,
137
+ invalid thresholds, non-noul selection questions and target-field references in
138
+ selection questions are refused by `--check`.
139
+
140
+ `inside`, `enclosing` and `same_file` accept exactly one of `rule` or `kind`.
141
+ A rule source reads raw matches; a kind source reads final pieces after selection
142
+ and containment. `remainder.exclude` removes only strictly contained ranges,
143
+ including child sections; an equal range never erases the piece itself. A target's
144
+ `as_kind` must remain target-free and independent of selection.
145
+
146
+ The model receives consecutive candidates of one file and kind, with one question
147
+ per candidate. Fields in `shared` must come from `same_file`; their view is bounded
148
+ once and sent once per request. Each candidate has its own bounded view without
149
+ shared or target fields. Questions cannot refer to target fields, and selection
150
+ requests carry no target opening or target-file fields. Requests split to satisfy
151
+ encoded character, byte, question-count and input-token limits. Selection and rule
152
+ requests share the run's request count, concurrency and usage accounting.
153
+
154
+ Under a change scope, selection considers all candidates of each file with a
155
+ changed hunk or a changed load target. Other files retain their candidate counts
156
+ with `asked: 0`. Final pieces are still picked by their own changed ranges or
157
+ changed targets; changing only a parent heading does not pick every child step.
158
+
159
+ JSON reports and evidence listings add `selections` and `file_counts`. Each asked
160
+ candidate reports its kind, source location, first line and outcome, with a yes
161
+ probability or an incomplete reason. Counts cover every built file and configured
162
+ kind, including zero-candidate files: matches, pieces, picked and scan-limited,
163
+ plus candidate/asked/outcome counts for selected kinds. The default format prints
164
+ selection totals and files with candidates but none selected. Selection uncertainty
165
+ uses exit 5 unless a higher-priority status applies; any incomplete candidate
166
+ makes the run incomplete with `selection_incomplete`. GitHub and SARIF formatting
167
+ is unchanged.
168
+
169
+ The generic numbered-heading and Step-heading utilities recognize levels H2
170
+ through H6; H1 titles are excluded. Existing configurations otherwise preserve
171
+ 0.2.0 behavior, apart from these extra heading matches and evidence, fields and
172
+ results derived from their sections. See the complete
173
+ [selection fixture](tests/fixtures/rulebook-lint/selection/skill-rules.config.json)
174
+ for working configuration inputs; its domain-specific question is test content.
175
+
84
176
  ## Native JSON protocol
85
177
 
86
178
  Run `sunstack exec` (or `cargo run -p sunstack -- exec` from the repository root).
@@ -19,7 +19,7 @@
19
19
  "hasInstallScript": true,
20
20
  "license": "MIT",
21
21
  "name": "@sunstack/cli",
22
- "version": "0.2.0"
22
+ "version": "0.4.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.2.0"
51
+ "version": "0.4.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.2.0"
3
+ "https://github.com/ShravanSunder/sunstack-tools/releases/download/v0.4.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.2.0",
91
+ "version": "0.4.0",
92
92
  "volta": {
93
93
  "node": "18.14.1",
94
94
  "npm": "9.5.0"