@gregiteen/ssss-cli 0.10.0 → 0.10.1
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 +12 -0
- package/VERSION +1 -1
- package/conformance/reference-bundle.ucw.json +1 -1
- package/package.json +1 -1
- package/scripts/conformance-09.mjs +12 -0
- package/src/registry.mjs +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.10.1] - 2026-09-28
|
|
11
|
+
### Fixed
|
|
12
|
+
- A required list field set to an empty list (`deferred_steps: []`) was
|
|
13
|
+
rejected as "Missing required field". Required means present: only an
|
|
14
|
+
absent, `null` or empty-string value is missing now. Hosts had to patch the
|
|
15
|
+
package to write valid documents with empty lists.
|
|
16
|
+
|
|
17
|
+
### Behavior changes hosts should check
|
|
18
|
+
- Documents with a required list field set to `[]` now validate.
|
|
19
|
+
- New conformance checks: an empty list satisfies a required list field;
|
|
20
|
+
absent, `null` and empty-string values are still missing.
|
|
21
|
+
|
|
10
22
|
## [0.10.0] - 2026-09-28
|
|
11
23
|
### Added
|
|
12
24
|
- **`asset` primitive**: Text-encoded files (Base64 for small binaries, UTF-8 for code/SVGs) and pointer metadata for large files (`resource_ref`, `storage_uri`, `hash`).
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.10.
|
|
1
|
+
0.10.1
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
"file_count": 14,
|
|
107
107
|
"provenance": {
|
|
108
108
|
"content_hash": "sha256:7febd673938a3dc04c068e0bf08097a9783c09e612606d2df9a4db8dcb8907f5",
|
|
109
|
-
"exporter": "@gregiteen/ssss-cli@0.10.
|
|
109
|
+
"exporter": "@gregiteen/ssss-cli@0.10.1"
|
|
110
110
|
}
|
|
111
111
|
},
|
|
112
112
|
"files": [
|
package/package.json
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
createRegistryLock,
|
|
10
10
|
loadRegistries,
|
|
11
11
|
resolvePrimitiveDefinition,
|
|
12
|
+
validateDataConstraints,
|
|
12
13
|
verifyRegistryLock,
|
|
13
14
|
} from '../src/registry.mjs';
|
|
14
15
|
import { createValidator } from '../src/validator.mjs';
|
|
@@ -258,6 +259,16 @@ function checkFrontmatterSubset(check) {
|
|
|
258
259
|
JSON.stringify(parseDocument(serializeDocument(data, '\nbody')).data) === JSON.stringify(data));
|
|
259
260
|
}
|
|
260
261
|
|
|
262
|
+
// A required field is satisfied by any present value, including an empty
|
|
263
|
+
// list; only an absent, null or empty-string value is missing.
|
|
264
|
+
function checkRequiredPresence(check) {
|
|
265
|
+
const def = { required_fields: ['steps', 'name'] };
|
|
266
|
+
const missing = (data) => validateDataConstraints(def, data).map((i) => i.field).sort().join(',');
|
|
267
|
+
check('required fields: an empty list satisfies a required list field', missing({ steps: [], name: 'x' }) === '');
|
|
268
|
+
check('required fields: absent, null and empty-string values are missing',
|
|
269
|
+
missing({ name: '' }) === 'name,steps' && missing({ steps: null, name: 'x' }) === 'steps');
|
|
270
|
+
}
|
|
271
|
+
|
|
261
272
|
// Capabilities (spec §6.6): trailing-`*` grants are prefix scoped, and the
|
|
262
273
|
// pre-0.9 façade still honors the role permissions it always documented.
|
|
263
274
|
async function checkCapabilities(root, check) {
|
|
@@ -606,6 +617,7 @@ export async function runKernel09Conformance() {
|
|
|
606
617
|
check('UI planning redacts prompt-injection content and falls back safely', planned.generated && planned.manifest.components[0].bind === 'status');
|
|
607
618
|
await checkResourceLifecycle(check);
|
|
608
619
|
checkFrontmatterSubset(check);
|
|
620
|
+
checkRequiredPresence(check);
|
|
609
621
|
await checkCapabilities(temp, check);
|
|
610
622
|
} finally {
|
|
611
623
|
fs.rmSync(temp, { recursive: true, force: true });
|
package/src/registry.mjs
CHANGED
|
@@ -355,8 +355,9 @@ export function documentHash(content) {
|
|
|
355
355
|
}
|
|
356
356
|
|
|
357
357
|
function isEmpty(value) {
|
|
358
|
-
|
|
359
|
-
|
|
358
|
+
// "Required" means present: an empty array (e.g. `deferred_steps: []`) is a
|
|
359
|
+
// valid value for a required list field, so it is not treated as missing.
|
|
360
|
+
return value === undefined || value === null || value === '';
|
|
360
361
|
}
|
|
361
362
|
|
|
362
363
|
/**
|