octwin-cli 0.8.5 → 0.8.7
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 +62 -0
- package/dist/index.js +493 -503
- package/dist/lib/declaration-check.js +50 -1
- package/dist/lib/outcome.js +79 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,68 @@ Format: [Keep a Changelog](https://keepachangelog.com/) — newest first, bucket
|
|
|
5
5
|
**Added · Changed · Deprecated · Removed · Fixed · Security**. The platform-wide view lives in the
|
|
6
6
|
repo root [`CHANGELOG.md`](../../CHANGELOG.md); this file is the CLI-only cut that ships with the package.
|
|
7
7
|
|
|
8
|
+
## [0.8.7] - 2026-09-06
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **`validate` now reads a map's KEYS, not only its values.** The declaration walker reported four
|
|
12
|
+
things — an unknown key, a missing `required` key, a wrong scalar type, a value outside a closed
|
|
13
|
+
`enum` — and every one of them is about a VALUE. But a map's keys carry meaning in several
|
|
14
|
+
declarations (`roles.yaml` grant resources and verbs, `xrm.yaml` entity names), and those keys had
|
|
15
|
+
no check at all. Rule 5 replays `propertyNames` — both the `enum` and the `pattern` form.
|
|
16
|
+
|
|
17
|
+
This is why publishing the RBAC vocabulary was worth doing. A pack author wrote `case:` where the
|
|
18
|
+
grant key is `record.case`, passed offline `validate` clean, and learned the truth one bad guess at
|
|
19
|
+
a time from `--remote` round-trips. They gave up on custom RBAC over it. The check now says
|
|
20
|
+
`not a valid key here — must be one of "record.case", …` before a deploy is attempted.
|
|
21
|
+
|
|
22
|
+
It stays inside the file's false-positive rule because it is a **faithful replay**: the same `enum`
|
|
23
|
+
membership and the same JS regex engine Zod itself runs, over a pattern the platform generated. A
|
|
24
|
+
pattern this engine cannot compile is treated like a combinator — walk away, do not guess.
|
|
25
|
+
|
|
26
|
+
Verified 2026-09-06 against the shipped binary: across all 23 marketplace packs rule 5 reports
|
|
27
|
+
**nothing**, with 10 of the 12 pulled declaration schemas carrying `propertyNames` (so the silence
|
|
28
|
+
is a result, not an unexercised branch). A deliberately broken key is caught on both branches — a
|
|
29
|
+
role named `Regional-Agent` against `^[a-z][a-z0-9_]*$`, and a grant key `case:` against an enum
|
|
30
|
+
vocabulary — each naming the file, the path and the rule it broke.
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
- **`deploy` had stopped printing its seed counts entirely.** `printDeploySuccess` read
|
|
34
|
+
`r.summary.records` / `.updated` / `.images` / `.rules` / `.failed`, but the deploy route's
|
|
35
|
+
`summary` is a run-log **string** (`"clinic v1.2.0 — {…}"`), not an object. So every field was
|
|
36
|
+
`undefined`, `parts` stayed empty, and the `if (parts.length)` guard turned *"I am reading the
|
|
37
|
+
wrong field"* into *"there was nothing to say"* — the block printed nothing and looked like a
|
|
38
|
+
deploy that simply seeded no rows. The counts have been on `r.seeded`, keyed by seed kind, and
|
|
39
|
+
`printSeedCounts` already renders them (filtering zeros, which is what makes a partial seed
|
|
40
|
+
legible). The dead block is gone and `printSeedCounts` is called instead.
|
|
41
|
+
|
|
42
|
+
Same shape as the bug 0.8.6 fixed in `validate`: *no data* and *no problem* rendering identically.
|
|
43
|
+
Two independent places in this CLI reached it within one week.
|
|
44
|
+
|
|
45
|
+
## [0.8.6] - 2026-09-04
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
- **`validate` can no longer print a `✓` for a check that did not run.** Each of the eight
|
|
49
|
+
checks now RETURNS an `Outcome` — `passed`, `findings`, or `not-run` — and a single printer
|
|
50
|
+
renders all of them, groups the skips by reason, and computes the exit code. Previously each
|
|
51
|
+
check printed its own `✓` inside the `if` that held its data, with a `skipped[]` array and a
|
|
52
|
+
`skipReasons` Map maintained alongside; it was correct because someone was careful, and the
|
|
53
|
+
next check added was one `if` away from lying again.
|
|
54
|
+
|
|
55
|
+
It had lied twice, in the same shape: the KB-dependent block once printed ONE `✓` above six
|
|
56
|
+
checks whose own `✓`s lived inside their `if`s (so a run with no pulled KB read as "one check,
|
|
57
|
+
passed", and an entire backlog batch reached production that way), and `yamlDocs()` once
|
|
58
|
+
dropped an unparseable file so `validate` printed all-green over a pack the platform's importer
|
|
59
|
+
then refused. **An unparseable file is not "no findings", it is "no idea", and those must never
|
|
60
|
+
print the same** — a check that returns nothing now cannot reach the `passed` branch at all.
|
|
61
|
+
|
|
62
|
+
Output is unchanged for a normal run. `passed` carries its own line, so the reserved-entity
|
|
63
|
+
check keeps the narrower wording it uses when the catalog rules are absent from an older pull.
|
|
64
|
+
`--require-kb` is now one line over the returned skip list.
|
|
65
|
+
|
|
66
|
+
Verified 2026-09-04: all 23 marketplace packs exit 0 with no findings; a pack with no pulled KB
|
|
67
|
+
prints zero `✓` for the six KB-dependent checks plus one grouped ⚠ naming all six, and
|
|
68
|
+
`--require-kb` exits 1; a duplicate YAML key still exits 1 naming the file.
|
|
69
|
+
|
|
8
70
|
## [0.8.5] - 2026-09-02
|
|
9
71
|
|
|
10
72
|
### Added
|