@aopslabs/aops 0.2.0

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 (171) hide show
  1. package/LICENSE +19 -0
  2. package/NOTICE +7 -0
  3. package/README.md +203 -0
  4. package/assets/agent-assets/core/SKILL.md +49 -0
  5. package/assets/agent-assets/core/references/agentspace/SKILL.md +78 -0
  6. package/assets/agent-assets/core/references/aops-cli-core/SKILL.md +108 -0
  7. package/assets/agent-assets/core/references/chatv3/SKILL.md +48 -0
  8. package/assets/agent-assets/core/references/collaborative-work/SKILL.md +85 -0
  9. package/assets/agent-assets/core/references/discuss/SKILL.md +66 -0
  10. package/assets/agent-assets/core/references/docman/SKILL.md +69 -0
  11. package/assets/agent-assets/core/references/hosted-chat/SKILL.md +64 -0
  12. package/assets/agent-assets/core/references/mission/SKILL.md +54 -0
  13. package/assets/agent-assets/core/references/projectman/SKILL.md +86 -0
  14. package/assets/agent-assets/core/references/sys/SKILL.md +36 -0
  15. package/assets/agent-assets/core/references/view/SKILL.md +58 -0
  16. package/assets/agent-assets/core/references/working-disciplines/SKILL.md +69 -0
  17. package/assets/agent-assets/core/user-guides/agent-assets.md +81 -0
  18. package/assets/agent-assets/core/user-guides/agentspace.md +1098 -0
  19. package/assets/agent-assets/core/user-guides/aops-cli.md +1107 -0
  20. package/assets/agent-assets/core/user-guides/aops-system.md +63 -0
  21. package/assets/agent-assets/core/user-guides/chatv3.md +113 -0
  22. package/assets/agent-assets/core/user-guides/docman.md +162 -0
  23. package/assets/agent-assets/core/user-guides/projectman.md +212 -0
  24. package/assets/agent-assets/core/user-guides/sys.md +94 -0
  25. package/assets/agent-assets/core/user-guides/working-disciplines.md +588 -0
  26. package/assets/agent-assets/gateway/aops/SKILL.md +14 -0
  27. package/assets/r6-remote-session-baseline.json +19 -0
  28. package/assets/skills/aops-install/SKILL.md +231 -0
  29. package/assets/skills/aops-install/agents/openai.yaml +4 -0
  30. package/dist/commands/activity.js +352 -0
  31. package/dist/commands/agent-profile.js +653 -0
  32. package/dist/commands/agent.js +710 -0
  33. package/dist/commands/agents-md.js +125 -0
  34. package/dist/commands/api.js +84 -0
  35. package/dist/commands/archive.js +873 -0
  36. package/dist/commands/artifact.js +535 -0
  37. package/dist/commands/assets.js +1414 -0
  38. package/dist/commands/auth/device-login.js +1 -0
  39. package/dist/commands/auth/legacy-export.js +177 -0
  40. package/dist/commands/auth/login.js +426 -0
  41. package/dist/commands/chat.js +1363 -0
  42. package/dist/commands/chatv3.js +1684 -0
  43. package/dist/commands/checkpoint.js +549 -0
  44. package/dist/commands/commercial-artifact.js +475 -0
  45. package/dist/commands/commercial-license.js +594 -0
  46. package/dist/commands/community-auth.js +62 -0
  47. package/dist/commands/community-cockpit.js +185 -0
  48. package/dist/commands/community-console.js +109 -0
  49. package/dist/commands/community-doctor.js +335 -0
  50. package/dist/commands/community-server.js +2062 -0
  51. package/dist/commands/community-setup.js +284 -0
  52. package/dist/commands/discuss.js +1448 -0
  53. package/dist/commands/doc.js +5219 -0
  54. package/dist/commands/experience.js +922 -0
  55. package/dist/commands/host.js +1127 -0
  56. package/dist/commands/init.js +118 -0
  57. package/dist/commands/memory.js +3129 -0
  58. package/dist/commands/mission.js +562 -0
  59. package/dist/commands/official-catalog.js +134 -0
  60. package/dist/commands/plan.js +84 -0
  61. package/dist/commands/playbook.js +415 -0
  62. package/dist/commands/pm/context.js +6 -0
  63. package/dist/commands/pm/index.js +701 -0
  64. package/dist/commands/pm/projectman.js +6266 -0
  65. package/dist/commands/project.js +1080 -0
  66. package/dist/commands/prompt.js +1024 -0
  67. package/dist/commands/repo-sync.js +1907 -0
  68. package/dist/commands/resource.js +527 -0
  69. package/dist/commands/skill.js +1211 -0
  70. package/dist/commands/start-disciplines.js +510 -0
  71. package/dist/commands/start.js +1343 -0
  72. package/dist/commands/target.js +309 -0
  73. package/dist/commands/version.js +42 -0
  74. package/dist/commands/view.js +1852 -0
  75. package/dist/launchers/cockpit.js +28 -0
  76. package/dist/launchers/options.js +74 -0
  77. package/dist/launchers/server.js +41 -0
  78. package/dist/lib/agent-assets/envelope.js +83 -0
  79. package/dist/lib/agent-assets/gateway.js +15 -0
  80. package/dist/lib/agent-assets/guards.js +23 -0
  81. package/dist/lib/agent-assets/hosted-discovery.js +148 -0
  82. package/dist/lib/agent-assets/hosted-package-input.js +154 -0
  83. package/dist/lib/agent-assets/legacy-pointer-migration.js +677 -0
  84. package/dist/lib/agent-assets/native-fs.js +589 -0
  85. package/dist/lib/agent-assets/package-manifest.js +324 -0
  86. package/dist/lib/agent-assets/portable-path.js +67 -0
  87. package/dist/lib/agent-assets/release-input.js +177 -0
  88. package/dist/lib/agent-assets/roots.js +45 -0
  89. package/dist/lib/agent-assets/runtime-binding-reader.js +545 -0
  90. package/dist/lib/agent-assets/runtime-targets.js +50 -0
  91. package/dist/lib/agent-assets/store-reader.js +1212 -0
  92. package/dist/lib/agent-assets/store-types.js +1 -0
  93. package/dist/lib/agent-assets/store-writer.js +1484 -0
  94. package/dist/lib/agent-assets/types.js +1 -0
  95. package/dist/lib/agent-assets/unicode-case-folding-v15-1.generated.js +1548 -0
  96. package/dist/lib/commercial-final-readiness.js +504 -0
  97. package/dist/lib/commercial-lifecycle-smoke-isolation.js +236 -0
  98. package/dist/lib/commercial-managed-postgres-docker-adapter.js +274 -0
  99. package/dist/lib/commercial-setup-readiness-adapter.js +179 -0
  100. package/dist/lib/community-client-contract.js +164 -0
  101. package/dist/lib/community-cockpit-lifecycle.js +601 -0
  102. package/dist/lib/community-command-abort.js +59 -0
  103. package/dist/lib/community-diagnostic.js +237 -0
  104. package/dist/lib/community-docker-adapter.js +498 -0
  105. package/dist/lib/community-home.js +31 -0
  106. package/dist/lib/community-instance-contract.js +148 -0
  107. package/dist/lib/community-instance-layout.js +97 -0
  108. package/dist/lib/community-lifecycle.js +1631 -0
  109. package/dist/lib/community-migration-snapshot.js +770 -0
  110. package/dist/lib/community-native-application-recovery.js +425 -0
  111. package/dist/lib/community-native-child.js +240 -0
  112. package/dist/lib/community-native-database-recovery.js +456 -0
  113. package/dist/lib/community-native-lifecycle.js +2458 -0
  114. package/dist/lib/community-native-migration.js +339 -0
  115. package/dist/lib/community-native-postgres.js +596 -0
  116. package/dist/lib/community-operation-journal.js +773 -0
  117. package/dist/lib/community-operation-lock.js +596 -0
  118. package/dist/lib/community-release-resolver.js +291 -0
  119. package/dist/lib/community-release-verifier.js +475 -0
  120. package/dist/lib/community-repo-discovery.js +252 -0
  121. package/dist/lib/community-setup-server-env.js +203 -0
  122. package/dist/lib/external-url.js +110 -0
  123. package/dist/lib/official-catalog-gateway.js +108 -0
  124. package/dist/lib/official-catalog.js +364 -0
  125. package/dist/lib/server-bootstrap.js +240 -0
  126. package/dist/lib/setup-agent-assets-bridge.js +176 -0
  127. package/dist/lib/setup-agent-assets-release.js +52 -0
  128. package/dist/lib/setup-external-postgres.js +108 -0
  129. package/dist/lib/setup-init-orchestrator.js +990 -0
  130. package/dist/lib/setup-install-guide.js +52 -0
  131. package/dist/lib/setup-installer-release.js +47 -0
  132. package/dist/lib/setup-local-postgres.js +329 -0
  133. package/dist/lib/setup-official-catalog-bridge.js +148 -0
  134. package/dist/lib/setup-readiness.js +888 -0
  135. package/dist/lib/tui-launcher.js +59 -0
  136. package/dist/main.js +150 -0
  137. package/dist/seeds/agents-md.js +54 -0
  138. package/dist/utils/agent-gateway.js +275 -0
  139. package/dist/utils/agents-md.js +281 -0
  140. package/dist/utils/api.js +255 -0
  141. package/dist/utils/chatv3-session-store.js +185 -0
  142. package/dist/utils/command.js +67 -0
  143. package/dist/utils/community-host-runtime.js +376 -0
  144. package/dist/utils/config.js +1015 -0
  145. package/dist/utils/discussion-workspace.js +552 -0
  146. package/dist/utils/experience-workspace.js +326 -0
  147. package/dist/utils/guide-paths.js +67 -0
  148. package/dist/utils/hosted-sugar.js +56 -0
  149. package/dist/utils/hosted-workspace.js +229 -0
  150. package/dist/utils/memory-workspace.js +537 -0
  151. package/dist/utils/operator-runtime.js +199 -0
  152. package/dist/utils/password-crypto.js +39 -0
  153. package/dist/utils/playbook-workspace.js +479 -0
  154. package/dist/utils/project-context.js +255 -0
  155. package/dist/utils/prompts.js +70 -0
  156. package/dist/utils/refresh-race.js +28 -0
  157. package/dist/utils/repo-config.js +109 -0
  158. package/dist/utils/repo-first-projectman.js +194 -0
  159. package/dist/utils/repo-first-storage.js +13 -0
  160. package/dist/utils/repo-first-view.js +305 -0
  161. package/dist/utils/session-guidance.js +278 -0
  162. package/dist/utils/session-state.js +137 -0
  163. package/dist/utils/table.js +39 -0
  164. package/dist/utils/transient-fs.js +49 -0
  165. package/dist/utils/workspace-root.js +1 -0
  166. package/launchers/aops-cockpit.ps1 +15 -0
  167. package/launchers/aops-cockpit.sh +16 -0
  168. package/launchers/aops-server.ps1 +15 -0
  169. package/launchers/aops-server.sh +16 -0
  170. package/native/tui/win32-x64/aops-tui.exe +0 -0
  171. package/package.json +81 -0
@@ -0,0 +1,475 @@
1
+ import { lstatSync, readFileSync, realpathSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { Command } from 'commander';
4
+ import { CommercialArtifactError, RELEASE_MANIFEST_PURPOSE, managedInstallationLayoutBinding, readVerifiedActiveCommercialArtifact, reestablishCommercialIntegrityAuthority, resolveManagedInstallationLayout, verifyOfflineArtifactImportAuthorization, } from '@aopslabs/artifact-trust-contracts';
5
+ import { installCommercialArtifactBundle, readActiveCommercialArtifact, rollbackCommercialArtifact, } from '@aopslabs/artifact-trust-contracts';
6
+ import { parseLeaseTrustBundleFile } from './commercial-license.js';
7
+ import { setupInstallerReleaseBinding, verifySetupInstallerReleaseManifest, } from '../lib/setup-installer-release.js';
8
+ function isRecord(value) {
9
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
10
+ }
11
+ function exactKeys(value, expected, reason) {
12
+ const actual = Object.keys(value).sort();
13
+ if (JSON.stringify(actual) !== JSON.stringify([...expected].sort()))
14
+ throw new Error(reason);
15
+ }
16
+ function regularFile(filePath, reason) {
17
+ const absolute = path.resolve(process.cwd(), filePath);
18
+ const stat = lstatSync(absolute);
19
+ if (stat.isSymbolicLink() || !stat.isFile())
20
+ throw new Error(reason);
21
+ return realpathSync.native(absolute);
22
+ }
23
+ function jsonFile(filePath, reason) {
24
+ try {
25
+ return JSON.parse(readFileSync(regularFile(filePath, reason), 'utf8'));
26
+ }
27
+ catch (error) {
28
+ if (error instanceof Error && error.message === reason)
29
+ throw error;
30
+ throw new Error(reason);
31
+ }
32
+ }
33
+ function requiredOption(value, reason) {
34
+ const normalized = value?.trim();
35
+ if (!normalized)
36
+ throw new Error(reason);
37
+ return normalized;
38
+ }
39
+ function optionalEpoch(value) {
40
+ if (value === undefined)
41
+ return undefined;
42
+ const parsed = Number(value);
43
+ if (!Number.isSafeInteger(parsed) || parsed < 0) {
44
+ throw new Error('minimum_revocation_epoch_invalid');
45
+ }
46
+ return parsed;
47
+ }
48
+ export function loadReleaseTrustBundleFile(filePath) {
49
+ const resolved = regularFile(filePath, 'release_trust_bundle_unsafe');
50
+ let value;
51
+ try {
52
+ value = JSON.parse(readFileSync(resolved, 'utf8'));
53
+ }
54
+ catch {
55
+ throw new Error('release_trust_bundle_json_invalid');
56
+ }
57
+ if (!isRecord(value))
58
+ throw new Error('release_trust_bundle_schema_invalid');
59
+ exactKeys(value, ['schemaVersion', 'objectType', 'purpose', 'keys'], 'release_trust_bundle_schema_invalid');
60
+ if (value.schemaVersion !== 1 ||
61
+ value.objectType !== 'aops-release-trust-bundle-v1' ||
62
+ value.purpose !== RELEASE_MANIFEST_PURPOSE ||
63
+ !Array.isArray(value.keys) ||
64
+ value.keys.length === 0)
65
+ throw new Error('release_trust_bundle_schema_invalid');
66
+ const keys = value.keys.map((candidate) => {
67
+ if (!isRecord(candidate))
68
+ throw new Error('release_trust_key_invalid');
69
+ const actualKeys = Object.keys(candidate).sort();
70
+ const legacyKeys = ['alg', 'kid', 'publicKeyPem', 'purpose'];
71
+ const rotatingKeys = [
72
+ 'alg', 'kid', 'notAfter', 'notBefore', 'publicKeyPem', 'purpose', 'status',
73
+ ];
74
+ const rotating = actualKeys.length === rotatingKeys.length &&
75
+ actualKeys.every((key, index) => key === rotatingKeys[index]);
76
+ if (!rotating &&
77
+ (actualKeys.length !== legacyKeys.length ||
78
+ actualKeys.some((key, index) => key !== legacyKeys[index])))
79
+ throw new Error('release_trust_key_invalid');
80
+ if (typeof candidate.kid !== 'string' ||
81
+ !/^release\/[A-Za-z0-9._~-]{1,160}$/.test(candidate.kid) ||
82
+ candidate.purpose !== RELEASE_MANIFEST_PURPOSE ||
83
+ candidate.alg !== 'EdDSA' ||
84
+ typeof candidate.publicKeyPem !== 'string' ||
85
+ !candidate.publicKeyPem.startsWith('-----BEGIN PUBLIC KEY-----') ||
86
+ (rotating &&
87
+ !['active', 'verify-only', 'retired', 'revoked'].includes(String(candidate.status))) ||
88
+ (rotating &&
89
+ candidate.notBefore !== null &&
90
+ typeof candidate.notBefore !== 'string') ||
91
+ (rotating &&
92
+ candidate.notAfter !== null &&
93
+ typeof candidate.notAfter !== 'string'))
94
+ throw new Error('release_trust_key_invalid');
95
+ if (candidate.kid.toLowerCase().includes('test-ephemeral')) {
96
+ throw new Error('release_trust_test_key_refused');
97
+ }
98
+ return {
99
+ kid: candidate.kid,
100
+ purpose: RELEASE_MANIFEST_PURPOSE,
101
+ alg: 'EdDSA',
102
+ publicKeyPem: candidate.publicKeyPem,
103
+ ...(rotating ? {
104
+ status: candidate.status,
105
+ ...(candidate.notBefore === null
106
+ ? {}
107
+ : { notBefore: candidate.notBefore }),
108
+ ...(candidate.notAfter === null
109
+ ? {}
110
+ : { notAfter: candidate.notAfter }),
111
+ } : {}),
112
+ };
113
+ });
114
+ if (new Set(keys.map((key) => key.kid)).size !== keys.length) {
115
+ throw new Error('release_trust_key_duplicate');
116
+ }
117
+ return { filePath: resolved, keys: Object.freeze(keys) };
118
+ }
119
+ function storeRoot(options) {
120
+ const configured = options.storeRoot?.trim() || process.env.AOPS_COMMERCIAL_ARTIFACT_STORE?.trim();
121
+ return path.resolve(configured || resolveManagedInstallationLayout().storeRoot);
122
+ }
123
+ function managedIntegrityStateRoot(selectedStoreRoot, layout = resolveManagedInstallationLayout()) {
124
+ return path.resolve(selectedStoreRoot) === path.resolve(layout.storeRoot)
125
+ ? layout.stateRoot
126
+ : undefined;
127
+ }
128
+ function commercialIntegrityStatus(managed, active, metrics) {
129
+ if (!active) {
130
+ return Object.freeze({
131
+ verificationMode: managed ? 'routine' : 'full',
132
+ scheduledVerification: managed
133
+ ? 'listener-readiness-worker-24h'
134
+ : 'not-applicable-custom-store',
135
+ authorityDecision: null,
136
+ fastPathEnabled: false,
137
+ fullVerificationPerformed: false,
138
+ customerVisibleRoutineStartupBudgetMs: 15000,
139
+ startupBudgetEvidenceClass: 'cold-process-real-time-antivirus-enabled-supported-machine',
140
+ reason: 'commercial_artifact_inactive',
141
+ });
142
+ }
143
+ if (!managed) {
144
+ return Object.freeze({
145
+ verificationMode: 'full',
146
+ scheduledVerification: 'not-applicable-custom-store',
147
+ authorityDecision: null,
148
+ fastPathEnabled: false,
149
+ fullVerificationPerformed: true,
150
+ customerVisibleRoutineStartupBudgetMs: 15000,
151
+ startupBudgetEvidenceClass: 'cold-process-real-time-antivirus-enabled-supported-machine',
152
+ reason: 'commercial_integrity_custom_store_full_verification',
153
+ });
154
+ }
155
+ const authorityDecision = metrics?.authorityDecision ?? null;
156
+ const reasons = {
157
+ verified: 'commercial_integrity_fast_path_verified',
158
+ 'full-fallback-authority-unavailable': 'commercial_integrity_authority_unavailable_full_verification',
159
+ 'full-fallback-authority-behind': 'commercial_integrity_authority_behind_full_verification',
160
+ 'full-fallback-size-drift': 'commercial_integrity_size_drift_full_verification',
161
+ 'full-heal-forward': 'commercial_integrity_pending_healed_by_full_verification',
162
+ };
163
+ return Object.freeze({
164
+ verificationMode: 'routine',
165
+ scheduledVerification: 'listener-readiness-worker-24h',
166
+ authorityDecision,
167
+ fastPathEnabled: authorityDecision === 'verified',
168
+ fullVerificationPerformed: metrics?.fullVerificationPerformed ?? true,
169
+ customerVisibleRoutineStartupBudgetMs: 15000,
170
+ startupBudgetEvidenceClass: 'cold-process-real-time-antivirus-enabled-supported-machine',
171
+ reason: authorityDecision === null
172
+ ? 'commercial_integrity_diagnostics_unavailable'
173
+ : reasons[authorityDecision],
174
+ });
175
+ }
176
+ function print(value) {
177
+ console.log(JSON.stringify(value, null, 2));
178
+ }
179
+ function handleError(error) {
180
+ if (error instanceof CommercialArtifactError) {
181
+ print({
182
+ ok: false,
183
+ stage: error.stage,
184
+ decision: error.decision,
185
+ reason: error.reason,
186
+ });
187
+ }
188
+ else {
189
+ print({
190
+ ok: false,
191
+ stage: 'command-input',
192
+ decision: 'deny',
193
+ reason: error instanceof Error ? error.message : String(error),
194
+ });
195
+ }
196
+ process.exitCode = 1;
197
+ }
198
+ export function runCommercialArtifactInstall(options) {
199
+ try {
200
+ const bundleRoot = realpathSync.native(path.resolve(process.cwd(), options.from));
201
+ const trust = loadReleaseTrustBundleFile(options.trustBundle);
202
+ const trustRelative = path.relative(bundleRoot, trust.filePath);
203
+ if (!trustRelative.startsWith('..') && !path.isAbsolute(trustRelative)) {
204
+ throw new Error('release_trust_bundle_must_be_host_pinned_outside_artifact_bundle');
205
+ }
206
+ const managedLayout = options.bootstrapJson
207
+ ? (options.managedLayout ?? resolveManagedInstallationLayout())
208
+ : undefined;
209
+ const selectedStoreRoot = storeRoot(options);
210
+ if (managedLayout &&
211
+ path.resolve(selectedStoreRoot) !== path.resolve(managedLayout.storeRoot))
212
+ throw new Error('customer_managed_store_root_override_refused');
213
+ let offlineAuthorization;
214
+ let installerRelease;
215
+ if (options.bootstrapJson) {
216
+ const challengeFile = requiredOption(options.activationChallengeFile, 'offline_activation_challenge_file_required');
217
+ const leaseTrustFile = requiredOption(options.leaseTrustBundle, 'lease_trust_bundle_required');
218
+ const leaseTrust = regularFile(leaseTrustFile, 'lease_trust_bundle_invalid');
219
+ const leaseTrustRelative = path.relative(bundleRoot, leaseTrust);
220
+ if (!leaseTrustRelative.startsWith('..') && !path.isAbsolute(leaseTrustRelative)) {
221
+ throw new Error('lease_trust_bundle_must_be_host_pinned_outside_artifact_bundle');
222
+ }
223
+ const envelope = jsonFile(path.join(bundleRoot, 'release-manifest.json'), 'release_manifest_invalid');
224
+ const activationResponse = jsonFile(path.join(bundleRoot, 'offline-activation-response.json'), 'offline_activation_response_invalid');
225
+ const activationChallengeToken = readFileSync(regularFile(challengeFile, 'offline_activation_challenge_file_invalid'), 'utf8').trim();
226
+ const hostProtocolVersion = options.hostProtocolVersion;
227
+ const minimumRevocationEpoch = optionalEpoch(options.minimumRevocationEpoch);
228
+ offlineAuthorization = verifyOfflineArtifactImportAuthorization({
229
+ manifestEnvelope: envelope,
230
+ releaseTrustKeys: trust.keys,
231
+ hostProtocolVersion,
232
+ activationResponse,
233
+ activationChallengeToken,
234
+ leaseTrustKeys: parseLeaseTrustBundleFile(leaseTrust),
235
+ leaseIssuer: requiredOption(options.leaseIssuer, 'lease_issuer_required'),
236
+ expected: {
237
+ tenantId: requiredOption(options.tenantId, 'tenant_id_required'),
238
+ installationId: options.installationId,
239
+ hostInstanceId: options.hostInstanceId,
240
+ productId: requiredOption(options.productId, 'product_id_required'),
241
+ ...(minimumRevocationEpoch === undefined
242
+ ? {}
243
+ : { minimumRevocationEpoch }),
244
+ },
245
+ now: options.now,
246
+ });
247
+ installerRelease = verifySetupInstallerReleaseManifest(envelope, {
248
+ trustKeys: trust.keys,
249
+ hostProtocolVersion,
250
+ now: options.now,
251
+ });
252
+ }
253
+ const receipt = installCommercialArtifactBundle({
254
+ storeRoot: selectedStoreRoot,
255
+ bundleRoot,
256
+ installationId: options.installationId,
257
+ hostInstanceId: options.hostInstanceId,
258
+ hostProtocolVersion: options.hostProtocolVersion,
259
+ trustKeys: trust.keys,
260
+ now: options.now,
261
+ customerMode: options.bootstrapJson === true,
262
+ ...(offlineAuthorization === undefined ? {} : { offlineAuthorization }),
263
+ requireRetainedRevocationEpoch: options.recovery === true,
264
+ ...(managedLayout === undefined ? {} : { managedLayout }),
265
+ });
266
+ if (options.bootstrapJson) {
267
+ if (!installerRelease)
268
+ throw new Error('installer_release_binding_required');
269
+ if (!managedLayout)
270
+ throw new Error('managed_installation_layout_required');
271
+ print({
272
+ schemaVersion: 1,
273
+ action: 'commercial-artifact.offline-install',
274
+ mode: 'offline',
275
+ ok: true,
276
+ decision: 'activated',
277
+ installationId: receipt.installationId,
278
+ hostInstanceId: receipt.hostInstanceId,
279
+ layout: managedInstallationLayoutBinding(managedLayout),
280
+ release: setupInstallerReleaseBinding(installerRelease),
281
+ artifact: {
282
+ packageName: receipt.packageName,
283
+ version: receipt.version,
284
+ manifestDigest: receipt.manifestDigest,
285
+ closureDigest: receipt.closureDigest,
286
+ activationGeneration: receipt.activation.generation,
287
+ },
288
+ verification: {
289
+ manifestSignature: receipt.verification.manifestSignatureDecision,
290
+ closureReadback: receipt.verification.closureReadbackDecision,
291
+ hostAbi: receipt.hostAbiReadback.decision,
292
+ antiDowngrade: 'enforced',
293
+ entitlement: 'verified',
294
+ revocationEpoch: 'retained',
295
+ },
296
+ });
297
+ return;
298
+ }
299
+ print({
300
+ ok: true,
301
+ action: 'commercial-artifact.install',
302
+ decision: 'activated',
303
+ storeRoot: selectedStoreRoot,
304
+ receipt,
305
+ });
306
+ }
307
+ catch (error) {
308
+ handleError(error);
309
+ }
310
+ }
311
+ export function runCommercialArtifactStatus(options) {
312
+ try {
313
+ const selectedStoreRoot = storeRoot(options);
314
+ const integrityStateRoot = managedIntegrityStateRoot(selectedStoreRoot, options.managedLayout);
315
+ let routineVerification;
316
+ const receipt = readActiveCommercialArtifact({
317
+ storeRoot: selectedStoreRoot,
318
+ integrityStateRoot,
319
+ verificationMode: integrityStateRoot ? 'routine' : 'full',
320
+ onRoutineVerified: (metrics) => { routineVerification = metrics; },
321
+ });
322
+ print({
323
+ ok: true,
324
+ action: 'commercial-artifact.status',
325
+ storeRoot: selectedStoreRoot,
326
+ active: receipt,
327
+ integrity: commercialIntegrityStatus(integrityStateRoot !== undefined, receipt !== null, routineVerification),
328
+ });
329
+ }
330
+ catch (error) {
331
+ handleError(error);
332
+ }
333
+ }
334
+ export function runCommercialArtifactVerify(options) {
335
+ try {
336
+ const selectedStoreRoot = storeRoot(options);
337
+ const integrityStateRoot = managedIntegrityStateRoot(selectedStoreRoot, options.managedLayout);
338
+ if (!integrityStateRoot)
339
+ throw new Error('commercial_integrity_verify_requires_managed_store');
340
+ const trust = loadReleaseTrustBundleFile(options.trustBundle);
341
+ const active = readVerifiedActiveCommercialArtifact({
342
+ storeRoot: selectedStoreRoot,
343
+ integrityStateRoot,
344
+ verificationMode: 'scheduled',
345
+ trustKeys: trust.keys,
346
+ expectedIdentity: {
347
+ installationId: options.installationId,
348
+ hostInstanceId: options.hostInstanceId,
349
+ },
350
+ });
351
+ if (!active)
352
+ throw new Error('commercial_artifact_not_active');
353
+ print({
354
+ ok: true,
355
+ action: 'commercial-artifact.verify-full',
356
+ decision: 'verified',
357
+ receiptId: active.receipt.receiptId,
358
+ closureDigest: active.receipt.closureDigest,
359
+ activationGeneration: active.receipt.activation.generation,
360
+ nextScheduledVerificationAfterHours: 24,
361
+ });
362
+ }
363
+ catch (error) {
364
+ handleError(error);
365
+ }
366
+ }
367
+ export function runCommercialArtifactReestablishAuthority(options) {
368
+ try {
369
+ if (options.confirmAuthorityReestablish !== 'REESTABLISH-INTEGRITY-AUTHORITY') {
370
+ throw new Error('commercial_integrity_authority_reestablish_confirmation_required');
371
+ }
372
+ const selectedStoreRoot = storeRoot(options);
373
+ const integrityStateRoot = managedIntegrityStateRoot(selectedStoreRoot, options.managedLayout);
374
+ if (!integrityStateRoot) {
375
+ throw new Error('commercial_integrity_authority_reestablish_requires_managed_store');
376
+ }
377
+ const trust = loadReleaseTrustBundleFile(options.trustBundle);
378
+ const result = reestablishCommercialIntegrityAuthority({
379
+ storeRoot: selectedStoreRoot,
380
+ integrityStateRoot,
381
+ trustKeys: trust.keys,
382
+ expectedIdentity: {
383
+ installationId: options.installationId,
384
+ hostInstanceId: options.hostInstanceId,
385
+ },
386
+ });
387
+ print({
388
+ ok: true,
389
+ action: 'commercial-artifact.reestablish-integrity-authority',
390
+ decision: 'authority-reestablished-restart-required',
391
+ receiptId: result.authority.receiptId,
392
+ closureDigest: result.authority.closureDigest,
393
+ activationGeneration: result.authority.activationGeneration,
394
+ authorityReestablished: result.authority.authorityReestablished,
395
+ previousAnchorUnknown: result.authority.previousAnchorUnknown,
396
+ evidencePath: result.evidencePath,
397
+ nextAction: 'restart_aops_server_and_confirm_commercial_integrity_readback',
398
+ });
399
+ }
400
+ catch (error) {
401
+ handleError(error);
402
+ }
403
+ }
404
+ export function runCommercialArtifactRollback(options) {
405
+ try {
406
+ const trust = loadReleaseTrustBundleFile(options.trustBundle);
407
+ const selectedStoreRoot = storeRoot(options);
408
+ const receipt = rollbackCommercialArtifact({
409
+ storeRoot: selectedStoreRoot,
410
+ integrityStateRoot: managedIntegrityStateRoot(selectedStoreRoot, options.managedLayout),
411
+ trustKeys: trust.keys,
412
+ });
413
+ print({
414
+ ok: true,
415
+ action: 'commercial-artifact.rollback',
416
+ decision: 'activated-previous',
417
+ storeRoot: selectedStoreRoot,
418
+ receipt,
419
+ });
420
+ }
421
+ catch (error) {
422
+ handleError(error);
423
+ }
424
+ }
425
+ function withStoreRoot(command) {
426
+ return command
427
+ .option('--store-root <path>', 'Operator-mode artifact store override; customer bootstrap uses the canonical managed per-user root')
428
+ .option('--json', 'Print JSON output');
429
+ }
430
+ export function makeCommercialArtifactCommand() {
431
+ const command = new Command('commercial-artifact')
432
+ .description('Verify, install, inspect, and roll back signed private artifact closures');
433
+ withStoreRoot(command
434
+ .command('install')
435
+ .description('Verify a signed release bundle into CAS and atomically activate its receipt')
436
+ .requiredOption('--from <path>', 'Bundle directory containing release-manifest.json and objects/sha256')
437
+ .requiredOption('--trust-bundle <path>', 'Host-pinned release trust bundle outside the artifact bundle')
438
+ .requiredOption('--installation-id <id>', 'License-bound installation identity')
439
+ .requiredOption('--host-instance-id <id>', 'Host instance identity')
440
+ .option('--host-protocol-version <version>', 'Host commercial artifact ABI protocol', '1')
441
+ .option('--activation-challenge-file <path>', 'Customer offline mode: installation-signed challenge token file')
442
+ .option('--lease-trust-bundle <path>', 'Customer offline mode: host-pinned South lease trust bundle')
443
+ .option('--lease-issuer <issuer>', 'Customer offline mode: expected South lease issuer')
444
+ .option('--tenant-id <id>', 'Customer offline mode: expected tenant identity')
445
+ .option('--product-id <id>', 'Customer offline mode: expected licensed product identity')
446
+ .option('--minimum-revocation-epoch <epoch>', 'Customer offline mode: optional external epoch floor')
447
+ .option('--recovery', 'Require an existing retained revocation epoch before repair')
448
+ .option('--bootstrap-json', 'Print the strict secret-free native bootstrap receipt')
449
+ .action((options) => runCommercialArtifactInstall(options)));
450
+ withStoreRoot(command
451
+ .command('status')
452
+ .description('Verify and print the active host-owned installation receipt')
453
+ .action((options) => runCommercialArtifactStatus(options)));
454
+ withStoreRoot(command
455
+ .command('verify-full')
456
+ .description('Run an explicit full closure verification and refresh scheduled integrity authority')
457
+ .requiredOption('--trust-bundle <path>', 'Host-pinned release trust bundle')
458
+ .requiredOption('--installation-id <id>', 'Expected installation identity')
459
+ .requiredOption('--host-instance-id <id>', 'Expected host instance identity')
460
+ .action((options) => runCommercialArtifactVerify(options)));
461
+ withStoreRoot(command
462
+ .command('reestablish-integrity-authority')
463
+ .description('Guarded full verification that creates a new local integrity anchor after authority loss')
464
+ .requiredOption('--trust-bundle <path>', 'Host-pinned release trust bundle')
465
+ .requiredOption('--installation-id <id>', 'Expected installation identity')
466
+ .requiredOption('--host-instance-id <id>', 'Expected host instance identity')
467
+ .requiredOption('--confirm-authority-reestablish <phrase>', 'Must equal REESTABLISH-INTEGRITY-AUTHORITY; the prior local anchor becomes explicitly unknown')
468
+ .action((options) => runCommercialArtifactReestablishAuthority(options)));
469
+ withStoreRoot(command
470
+ .command('rollback')
471
+ .description('Re-verify the previous manifest and CAS closure before activation')
472
+ .requiredOption('--trust-bundle <path>', 'Host-pinned release trust bundle')
473
+ .action((options) => runCommercialArtifactRollback(options)));
474
+ return command;
475
+ }