@gregiteen/ssss-cli 0.9.2 → 0.9.4

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
@@ -7,6 +7,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.9.4] - 2026-09-25
11
+ ### Fixed
12
+ - The kernel now returns symbolic failure codes with transport status mapping,
13
+ reconciles prepared resources on dry runs and pre-commit failures, and keeps
14
+ logged commits intact when resource finalization or projection dispatch fails.
15
+ - The reference frontmatter parser handles the documented block-scalar subset,
16
+ and capability and legacy-role checks match the v0.9 authorization contract.
17
+
18
+ ### Changed
19
+ - Aligned the v0.9 specification, conformance fixture statuses, and reference
20
+ implementation. The in-process runner checks expected HTTP statuses, and
21
+ `npm test` validates the spec's example documents and contract tables.
22
+ - Exposed every repository skill to Codex through relative links in
23
+ `.agents/skills`, while keeping the project Total Recall brain private.
24
+ - The release SBOM now hashes only the files included in the npm package.
25
+
26
+ ### Added
27
+ - Completed the `SPEC_CODE_ALIGNMENT` project documentation and audit.
28
+ - Expanded the SSSS project-management skill with workflow references,
29
+ document checks, and review guidance.
30
+
31
+ ## [0.9.3] - 2026-09-24
32
+ ### Fixed
33
+ - Two processes sending an `event` envelope with the same idempotency key at the
34
+ same moment could both append an event, because the kernel records the result
35
+ only after committing and `event` envelopes have no VFS compare-and-swap. The
36
+ kernel now derives an `event` envelope's `event_id` from `(workspace_id,
37
+ idempotency_key)` (`idempotentEventId`, UUIDv5), so the event store rejects
38
+ the second append. Any request that loses at commit re-reads the idempotency
39
+ store and returns the winner's result as a replay, or an idempotency conflict
40
+ when its request differs. If a process dies after appending an event but
41
+ before recording its result, retries of that key now fail instead of
42
+ appending a second event.
43
+
44
+ ### Added
45
+ - `idempotentEventId(workspaceId, idempotencyKey)` in `@gregiteen/ssss-cli/events`.
46
+ - Conformance checks racing six kernel processes on one `event` idempotency key,
47
+ with identical and with differing content.
48
+
10
49
  ## [0.9.2] - 2026-09-24
11
50
  ### Fixed
12
51
  - The file adapters are now safe to share between processes. Each one checked
package/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.2
1
+ 0.9.4
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://ssss.dev/conformance/v1",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "Canonical SSSS Operation Contract conformance fixtures. These define the canonical request/response shapes for the Operation Contract (spec §6) and are the shared test contract every SSSS implementation MUST pass. A host is conformant only if, for every fixture, it produces the expected response and status code (spec §12).",
5
5
  "spec_url": "../docs/ssss-spec.md",
6
6
  "operation_types": {
@@ -159,6 +159,9 @@
159
159
  "idempotency_key": "22222222-2222-2222-2222-222222222222",
160
160
  "path": "assistants/bad-bot/ASSISTANT.md",
161
161
  "workspace_id": "TEST_WORKSPACE_ID",
162
+ "actor": {
163
+ "role": "system"
164
+ },
162
165
  "content": "---\ntype: assistant\ntitle: \"Create Assistant — Missing Required Name Field\"\ntimestamp: \"2026-07-02T00:00:00Z\"\ndescription: \"Missing the name field.\"\n---\n\n## Instructions\n\nBroken bot.",
163
166
  "intent": "Conformance fixture: missing required name field"
164
167
  },
@@ -302,7 +305,7 @@
302
305
  ]
303
306
  }
304
307
  },
305
- "expected_http_status": 422
308
+ "expected_http_status": 400
306
309
  },
307
310
  {
308
311
  "id": "fixture-008",
@@ -413,7 +416,7 @@
413
416
  ]
414
417
  }
415
418
  },
416
- "expected_http_status": 422
419
+ "expected_http_status": 401
417
420
  },
418
421
  {
419
422
  "id": "fixture-012",
@@ -469,9 +472,9 @@
469
472
  "Missing required field 'object' for type 'memory' when schema_version==2 in memory/incomplete-schema2.md.",
470
473
  "Missing required field 'sentiment_polarity' for type 'memory' when schema_version==2 in memory/incomplete-schema2.md."
471
474
  ]
472
- },
473
- "expected_http_status": 422
474
- }
475
+ }
476
+ },
477
+ "expected_http_status": 422
475
478
  },
476
479
  {
477
480
  "id": "fixture-014",
@@ -611,7 +614,7 @@
611
614
  ]
612
615
  }
613
616
  },
614
- "expected_http_status": 422
617
+ "expected_http_status": 403
615
618
  },
616
619
  {
617
620
  "id": "fixture-019",
@@ -754,21 +757,27 @@
754
757
  "idempotency_key": "35353535-3535-3535-3535-353535353535",
755
758
  "path": "rules/translatable-refund-rule.md",
756
759
  "workspace_id": "TEST_WORKSPACE_ID",
757
- "actor": { "role": "system" },
760
+ "actor": {
761
+ "role": "system"
762
+ },
758
763
  "content": "---\ntype: rule\ntitle: \"Política de reembolsos\"\ndescription: \"Explica cuándo están disponibles los reembolsos.\"\ntimestamp: \"2026-07-10T00:00:00Z\"\nname: refund-policy\nlanguage: es\n---\nLos reembolsos están disponibles antes de la fecha límite.",
759
764
  "intent": "Conformance fixture: create a non-English structural source"
760
765
  },
761
766
  "expected_response": {
762
767
  "success": true,
763
768
  "type": "operation",
764
- "validation": { "valid": true, "type": "rule", "errors": [] }
769
+ "validation": {
770
+ "valid": true,
771
+ "type": "rule",
772
+ "errors": []
773
+ }
765
774
  }
766
775
  }
767
776
  ],
768
777
  "error_codes": {
769
778
  "400": "invalid_request — Invalid parameters, directory traversal, malformed request envelope, or path template mismatch",
770
- "401": "unauthorized — Missing or invalid auth token / session",
771
- "403": "forbidden — Access denied (workspace membership check failed or system scope isolation violation)",
779
+ "401": "unauthorized — Missing or invalid verified principal (no authenticated identity reached the kernel)",
780
+ "403": "forbidden — The verified principal is not scoped to the workspace or lacks a required capability",
772
781
  "404": "not_found — The requested file to patch or delete does not exist",
773
782
  "409": "lease_conflict, version_conflict, or idempotency_conflict — Lease locked, out-of-date expected version, or idempotency key replay payload mismatch",
774
783
  "422": "validation_failed — Primitive registry/conformance validation errors (contains validation.errors and repair in body)",
@@ -781,5 +790,5 @@
781
790
  ],
782
791
  "maintained_by": "SSSS standard (canonical: this repo)",
783
792
  "provenance": "Seeded from the festech.live reference implementation, which authored the original shared contract; canonicalized here as the vendor-neutral source of truth.",
784
- "last_updated": "2026-07-10"
793
+ "last_updated": "2026-09-24"
785
794
  }
@@ -106,7 +106,7 @@
106
106
  "file_count": 14,
107
107
  "provenance": {
108
108
  "content_hash": "sha256:7febd673938a3dc04c068e0bf08097a9783c09e612606d2df9a4db8dcb8907f5",
109
- "exporter": "@gregiteen/ssss-cli@0.9.2"
109
+ "exporter": "@gregiteen/ssss-cli@0.9.4"
110
110
  }
111
111
  },
112
112
  "files": [
@@ -13,6 +13,23 @@ most one racer wins:
13
13
 
14
14
  `.ssss-locks/` is reserved: VFS paths under it are rejected and `list()` skips it.
15
15
 
16
+ ## Same idempotency key from two processes
17
+
18
+ The kernel records a request's result only after it commits, so two processes
19
+ can both miss the stored result for one key. The commit step then decides:
20
+
21
+ - `operation`, `patch`, `delete`: the VFS compare-and-swap lets one commit; the
22
+ other fails its precondition.
23
+ - `event`: the event's `event_id` is derived from `(workspace_id,
24
+ idempotency_key)` (`idempotentEventId`, a UUIDv5), so the event store rejects
25
+ the second append.
26
+
27
+ The loser then re-reads the idempotency store: if the winner has already
28
+ recorded its result, the loser returns it as a replay (or an idempotency
29
+ conflict when its request differs); otherwise it fails and a retry replays. If a
30
+ process dies after appending an event but before recording the result, retries
31
+ of that key fail rather than append a second event.
32
+
16
33
  ## Crashed holders
17
34
 
18
35
  A lock records its holder's pid and host. A waiter breaks the lock when the
@@ -31,10 +48,6 @@ Symlinked lock files are refused.
31
48
 
32
49
  - Locks are advisory: only writers using these adapters take them. Writers from
33
50
  `@gregiteen/ssss-cli` 0.9.1 and earlier do not.
34
- - The kernel's idempotency check for `event` envelopes is read before commit and
35
- written after, so two processes sending the same idempotency key at the same
36
- moment can each append an event. `operation`, `patch`, and `delete` are
37
- protected by the VFS compare-and-swap.
38
51
  - Network filesystems must support exclusive create (`O_EXCL`).
39
52
  - Dead-holder detection assumes processes that share the filesystem have
40
53
  distinct hostnames (containers with the same hostname and separate pid