@lssm-tech/module.lssm-os-control-plane 2.1.2

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.
Files changed (2) hide show
  1. package/README.md +220 -0
  2. package/package.json +236 -0
package/README.md ADDED
@@ -0,0 +1,220 @@
1
+ # `@lssm-tech/module.lssm-os-control-plane`
2
+
3
+ Application-service composition for the LSSM OS control plane.
4
+
5
+ It coordinates validation, plan compilation, Connect authorization requests,
6
+ exact-digest apply, work-order scheduling, tenant-safe status projections,
7
+ Builder handoff receipts, drift, and replay through injected ports. The module
8
+ does not own policy authority, provider credentials, or provider SDKs.
9
+
10
+ ## Public entrypoints
11
+
12
+ - `@lssm-tech/module.lssm-os-control-plane`
13
+ - `@lssm-tech/module.lssm-os-control-plane/application`
14
+ - `@lssm-tech/module.lssm-os-control-plane/worker`
15
+ - `@lssm-tech/module.lssm-os-control-plane/builder-handoff`
16
+ - `@lssm-tech/module.lssm-os-control-plane/ports`
17
+ - `@lssm-tech/module.lssm-os-control-plane/in-memory`
18
+ - `@lssm-tech/module.lssm-os-control-plane/runtime-node-worker`
19
+ - `@lssm-tech/module.lssm-os-control-plane/topology`
20
+
21
+ ## Workspace and published resolution
22
+
23
+ Development exports resolve the exact public subpaths directly to TypeScript
24
+ source, so clean-checkout consumers can typecheck before dependency builds.
25
+ `publishConfig.exports` retains the compiled Bun, Node, browser, and declaration
26
+ paths. The pack verifier applies that projection only in disposable staging;
27
+ never copy the published export map into the workspace manifest.
28
+
29
+ ## Runtime Node V2 worker
30
+
31
+ `LssmOsRuntimeNodeWorkerV2` composes the signed Runtime Node V2 contracts into
32
+ one fail-closed executable loop. It verifies the exact Connect-issued work
33
+ order, delegates signed eligibility authority to the injected durable claim
34
+ port, resumes only an exact ordered durable receipt prefix, routes each step to
35
+ the exact qualified provider binding, and completes from the authoritative
36
+ receipt/evidence set.
37
+
38
+ Every injected asynchronous operation shares one absolute monotonic deadline.
39
+ Provider, receipt, or completion outcomes that cannot be proven are returned as
40
+ `indeterminate`; the worker never fabricates a failed or successful terminal
41
+ receipt after an unresolved provider effect. Provider adapters, Connect
42
+ verification, trusted time, durable work-order state, and durable receipt state
43
+ remain injected ports. No provider SDK or credential material enters this
44
+ module.
45
+
46
+ The V1 `LssmOsControlPlaneWorker` remains available unchanged. Adopters opt in
47
+ to the V2 worker through the dedicated subpath and must provide the authoritative
48
+ Runtime Node ports from `@lssm-tech/lib.lssm-os-runtime`.
49
+
50
+ ## Governed topology controller
51
+
52
+ `LssmOsTopologyControllerV1` evaluates an exact active topology, signed scale
53
+ policy, and current capacity observation through injected ports. It initializes
54
+ an observed transition durably, advances non-effect lifecycle evidence with
55
+ exact-state CAS, requires fresh Connect and V3 operation verification before
56
+ creating `authorized` evidence, and delegates at most one observable step to
57
+ Runtime Node V3. Generic callers cannot promote simulated state into an
58
+ authority-bearing state.
59
+ Rejected, blocked, indeterminate, and manual-custody evidence is admitted only
60
+ when an injected verifier returns the exact closed receipt. Verifier denial,
61
+ throw, timeout, or substitution leaves durable topology state unchanged.
62
+ The controller never mints a Connect decision, work order, claim, fence, or
63
+ provider receipt. If an effect succeeds but its topology receipt cannot be
64
+ confirmed durably, the controller first CAS-transitions the exact V3 operation
65
+ into durable `indeterminate` custody with the receipt ref. Failure to obtain
66
+ that custody is reported separately and is never described as durable.
67
+
68
+ `proposeScaleTransition` is the governed bridge from evaluation to transition
69
+ admission. It re-evaluates the active topology and observation, enforces the
70
+ signed replica, budget, quota, freeze, direction, and reversible-transition
71
+ bounds, binds the exact decision and observation digests to a semantically valid
72
+ transition plan, and admits only one observed transition through the topology
73
+ state port. It does not authorize or execute the plan; those steps still require
74
+ fresh Connect verification and Runtime Node V3 operation, claim, attempt, and
75
+ fence authority.
76
+
77
+ `createDeterministicScalePlannerV1` is the reference policy evaluator behind
78
+ that port. It owns dependency output graphs, accepts one exact stable and fresh
79
+ capacity window, applies hysteresis, cooldown, freeze mode, replica, provider
80
+ quota, tenant concurrency, drain, backlog, and daily-cost bounds, and invokes
81
+ an injected exact policy verifier before history or target resolution. It asks
82
+ the target resolver only for an already-qualified reversible topology
83
+ digest. A changing decision is recorded through an injected durable
84
+ `recordIfLatest` history CAS before it is returned; concurrent controllers
85
+ either receive that exact replay or fail closed. The planner does not provision,
86
+ sign policy, mint Runtime Node authority, or treat a scale decision as execution
87
+ permission.
88
+
89
+ `recordObservedProfileTransition` additionally verifies the complete T0–T3
90
+ recipe before admission. Cache and broker promotion/removal must match the
91
+ exact source and target topology profiles, preserve the authoritative SQL
92
+ component, tenant scope, residency, classification, and encryption policy, and
93
+ change only the declared cache or queue role. Same-kind vertical and horizontal
94
+ plans retain this profile binding. This makes database-only fallback an exact
95
+ governed recipe instead of an environment-driven transport switch.
96
+
97
+ T0↔T1 moves use explicit `promote_state_backend` or `demote_state_backend`
98
+ plans. Those plans must replace both the SQLite/in-process authority and queue
99
+ roles with their PostgreSQL counterparts (or the exact reverse), preserve the
100
+ data policy and scope, and declare the full migration, drain, rollback, and
101
+ decommission lifecycle. Other transition classes continue to reject any
102
+ authority-store substitution.
103
+
104
+ ### Queue admission authority
105
+
106
+ Authorization and scheduling validate the exact externally verified decision,
107
+ verdict, source-plan digest, tenant/workspace/environment, and current desired and
108
+ observed revisions before enqueueing. Time is read again after verification and
109
+ state reads, so expiry during those reads blocks admission. Authorization requests
110
+ also bind the returned decision to the requested actor. Workers retain their
111
+ independent pre-effect validation; queue admission does not replace execution
112
+ fencing or atomic provider custody.
113
+
114
+ ### Reference work-order ownership
115
+
116
+ The in-memory queue snapshots admissions and returned records. Exact admission
117
+ retries preserve the existing lifecycle; changed plan, authorization, execution,
118
+ idempotency or retry-limit bindings are rejected. Scope tuples are encoded without
119
+ delimiter ambiguity. Completion/retry requires an active fenced claim, and exhausted
120
+ orders cannot be claimed again. This adapter remains a local reference, not a
121
+ persistent production queue.
122
+
123
+ ### Legacy worker outcome custody
124
+
125
+ The legacy worker completes every explicit terminal executor result, including
126
+ failure. A thrown apply call or nonterminal return is recorded as indeterminate
127
+ and is not automatically retried: an external effect may have occurred before an
128
+ acknowledgement was lost. Resolve that evidence through the runtime reconciliation
129
+ path before admitting new work. Queue completion errors propagate to the host.
130
+
131
+ ### Builder handoff interoperability
132
+
133
+ Handoff verification reuses Builder's canonical payload digest, excluding the
134
+ derived packet ID and digest field. Real Builder-produced packets can enter
135
+ review without translation. The original LSSM OS id-inclusive `sha256:` digest
136
+ remains readable after exact recomputation for compatibility; new helper output
137
+ uses Builder's format. Both paths require the expected digest and plan match.
138
+ Acceptance remains plan-only and never grants apply authority.
139
+
140
+ Canonical packet IDs are recomputed from the same payload before review acceptance,
141
+ so changing only the packet ID cannot redirect an otherwise valid handoff.
142
+
143
+ Builder Runtime Node execution loads a digest-bound patch payload,
144
+ matches tenant/workspace/environment and delivery plan, and delegates to the
145
+ existing governed patch service only within the injected active-claim callback.
146
+ It does not mint work orders or permits. Runtime coordinator fencing and the
147
+ provider lifecycle receipt adapter remain required before live activation.
148
+
149
+ The apply-only Builder provider adapter keeps patch generation and
150
+ receipt persistence/verification within the active claim callback. Returned
151
+ Runtime Node receipts must match the execution and reference the candidate ID,
152
+ patch hash and head revision. Compensation/observation remain explicitly
153
+ unqualified. Durable receipt storage and actual claim fencing remain host ports.
154
+
155
+ Builder Runtime Node receipt persistence now adapts the existing scoped
156
+ RuntimeWorkOrderReceiptPort. It binds candidate ID/hash/head to the execution,
157
+ requires append plus readback, and returns the original receipt for an identical
158
+ step replay. A changed candidate under the same step is a conflict. Tests use a
159
+ store fixture; production SQL durability and active-claim integration still need
160
+ qualification. Candidate creation success does not mean release approval.
161
+
162
+ The Builder receipt writer is tested against the existing file-backed SQLite
163
+ Runtime Node order/receipt ports: the database is closed and reopened, identical
164
+ replay returns one receipt, changed candidates conflict, and cross-tenant lookup
165
+ is empty. Authority-verifier callbacks remain test fixtures; this validates SQL
166
+ persistence/replay, not production authority or distributed execution fencing.
167
+
168
+ The Builder provider checks for an existing exact-step receipt inside the active
169
+ claim before invoking patch generation. Verified replay returns that receipt
170
+ without generating a second candidate. Read/verification failures stop execution;
171
+ they are not treated as an absent receipt. Payload and scope admission still run
172
+ before replay. This relies on host claim fencing for concurrent execution safety.
173
+
174
+ Worker retries receiving already_claimed can reconcile durable terminal receipts
175
+ and finish an unconfirmed completion write, but cannot execute missing provider
176
+ steps. Those return active_claim_requires_reconciliation. This prevents duplicate
177
+ active worker effects; it does not prove that an expired executor has stopped.
178
+
179
+ The root barrel now exports `createBuilderRuntimeProvider`, its configuration
180
+ types, `BuilderRuntimePatchPayload`, and `createBuilderRuntimeReceiptWriter`.
181
+ The existing active-claim coordinator and durable receipt contracts remain
182
+ mandatory; additive discoverability does not supply production implementations.
183
+
184
+ `createBuilderProviderReceipt` is an additive data-construction export shared by
185
+ V2 and V3 receipt persistence. Its digest is not an authorization or proof of
186
+ storage. Hosts must use the appropriate durable authority owner and verify
187
+ persisted readback before treating the constructed receipt as evidence.
188
+
189
+ ## Builder candidate host
190
+
191
+ `BuilderCandidateHost` implements the existing Builder candidate service with
192
+ canonical operation state, Connect V3 issuance, restart-safe issued-order reads,
193
+ and Durable Queue V2 admission. Configure current member/project resolution and
194
+ immutable profile/lifecycle material; browser request IDs are correlation only.
195
+ Prepare records the accepted operation. Approve persists the signed standard and
196
+ cleanup lifecycle with its budget reservations. Execute separately verifies
197
+ admission authority, advances the operation by CAS and admits the exact envelope.
198
+ Interrupted queue admission can resume; it is not pristine co-atomic admission.
199
+
200
+ Successful candidate output requires a digest-valid terminal receipt linked to
201
+ the persisted provider receipt and verified retained patch/bundle bytes. Queue
202
+ status reads recheck exact admission evidence. Missing, stale, conflicting or
203
+ unavailable evidence never becomes a successful candidate or release. Agent Host
204
+ owns provider effects and stricter dispatch verification. Installation still
205
+ requires concrete durable stores, qualified profiles, signing keys and current
206
+ policy; there is no default authority or model.
207
+
208
+ Candidate payloads may bind their reviewed Builder plan through `builderPlanRef`.
209
+ That signed payload field is checked against the Runtime Node plan digest while
210
+ Connect plan-packet, delivery-plan and quality-plan references retain their own
211
+ identities. Legacy payloads without `builderPlanRef` retain the original delivery-
212
+ plan digest check. Changing the new reference changes the signed payload digest;
213
+ it cannot substitute another plan under an existing work order.
214
+
215
+ Builder provider receipts now report `failed` when the canonical patch risk
216
+ assessment contains `required_check_failed`. Successful generation and retained
217
+ patch bytes cannot override a failed required QA gate. Other review-required
218
+ risk reasons remain review outcomes; they do not silently authorize release.
219
+ Historical immutable receipts are not rewritten. A replay whose recomputed
220
+ result conflicts with existing evidence must reconcile rather than replace it.
package/package.json ADDED
@@ -0,0 +1,236 @@
1
+ {
2
+ "name": "@lssm-tech/module.lssm-os-control-plane",
3
+ "version": "2.1.2",
4
+ "description": "Tenant-safe application services and scheduling for the LSSM OS control plane.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "types": "./dist/index.d.ts",
8
+ "files": [
9
+ "package.json"
10
+ ],
11
+ "scripts": {
12
+ "publish:pkg": "bun publish --tolerate-republish --ignore-scripts --verbose",
13
+ "publish:pkg:canary": "bun publish:pkg --tag canary",
14
+ "build": "bun run clean && bun run build:bundle && bun run build:types",
15
+ "build:bundle": "contractspec-bun-build transpile",
16
+ "build:types": "contractspec-bun-build types",
17
+ "clean": "rimraf dist .turbo",
18
+ "lint": "bun run lint:fix",
19
+ "lint:fix": "node ../../../scripts/biome.cjs check --write .",
20
+ "lint:check": "node ../../../scripts/biome.cjs check .",
21
+ "pack:verify": "bun run build && node ./scripts/verify-pack.mjs",
22
+ "test": "bun test",
23
+ "typecheck": "tsgo --noEmit"
24
+ },
25
+ "dependencies": {
26
+ "@lssm-tech/lib.builder-spec": "workspace:^",
27
+ "@lssm-tech/lib.contracts-spec": "workspace:^",
28
+ "@lssm-tech/lib.crypto-utils": "workspace:^",
29
+ "@lssm-tech/lib.lssm-os-runtime": "workspace:^",
30
+ "@lssm-tech/lib.lssm-os-spec": "workspace:^",
31
+ "@lssm-tech/lib.schema": "workspace:^",
32
+ "zod": "catalog:",
33
+ "@lssm-tech/lib.builder-runtime": "workspace:^",
34
+ "@lssm-tech/lib.contractspec-connect": "workspace:^"
35
+ },
36
+ "devDependencies": {
37
+ "@lssm-tech/tool.bun": "workspace:*",
38
+ "@lssm-tech/tool.typescript": "workspace:*",
39
+ "typescript": "catalog:"
40
+ },
41
+ "exports": {
42
+ ".": "./src/index.ts",
43
+ "./application": "./src/application.ts",
44
+ "./builder-handoff": "./src/builder-handoff.ts",
45
+ "./in-memory": "./src/in-memory.ts",
46
+ "./ports": "./src/ports.ts",
47
+ "./runtime-node-worker": "./src/runtime-node-worker.ts",
48
+ "./topology": "./src/topology-controller.ts",
49
+ "./types": "./src/types.ts",
50
+ "./worker": "./src/worker.ts"
51
+ },
52
+ "publishConfig": {
53
+ "access": "public",
54
+ "registry": "https://registry.npmjs.org",
55
+ "exports": {
56
+ ".": {
57
+ "types": "./dist/index.d.ts",
58
+ "browser": "./dist/browser/index.js",
59
+ "bun": "./dist/index.js",
60
+ "node": "./dist/node/index.js",
61
+ "default": "./dist/index.js"
62
+ },
63
+ "./application": {
64
+ "types": "./dist/application.d.ts",
65
+ "browser": "./dist/browser/application.js",
66
+ "bun": "./dist/application.js",
67
+ "node": "./dist/node/application.js",
68
+ "default": "./dist/application.js"
69
+ },
70
+ "./builder-handoff": {
71
+ "types": "./dist/builder-handoff.d.ts",
72
+ "browser": "./dist/browser/builder-handoff.js",
73
+ "bun": "./dist/builder-handoff.js",
74
+ "node": "./dist/node/builder-handoff.js",
75
+ "default": "./dist/builder-handoff.js"
76
+ },
77
+ "./in-memory": {
78
+ "types": "./dist/in-memory.d.ts",
79
+ "browser": "./dist/browser/in-memory.js",
80
+ "bun": "./dist/in-memory.js",
81
+ "node": "./dist/node/in-memory.js",
82
+ "default": "./dist/in-memory.js"
83
+ },
84
+ "./ports": {
85
+ "types": "./dist/ports.d.ts",
86
+ "browser": "./dist/browser/ports.js",
87
+ "bun": "./dist/ports.js",
88
+ "node": "./dist/node/ports.js",
89
+ "default": "./dist/ports.js"
90
+ },
91
+ "./runtime-node-worker": {
92
+ "types": "./dist/runtime-node-worker.d.ts",
93
+ "browser": "./dist/browser/runtime-node-worker.js",
94
+ "bun": "./dist/runtime-node-worker.js",
95
+ "node": "./dist/node/runtime-node-worker.js",
96
+ "default": "./dist/runtime-node-worker.js"
97
+ },
98
+ "./topology": {
99
+ "types": "./dist/topology-controller.d.ts",
100
+ "browser": "./dist/browser/topology-controller.js",
101
+ "bun": "./dist/topology-controller.js",
102
+ "node": "./dist/node/topology-controller.js",
103
+ "default": "./dist/topology-controller.js"
104
+ },
105
+ "./types": {
106
+ "types": "./dist/types.d.ts",
107
+ "browser": "./dist/browser/types.js",
108
+ "bun": "./dist/types.js",
109
+ "node": "./dist/node/types.js",
110
+ "default": "./dist/types.js"
111
+ },
112
+ "./worker": {
113
+ "types": "./dist/worker.d.ts",
114
+ "browser": "./dist/browser/worker.js",
115
+ "bun": "./dist/worker.js",
116
+ "node": "./dist/node/worker.js",
117
+ "default": "./dist/worker.js"
118
+ }
119
+ }
120
+ },
121
+ "repository": {
122
+ "type": "git",
123
+ "url": "https://github.com/lssm-tech/contractspec.git",
124
+ "directory": "packages/modules/lssm-os-control-plane"
125
+ },
126
+ "homepage": "https://contractspec.io",
127
+ "contractspec": {
128
+ "catalog": {
129
+ "family": "solutions",
130
+ "kind": "module",
131
+ "status": "active",
132
+ "adoptionMode": "adoptable",
133
+ "stability": "experimental",
134
+ "platforms": [
135
+ "web",
136
+ "server"
137
+ ],
138
+ "runtimes": [
139
+ "bun",
140
+ "node",
141
+ "browser"
142
+ ],
143
+ "entrypoints": [
144
+ ".",
145
+ "./application",
146
+ "./builder-handoff",
147
+ "./in-memory",
148
+ "./ports",
149
+ "./runtime-node-worker",
150
+ "./types",
151
+ "./worker"
152
+ ],
153
+ "documentation": [
154
+ {
155
+ "title": "Module Lssm Os Control Plane documentation",
156
+ "url": "https://www.npmjs.com/package/%40lssm-tech%2Fmodule.lssm-os-control-plane",
157
+ "kind": "readme"
158
+ }
159
+ ],
160
+ "examples": [],
161
+ "replacements": [],
162
+ "capabilities": [
163
+ {
164
+ "id": "package.lssm.tech.module.lssm.os.control.plane",
165
+ "title": "Module Lssm Os Control Plane",
166
+ "description": "Tenant-safe application services and scheduling for the LSSM OS control plane.",
167
+ "status": "active",
168
+ "useCases": [
169
+ "Adopt tenant-safe application services and scheduling for the lssm os control plane"
170
+ ],
171
+ "aliases": [
172
+ "module",
173
+ "lssm",
174
+ "control",
175
+ "plane"
176
+ ],
177
+ "pythonEquivalents": [],
178
+ "canonicalImports": [
179
+ {
180
+ "from": "@lssm-tech/module.lssm-os-control-plane",
181
+ "symbols": []
182
+ },
183
+ {
184
+ "from": "@lssm-tech/module.lssm-os-control-plane/application",
185
+ "symbols": []
186
+ },
187
+ {
188
+ "from": "@lssm-tech/module.lssm-os-control-plane/builder-handoff",
189
+ "symbols": []
190
+ },
191
+ {
192
+ "from": "@lssm-tech/module.lssm-os-control-plane/in-memory",
193
+ "symbols": []
194
+ },
195
+ {
196
+ "from": "@lssm-tech/module.lssm-os-control-plane/ports",
197
+ "symbols": []
198
+ },
199
+ {
200
+ "from": "@lssm-tech/module.lssm-os-control-plane/runtime-node-worker",
201
+ "symbols": []
202
+ },
203
+ {
204
+ "from": "@lssm-tech/module.lssm-os-control-plane/types",
205
+ "symbols": []
206
+ },
207
+ {
208
+ "from": "@lssm-tech/module.lssm-os-control-plane/worker",
209
+ "symbols": []
210
+ }
211
+ ],
212
+ "constraints": {
213
+ "platforms": [
214
+ "web",
215
+ "server"
216
+ ],
217
+ "runtimes": [
218
+ "bun",
219
+ "node",
220
+ "browser"
221
+ ],
222
+ "avoidWhen": [
223
+ "The @lssm-tech/module.lssm-os-control-plane package constraints do not match the target runtime or platform."
224
+ ],
225
+ "requires": [
226
+ "TypeScript"
227
+ ]
228
+ },
229
+ "alternatives": [],
230
+ "relationships": [],
231
+ "resolutionPriority": 50
232
+ }
233
+ ]
234
+ }
235
+ }
236
+ }