@uns-kit/core 3.0.43 → 3.0.45
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/MIGRATIONS.md +37 -0
- package/README.md +14 -0
- package/dist/runtime/retained-store-examples/index-worker.manifest.json +22 -0
- package/dist/runtime/retained-store-examples/measurement-worker.manifest.json +22 -0
- package/dist/runtime/retained-store-guide.md +122 -0
- package/dist/runtime/retained-store-storage-contract.json +9 -0
- package/dist/runtime/retained-store-storage.d.mts +17 -0
- package/dist/runtime/retained-store-storage.mjs +493 -0
- package/dist/runtime/retained-store.d.ts +126 -0
- package/dist/runtime/retained-store.d.ts.map +1 -0
- package/dist/runtime/retained-store.js +373 -0
- package/dist/runtime/retained-store.js.map +1 -0
- package/package.json +10 -1
package/MIGRATIONS.md
CHANGED
|
@@ -9,6 +9,43 @@ Agents must inspect the application's existing ownership and shutdown flow
|
|
|
9
9
|
before editing it. The examples below describe the intended behavior, not a
|
|
10
10
|
mechanical search-and-replace operation.
|
|
11
11
|
|
|
12
|
+
## 3.0.45 - Opt-in retained-store storage protocol
|
|
13
|
+
|
|
14
|
+
When crossing `<3.0.45` to `>=3.0.45`, ordinary applications keep their current
|
|
15
|
+
behavior. Applications adopting bound
|
|
16
|
+
retained stores must declare `storageProtocol: 1`, resolve only the shared resource
|
|
17
|
+
paths, acquire `openRetainedStoreLease(binding)` before opening payload writers,
|
|
18
|
+
and release it only after final writer cleanup. Do not infer support from a Kit
|
|
19
|
+
version or default an old omitted capability to supported. Classify manifest
|
|
20
|
+
resources explicitly as backup payload or metadata when needed.
|
|
21
|
+
|
|
22
|
+
Read the [bundled guide](dist/runtime/retained-store-guide.md) and the two
|
|
23
|
+
unrelated manifests in `dist/runtime/retained-store-examples/`. The source guide
|
|
24
|
+
is `docs/retained-store-adoption.md` in the SDK repository.
|
|
25
|
+
Managed use requires the Runtime's external retained-store root. Older local
|
|
26
|
+
candidate bindings/layouts need reviewed initialization/relocation; the SDK never
|
|
27
|
+
silently changes their absolute roots or converts application data. Snapshot
|
|
28
|
+
requires stopped owners. Preserve original volumes and handle unknown outcomes
|
|
29
|
+
through the same operation ID before restarting any owner.
|
|
30
|
+
|
|
31
|
+
## 3.0.44 - Bounded operator JWKS recovery
|
|
32
|
+
|
|
33
|
+
When crossing `<3.0.44` to `>=3.0.44`, ordinary application handlers, standalone
|
|
34
|
+
shutdown and existing input/output journals need no migration. Applications using
|
|
35
|
+
declared operator endpoints receive this correction from `@uns-kit/api`; consume
|
|
36
|
+
the reviewed published API/core versions together with a frozen dependency lock.
|
|
37
|
+
No application-specific retry wrapper, configuration flag or new Controller
|
|
38
|
+
capability is needed.
|
|
39
|
+
|
|
40
|
+
The shared verifier coalesces key refreshes and retries a transient public-key GET
|
|
41
|
+
once within a bounded deadline. It does not retry an operator request or business
|
|
42
|
+
effect, extend the original key-cache lifetime, or skip parent revocation checks.
|
|
43
|
+
Persistent key-source failure remains a503 and a revoked parent remains denied.
|
|
44
|
+
Keep existing service permissions, launch identity, keys, queues, pause policies
|
|
45
|
+
and durable command receipts; never resume a paused target or broaden scopes to
|
|
46
|
+
make an upgrade pass. Follow the normal reviewed upgrade procedure after npm
|
|
47
|
+
publication. See the [operator contract and regression examples](../../docs/operator-api.md#bounded-jwks-recovery-3044).
|
|
48
|
+
|
|
12
49
|
## 3.0.43 - Shared managed operator route registration
|
|
13
50
|
|
|
14
51
|
This entry describes the prepared 3.0.43 release; npm publication is separate. Existing ordinary
|
package/README.md
CHANGED
|
@@ -29,6 +29,20 @@ npm install @uns-kit/core
|
|
|
29
29
|
- **MQTT helpers** — resilient publishers, topic builders, throttled queues, and handover support.
|
|
30
30
|
- **gRPC gateway** — infrastructure to bridge Python workers into the UNS message fabric.
|
|
31
31
|
|
|
32
|
+
## Optional retained stores (3.0.45)
|
|
33
|
+
|
|
34
|
+
Applications can explicitly declare stable opaque resources for reviewed
|
|
35
|
+
same-host adoption, offline backup and recovery. Import the shared contract from
|
|
36
|
+
`@uns-kit/core/runtime/retained-store.js`; hold its store lease before opening
|
|
37
|
+
payload writers. Ordinary applications retain their existing behavior.
|
|
38
|
+
|
|
39
|
+
Read the [bundled guide](dist/runtime/retained-store-guide.md) and manifests in
|
|
40
|
+
`dist/runtime/retained-store-examples/`, or the
|
|
41
|
+
[source guide](https://github.com/uns-openhub/uns-kit/blob/master/docs/retained-store-adoption.md).
|
|
42
|
+
Runtime mounts, Controller orchestration and helper releases must also support
|
|
43
|
+
the declared capability. The SDK version alone grants no permissions and does
|
|
44
|
+
not move data, enable queues or change the handover protocol.
|
|
45
|
+
|
|
32
46
|
## Basic usage
|
|
33
47
|
|
|
34
48
|
```ts
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"protocol": 1,
|
|
3
|
+
"format": "text-index-v1",
|
|
4
|
+
"resources": [
|
|
5
|
+
{
|
|
6
|
+
"id": "queue",
|
|
7
|
+
"path": "index-data",
|
|
8
|
+
"kind": "directory",
|
|
9
|
+
"required": true,
|
|
10
|
+
"backup": "payload"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"id": "replay",
|
|
14
|
+
"path": "maintenance.json",
|
|
15
|
+
"kind": "file",
|
|
16
|
+
"required": false,
|
|
17
|
+
"backup": "metadata"
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"legacyVersions": [],
|
|
21
|
+
"storageProtocol": 1
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"protocol": 1,
|
|
3
|
+
"format": "measurement-journal-v1",
|
|
4
|
+
"resources": [
|
|
5
|
+
{
|
|
6
|
+
"id": "queue",
|
|
7
|
+
"path": "pending-events",
|
|
8
|
+
"kind": "directory",
|
|
9
|
+
"required": true,
|
|
10
|
+
"backup": "payload"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"id": "policy",
|
|
14
|
+
"path": "destination-policy.json",
|
|
15
|
+
"kind": "file",
|
|
16
|
+
"required": false,
|
|
17
|
+
"backup": "metadata"
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"legacyVersions": ["1.0.0"],
|
|
21
|
+
"storageProtocol": 1
|
|
22
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Retained stores: opt-in same-host adoption
|
|
2
|
+
|
|
3
|
+
Prepared in UNS Kit 3.0.45; npm publication and coordinated Controller/Runtime
|
|
4
|
+
releases are separate steps. Existing applications do not change behavior.
|
|
5
|
+
This is a filesystem capability, separate from the small JSON
|
|
6
|
+
handover-state contract and MQTT output persistence. It does not change the
|
|
7
|
+
default handover protocol, enable disk queues, or transfer data between hosts.
|
|
8
|
+
|
|
9
|
+
## Ownership
|
|
10
|
+
|
|
11
|
+
The SDK owns the versioned manifest, binding, safe path validation and resumable
|
|
12
|
+
same-filesystem rename helpers. Controller owns authenticated review, launch
|
|
13
|
+
checks, reservations, durable operation state and managed lifecycle fences.
|
|
14
|
+
The application owns data schema compatibility, its exclusive writer/lease,
|
|
15
|
+
maintenance semantics, replay and database acknowledgements. Runtime/tools own
|
|
16
|
+
durable mounts and backup/restore coverage. No Controller package-name branches
|
|
17
|
+
or execution of application code are required.
|
|
18
|
+
|
|
19
|
+
Publish `retained-store.manifest.json` at the installed package root. Give each
|
|
20
|
+
opaque resource a stable ID, a relative legacy path, kind and required flag.
|
|
21
|
+
Declare a format only when both versions can safely open the same data. An
|
|
22
|
+
explicit legacy version list permits sources without a manifest; it is a
|
|
23
|
+
compatibility promise by the application, not an automatic schema conversion.
|
|
24
|
+
Keep keys, tokens and startup configuration outside resource declarations.
|
|
25
|
+
|
|
26
|
+
The two example manifests in `examples/retained-store/` deliberately describe
|
|
27
|
+
different applications/formats. Whole data directories include SQLite WAL/SHM
|
|
28
|
+
sidecars without the Controller reading SQLite or interpreting payloads.
|
|
29
|
+
The npm core package includes this guide at `dist/runtime/retained-store-guide.md`
|
|
30
|
+
and the same manifests at `dist/runtime/retained-store-examples/`.
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import {
|
|
34
|
+
readRetainedStoreManifest,
|
|
35
|
+
resolveRetainedStoreResources,
|
|
36
|
+
openRetainedStoreLease,
|
|
37
|
+
} from '@uns-kit/core/runtime/retained-store.js';
|
|
38
|
+
|
|
39
|
+
const resolved = resolveRetainedStoreResources(instanceDirectory,
|
|
40
|
+
readRetainedStoreManifest(packageDirectory),
|
|
41
|
+
{ rttNode: packageName, version: packageVersion, instanceId });
|
|
42
|
+
const lease = resolved.binding ? openRetainedStoreLease(resolved.binding) : undefined;
|
|
43
|
+
// Now open resolved payload resources and acquire application database leases.
|
|
44
|
+
// Keep the shared lease until writers close; call lease?.close() on shutdown.
|
|
45
|
+
// An attached store enters application maintenance before replay.
|
|
46
|
+
const dataDirectory = resolved.resources.queue;
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
A binding is private and names an opaque store UUID, generation, operation,
|
|
50
|
+
owner, reviewed configuration digest and stable directory. The shared store
|
|
51
|
+
metadata must match it exactly. A stale owner or fenced instance fails closed.
|
|
52
|
+
The helper does not acquire the application's database lock or authorize an
|
|
53
|
+
operator. Do not bypass either check with an application-specific fallback.
|
|
54
|
+
|
|
55
|
+
## Host procedure
|
|
56
|
+
|
|
57
|
+
1. Resolve installed package/instance IDs server-side. Require matching portable
|
|
58
|
+
configuration, compatible declarations, exact compiled artifact fingerprints,
|
|
59
|
+
an unoccupied target and one filesystem. Preview never creates storage.
|
|
60
|
+
2. Persist the reviewed selection/digest and, before moving, commit operation
|
|
61
|
+
intent. Require the reviewed source launch's clean physical exit according to
|
|
62
|
+
the supervisor; target must also be stopped. Reserve both managed instances.
|
|
63
|
+
3. Use `prepareRetainedStoreMove` and `applyRetainedStoreMove(plan, 'adopt')`.
|
|
64
|
+
Persist the complete plan before applying it. Moves are atomic per resource,
|
|
65
|
+
fsynced, inode/device pinned and resumable; there is no copy or overwrite
|
|
66
|
+
fallback. Several resources do not form one filesystem transaction.
|
|
67
|
+
4. Commit the binding/current owner and durable outcome before releasing the
|
|
68
|
+
receiving instance fence. Start only the new owner, initially in maintenance.
|
|
69
|
+
5. After stopping that owner, capture `prepareRetainedStoreReturn(plan)` and
|
|
70
|
+
persist return intent. Return the *current* resources, including new optional
|
|
71
|
+
or atomically replaced control files. Never restore an old queue snapshot.
|
|
72
|
+
|
|
73
|
+
Reconcile a timeout by reading/repeating the same operation UUID. A different
|
|
74
|
+
request is not a substitute for recovery. Keep the old-side fence after success.
|
|
75
|
+
A direct manual launch of an older binary outside Controller can ignore a fence;
|
|
76
|
+
this protocol protects managed lifecycle and participating SDK consumers.
|
|
77
|
+
|
|
78
|
+
## Deliberate limits
|
|
79
|
+
|
|
80
|
+
POSIX same-user, same-filesystem storage only. No cross-host transport, resource
|
|
81
|
+
merging, schema conversion, automatic deletion, retention finalization, or
|
|
82
|
+
exactly-once destination guarantee. Unknown write acknowledgements keep their
|
|
83
|
+
existing application semantics. Launches, configurations and artifacts changed
|
|
84
|
+
after review are rejected. An absent target requires the existing installation
|
|
85
|
+
workflow first.
|
|
86
|
+
|
|
87
|
+
Before production release, Runtime and backup tools must explicitly cover the
|
|
88
|
+
stable root, including a queue-excluding backup policy and full restore proof.
|
|
89
|
+
Moving a directory outside the previous archive layout is not backup coverage.
|
|
90
|
+
Consumers must be checked again against published, versioned registry packages;
|
|
91
|
+
a local file tarball is development evidence only.
|
|
92
|
+
|
|
93
|
+
## Runtime storage and backup extension
|
|
94
|
+
|
|
95
|
+
A bound application must now explicitly declare `storageProtocol: 1` in its
|
|
96
|
+
manifest and acquire `openRetainedStoreLease(binding)` before opening payloads.
|
|
97
|
+
Keep that handle until final writer shutdown and close it then; the SDK also pins
|
|
98
|
+
live leases process-wide, bounded to32. This is a participation contract, not an
|
|
99
|
+
inference from an installed SDK version. Older unbound applications keep their
|
|
100
|
+
legacy behavior. Bound sources/targets lacking the declaration are rejected by
|
|
101
|
+
managed startup/adoption instead of being guessed safe for offline capture.
|
|
102
|
+
The storage program has been tested on Node 24 with POSIX local filesystems;
|
|
103
|
+
application payload formats remain opaque to it.
|
|
104
|
+
|
|
105
|
+
The trusted Runtime root is `UNS_RETAINED_STORE_ROOT`; managed adoption requires
|
|
106
|
+
it, and an existing binding must match it exactly. No automatic rebasing of old
|
|
107
|
+
absolute bindings is performed. `store-resources.json` records the declaration,
|
|
108
|
+
including optional per-resource `backup: "payload" | "metadata"` (default payload).
|
|
109
|
+
An incomplete store operation or root restore blocks startup. A returned legacy
|
|
110
|
+
layout leaves a validated empty-store retirement marker, rather than making old
|
|
111
|
+
bindings appear live.
|
|
112
|
+
|
|
113
|
+
The shared `retained-store-storage.mjs` program supplies leases, offline capture
|
|
114
|
+
and retryable restoration without importing application modules. Runtime tools
|
|
115
|
+
vendor its exact bytes/limits with provenance. Capture requires all bound owners
|
|
116
|
+
stopped; output/input journals retain their existing distinct online protocols.
|
|
117
|
+
The full RTT backup includes the extra capsule inside its existing signed,
|
|
118
|
+
age-encrypted payload. Queue-excluding capture reports excluded payloads and
|
|
119
|
+
cannot be used as a complete queue restore. Restore retains store/owner/generation
|
|
120
|
+
identity at the same logical root on another offline volume, and leaves an applying
|
|
121
|
+
fence until complete. Known private partial staging files may be re-created only
|
|
122
|
+
from the verified snapshot; differing published work is never overwritten.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function rootLease(root: string, exclusive?: boolean, restoring?: boolean): () => void;
|
|
2
|
+
export function maintenanceLease(directory: string): () => void;
|
|
3
|
+
export function runtimeLease(binding: unknown): { close: () => void };
|
|
4
|
+
export function captureRetained(
|
|
5
|
+
root: string,
|
|
6
|
+
destination: string,
|
|
7
|
+
mode: string,
|
|
8
|
+
limits: unknown,
|
|
9
|
+
): { state: string; stores: number; files: number; payloadBytes: number };
|
|
10
|
+
export function restoreRetained(
|
|
11
|
+
source: string,
|
|
12
|
+
root: string,
|
|
13
|
+
backupDigest: string,
|
|
14
|
+
limits: unknown,
|
|
15
|
+
afterPublish?: (id: string) => void,
|
|
16
|
+
): { state: string; stores: number };
|
|
17
|
+
export function available(root: string): void;
|