create-principles-disciple 1.132.1 → 1.132.3

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 (221) hide show
  1. package/console/dist/server/routes/update.js +187 -19
  2. package/console/dist/server/update/mutation-controller.d.ts +18 -0
  3. package/console/dist/server/update/mutation-controller.js +29 -0
  4. package/console/dist/server/utils/installed-layout.d.ts +1 -0
  5. package/console/dist/server/utils/installed-layout.js +2 -0
  6. package/console/package.json +1 -0
  7. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +15 -0
  8. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
  9. package/core/dist/runtime-v2/adapter/__tests__/pd-stream-simple.test.d.ts +2 -0
  10. package/core/dist/runtime-v2/adapter/__tests__/pd-stream-simple.test.d.ts.map +1 -0
  11. package/core/dist/runtime-v2/adapter/__tests__/pd-stream-simple.test.js +71 -0
  12. package/core/dist/runtime-v2/adapter/__tests__/pd-stream-simple.test.js.map +1 -0
  13. package/core/dist/runtime-v2/adapter/__tests__/pi-ai-http-transport.test.d.ts +2 -0
  14. package/core/dist/runtime-v2/adapter/__tests__/pi-ai-http-transport.test.d.ts.map +1 -0
  15. package/core/dist/runtime-v2/adapter/__tests__/pi-ai-http-transport.test.js +219 -0
  16. package/core/dist/runtime-v2/adapter/__tests__/pi-ai-http-transport.test.js.map +1 -0
  17. package/core/dist/runtime-v2/adapter/artificer-l2-adapter.d.ts.map +1 -1
  18. package/core/dist/runtime-v2/adapter/artificer-l2-adapter.js +2 -3
  19. package/core/dist/runtime-v2/adapter/artificer-l2-adapter.js.map +1 -1
  20. package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.d.ts +12 -1
  21. package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.d.ts.map +1 -1
  22. package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.js +15 -2
  23. package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.js.map +1 -1
  24. package/core/dist/runtime-v2/adapter/pi-ai-http-transport.d.ts +50 -0
  25. package/core/dist/runtime-v2/adapter/pi-ai-http-transport.d.ts.map +1 -0
  26. package/core/dist/runtime-v2/adapter/pi-ai-http-transport.js +93 -0
  27. package/core/dist/runtime-v2/adapter/pi-ai-http-transport.js.map +1 -0
  28. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.d.ts.map +1 -1
  29. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.js +5 -0
  30. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.js.map +1 -1
  31. package/core/dist/runtime-v2/internalization/__tests__/diag-router-runner.test.js +43 -0
  32. package/core/dist/runtime-v2/internalization/__tests__/diag-router-runner.test.js.map +1 -1
  33. package/core/dist/runtime-v2/internalization/__tests__/mvp-core-loop-journeys.test.js +55 -0
  34. package/core/dist/runtime-v2/internalization/__tests__/mvp-core-loop-journeys.test.js.map +1 -1
  35. package/core/dist/runtime-v2/internalization/__tests__/owner-decision.test.js +152 -0
  36. package/core/dist/runtime-v2/internalization/__tests__/owner-decision.test.js.map +1 -1
  37. package/core/dist/runtime-v2/internalization/__tests__/rule-code-dialect.test.js +30 -9
  38. package/core/dist/runtime-v2/internalization/__tests__/rule-code-dialect.test.js.map +1 -1
  39. package/core/dist/runtime-v2/internalization/__tests__/shared-information-plane-runner.test.js +131 -0
  40. package/core/dist/runtime-v2/internalization/__tests__/shared-information-plane-runner.test.js.map +1 -1
  41. package/core/dist/runtime-v2/internalization/diag-router-runner.d.ts.map +1 -1
  42. package/core/dist/runtime-v2/internalization/diag-router-runner.js +35 -0
  43. package/core/dist/runtime-v2/internalization/diag-router-runner.js.map +1 -1
  44. package/core/dist/runtime-v2/internalization/internalization-orchestrator.d.ts.map +1 -1
  45. package/core/dist/runtime-v2/internalization/internalization-orchestrator.js +23 -0
  46. package/core/dist/runtime-v2/internalization/internalization-orchestrator.js.map +1 -1
  47. package/core/dist/runtime-v2/internalization/legacy-rule-contract-scanner.d.ts +11 -0
  48. package/core/dist/runtime-v2/internalization/legacy-rule-contract-scanner.d.ts.map +1 -1
  49. package/core/dist/runtime-v2/internalization/legacy-rule-contract-scanner.js +11 -1
  50. package/core/dist/runtime-v2/internalization/legacy-rule-contract-scanner.js.map +1 -1
  51. package/core/dist/runtime-v2/internalization/owner-review.d.ts +7 -1
  52. package/core/dist/runtime-v2/internalization/owner-review.d.ts.map +1 -1
  53. package/core/dist/runtime-v2/internalization/owner-review.js +22 -3
  54. package/core/dist/runtime-v2/internalization/owner-review.js.map +1 -1
  55. package/core/dist/runtime-v2/internalization/rule-code-validator.d.ts +7 -4
  56. package/core/dist/runtime-v2/internalization/rule-code-validator.d.ts.map +1 -1
  57. package/core/dist/runtime-v2/internalization/rule-code-validator.js +25 -2
  58. package/core/dist/runtime-v2/internalization/rule-code-validator.js.map +1 -1
  59. package/core/package.json +3 -2
  60. package/dist/installer.d.ts.map +1 -1
  61. package/dist/installer.js +50 -0
  62. package/dist/installer.js.map +1 -1
  63. package/dist/update/release-manager-authority.d.ts +69 -0
  64. package/dist/update/release-manager-authority.d.ts.map +1 -0
  65. package/dist/update/release-manager-authority.js +125 -0
  66. package/dist/update/release-manager-authority.js.map +1 -0
  67. package/dist/utils/workspace-divergence.d.ts +36 -0
  68. package/dist/utils/workspace-divergence.d.ts.map +1 -0
  69. package/dist/utils/workspace-divergence.js +87 -0
  70. package/dist/utils/workspace-divergence.js.map +1 -0
  71. package/host-runtime/dist/internalization-consumer-cycle.js +12 -1
  72. package/host-runtime/package.json +1 -1
  73. package/install-layout/dist/index.d.ts +5 -0
  74. package/install-layout/dist/index.js +1 -0
  75. package/install-layout/package.json +1 -1
  76. package/package.json +3 -2
  77. package/pd-cli/dist/commands/codex-worker.d.ts.map +1 -1
  78. package/pd-cli/dist/commands/codex-worker.js +14 -2
  79. package/pd-cli/dist/commands/codex-worker.js.map +1 -1
  80. package/pd-cli/dist/commands/runtime-internalization-run-once.d.ts.map +1 -1
  81. package/pd-cli/dist/commands/runtime-internalization-run-once.js +19 -3
  82. package/pd-cli/dist/commands/runtime-internalization-run-once.js.map +1 -1
  83. package/pd-cli/package.json +1 -1
  84. package/plugin/dist/bundle.js +871 -735
  85. package/plugin/dist/governance-audit.js +381 -247
  86. package/plugin/dist/openclaw-sdk.d.ts +3 -0
  87. package/plugin/dist/rulehost-evidence.js +420 -286
  88. package/plugin/dist/service/subagent-workflow/types.d.ts +2 -2
  89. package/plugin/dist/utils/retry.d.ts +1 -1
  90. package/plugin/dist/utils/workspace-resolver.d.ts +35 -4
  91. package/plugin/openclaw.plugin.json +1 -1
  92. package/plugin/package.json +1 -1
  93. package/release-manager/dist/i18n.d.ts +6 -0
  94. package/release-manager/dist/i18n.d.ts.map +1 -0
  95. package/release-manager/dist/i18n.js +234 -0
  96. package/release-manager/dist/i18n.js.map +1 -0
  97. package/release-manager/dist/index.d.ts +7 -0
  98. package/release-manager/dist/index.d.ts.map +1 -0
  99. package/release-manager/dist/index.js +474 -0
  100. package/release-manager/dist/index.js.map +1 -0
  101. package/release-manager/dist/installer.d.ts +185 -0
  102. package/release-manager/dist/installer.d.ts.map +1 -0
  103. package/release-manager/dist/installer.js +2305 -0
  104. package/release-manager/dist/installer.js.map +1 -0
  105. package/release-manager/dist/installers/codex-host-installer.d.ts +29 -0
  106. package/release-manager/dist/installers/codex-host-installer.d.ts.map +1 -0
  107. package/release-manager/dist/installers/codex-host-installer.js +494 -0
  108. package/release-manager/dist/installers/codex-host-installer.js.map +1 -0
  109. package/release-manager/dist/installers/index.d.ts +40 -0
  110. package/release-manager/dist/installers/index.d.ts.map +1 -0
  111. package/release-manager/dist/installers/index.js +35 -0
  112. package/release-manager/dist/installers/index.js.map +1 -0
  113. package/release-manager/dist/installers/openclaw-host-installer.d.ts +18 -0
  114. package/release-manager/dist/installers/openclaw-host-installer.d.ts.map +1 -0
  115. package/release-manager/dist/installers/openclaw-host-installer.js +414 -0
  116. package/release-manager/dist/installers/openclaw-host-installer.js.map +1 -0
  117. package/release-manager/dist/mvp-config.d.ts +197 -0
  118. package/release-manager/dist/mvp-config.d.ts.map +1 -0
  119. package/release-manager/dist/mvp-config.js +509 -0
  120. package/release-manager/dist/mvp-config.js.map +1 -0
  121. package/release-manager/dist/prompts.d.ts +30 -0
  122. package/release-manager/dist/prompts.d.ts.map +1 -0
  123. package/release-manager/dist/prompts.js +231 -0
  124. package/release-manager/dist/prompts.js.map +1 -0
  125. package/release-manager/dist/skill-language.d.ts +32 -0
  126. package/release-manager/dist/skill-language.d.ts.map +1 -0
  127. package/release-manager/dist/skill-language.js +107 -0
  128. package/release-manager/dist/skill-language.js.map +1 -0
  129. package/release-manager/dist/uninstaller.d.ts +55 -0
  130. package/release-manager/dist/uninstaller.d.ts.map +1 -0
  131. package/release-manager/dist/uninstaller.js +409 -0
  132. package/release-manager/dist/uninstaller.js.map +1 -0
  133. package/release-manager/dist/update/atomic-file.d.ts +35 -0
  134. package/release-manager/dist/update/atomic-file.d.ts.map +1 -0
  135. package/release-manager/dist/update/atomic-file.js +120 -0
  136. package/release-manager/dist/update/atomic-file.js.map +1 -0
  137. package/release-manager/dist/update/bootstrap-protocol.d.ts +55 -0
  138. package/release-manager/dist/update/bootstrap-protocol.d.ts.map +1 -0
  139. package/release-manager/dist/update/bootstrap-protocol.js +132 -0
  140. package/release-manager/dist/update/bootstrap-protocol.js.map +1 -0
  141. package/release-manager/dist/update/channel-metadata.d.ts +28 -0
  142. package/release-manager/dist/update/channel-metadata.d.ts.map +1 -0
  143. package/release-manager/dist/update/channel-metadata.js +90 -0
  144. package/release-manager/dist/update/channel-metadata.js.map +1 -0
  145. package/release-manager/dist/update/channel-promotion.d.ts +39 -0
  146. package/release-manager/dist/update/channel-promotion.d.ts.map +1 -0
  147. package/release-manager/dist/update/channel-promotion.js +55 -0
  148. package/release-manager/dist/update/channel-promotion.js.map +1 -0
  149. package/release-manager/dist/update/data-compatibility.d.ts +35 -0
  150. package/release-manager/dist/update/data-compatibility.d.ts.map +1 -0
  151. package/release-manager/dist/update/data-compatibility.js +45 -0
  152. package/release-manager/dist/update/data-compatibility.js.map +1 -0
  153. package/release-manager/dist/update/install-layout.d.ts +59 -0
  154. package/release-manager/dist/update/install-layout.d.ts.map +1 -0
  155. package/release-manager/dist/update/install-layout.js +127 -0
  156. package/release-manager/dist/update/install-layout.js.map +1 -0
  157. package/release-manager/dist/update/legacy-migration.d.ts +56 -0
  158. package/release-manager/dist/update/legacy-migration.d.ts.map +1 -0
  159. package/release-manager/dist/update/legacy-migration.js +254 -0
  160. package/release-manager/dist/update/legacy-migration.js.map +1 -0
  161. package/release-manager/dist/update/product-identity.d.ts +50 -0
  162. package/release-manager/dist/update/product-identity.d.ts.map +1 -0
  163. package/release-manager/dist/update/product-identity.js +63 -0
  164. package/release-manager/dist/update/product-identity.js.map +1 -0
  165. package/release-manager/dist/update/release-asset-manifest.d.ts +31 -0
  166. package/release-manager/dist/update/release-asset-manifest.d.ts.map +1 -0
  167. package/release-manager/dist/update/release-asset-manifest.js +161 -0
  168. package/release-manager/dist/update/release-asset-manifest.js.map +1 -0
  169. package/release-manager/dist/update/release-identity.d.ts +33 -0
  170. package/release-manager/dist/update/release-identity.d.ts.map +1 -0
  171. package/release-manager/dist/update/release-identity.js +108 -0
  172. package/release-manager/dist/update/release-identity.js.map +1 -0
  173. package/release-manager/dist/update/release-manager-authority.d.ts +69 -0
  174. package/release-manager/dist/update/release-manager-authority.d.ts.map +1 -0
  175. package/release-manager/dist/update/release-manager-authority.js +125 -0
  176. package/release-manager/dist/update/release-manager-authority.js.map +1 -0
  177. package/release-manager/dist/update/release-manager.d.ts +96 -0
  178. package/release-manager/dist/update/release-manager.d.ts.map +1 -0
  179. package/release-manager/dist/update/release-manager.js +253 -0
  180. package/release-manager/dist/update/release-manager.js.map +1 -0
  181. package/release-manager/dist/update/release-metadata.d.ts +57 -0
  182. package/release-manager/dist/update/release-metadata.d.ts.map +1 -0
  183. package/release-manager/dist/update/release-metadata.js +200 -0
  184. package/release-manager/dist/update/release-metadata.js.map +1 -0
  185. package/release-manager/dist/update/release-policy.d.ts +51 -0
  186. package/release-manager/dist/update/release-policy.d.ts.map +1 -0
  187. package/release-manager/dist/update/release-policy.js +103 -0
  188. package/release-manager/dist/update/release-policy.js.map +1 -0
  189. package/release-manager/dist/update/rollback-policy.d.ts +56 -0
  190. package/release-manager/dist/update/rollback-policy.d.ts.map +1 -0
  191. package/release-manager/dist/update/rollback-policy.js +61 -0
  192. package/release-manager/dist/update/rollback-policy.js.map +1 -0
  193. package/release-manager/dist/update/transaction-journal.d.ts +131 -0
  194. package/release-manager/dist/update/transaction-journal.d.ts.map +1 -0
  195. package/release-manager/dist/update/transaction-journal.js +346 -0
  196. package/release-manager/dist/update/transaction-journal.js.map +1 -0
  197. package/release-manager/dist/update/trust-metadata.d.ts +55 -0
  198. package/release-manager/dist/update/trust-metadata.d.ts.map +1 -0
  199. package/release-manager/dist/update/trust-metadata.js +170 -0
  200. package/release-manager/dist/update/trust-metadata.js.map +1 -0
  201. package/release-manager/dist/update/update-history.d.ts +46 -0
  202. package/release-manager/dist/update/update-history.d.ts.map +1 -0
  203. package/release-manager/dist/update/update-history.js +123 -0
  204. package/release-manager/dist/update/update-history.js.map +1 -0
  205. package/release-manager/dist/utils/config-file-io.d.ts +26 -0
  206. package/release-manager/dist/utils/config-file-io.d.ts.map +1 -0
  207. package/release-manager/dist/utils/config-file-io.js +128 -0
  208. package/release-manager/dist/utils/config-file-io.js.map +1 -0
  209. package/release-manager/dist/utils/env.d.ts +60 -0
  210. package/release-manager/dist/utils/env.d.ts.map +1 -0
  211. package/release-manager/dist/utils/env.js +308 -0
  212. package/release-manager/dist/utils/env.js.map +1 -0
  213. package/release-manager/dist/utils/logger.d.ts +15 -0
  214. package/release-manager/dist/utils/logger.d.ts.map +1 -0
  215. package/release-manager/dist/utils/logger.js +30 -0
  216. package/release-manager/dist/utils/logger.js.map +1 -0
  217. package/release-manager/dist/utils/workspace-divergence.d.ts +36 -0
  218. package/release-manager/dist/utils/workspace-divergence.d.ts.map +1 -0
  219. package/release-manager/dist/utils/workspace-divergence.js +87 -0
  220. package/release-manager/dist/utils/workspace-divergence.js.map +1 -0
  221. package/release-manager/package.json +78 -0
@@ -8,9 +8,10 @@ import { appendUpdateHistory } from './update-history.js';
8
8
  import { checkOpenClawGateway, stopOpenClawGateway, restartOpenClawGateway, } from '../utils/gateway.js';
9
9
  import { migrateLegacyExtensionBackups, reservePdBackupDestination, resolvePdBackupsRoot, } from '../utils/pd-backups.js';
10
10
  import { resolveExtensionsDir, resolveUpdateLayout, resolvePluginDir, readCurrentVersion, } from '../utils/installed-layout.js';
11
- import { ActivationCompatibilityReadModel } from '@principles/core/runtime-v2';
11
+ import { ActivationCompatibilityReadModel, isFeatureEnabled } from '@principles/core/runtime-v2';
12
12
  import { collectFileDepLinkSpecs } from '../utils/update-links.js';
13
- import { updateMutationController, LEGACY_MUTATION_AUTHORITY, } from '../update/mutation-controller.js';
13
+ import { updateMutationController, LEGACY_MUTATION_AUTHORITY, RELEASE_MANAGER_AUTHORITY, MUTATION_KINDS, } from '../update/mutation-controller.js';
14
+ import { loadPdConfig, computeFlagsFromLoadResult } from '../config/pd-config-store.js';
14
15
  /**
15
16
  * Legacy rule contract preflight (2026-08-19): refuse to swap the runtime
16
17
  * while an ACTIVE owner-approved rule still depends on a RuleHost contract
@@ -904,6 +905,11 @@ function ensureRuntimeResolutionLinks(layout, tempDir) {
904
905
  { manifestDir: path.join(tempDir, 'install-layout'), deployedDir: layout.installLayoutDir },
905
906
  { manifestDir: path.join(tempDir, 'core'), deployedDir: layout.coreDir },
906
907
  { manifestDir: path.join(tempDir, 'plugin'), deployedDir: layout.pluginDir },
908
+ // PRI-672: staged release-manager component (npm name
909
+ // create-principles-disciple). Its staged manifest carries the
910
+ // file:../install-layout ref, and the staged console's manifest carries
911
+ // file:../release-manager — both derive their resolution links here.
912
+ { manifestDir: path.join(tempDir, 'release-manager'), deployedDir: layout.releaseManagerDir },
907
913
  ];
908
914
  const readStagedDependencies = (manifestDir) => {
909
915
  try {
@@ -1152,6 +1158,18 @@ async function doInlineFullUpdate(workspaceDir) {
1152
1158
  if (fs.existsSync(path.join(installLayoutSrc, 'package.json')) && fs.existsSync(path.join(installLayoutSrc, 'dist'))) {
1153
1159
  copyDirRecursive(installLayoutSrc, layout.installLayoutDir, SKIP_DIRS);
1154
1160
  }
1161
+ // PRI-672: the release-manager component (npm name
1162
+ // create-principles-disciple — the ReleaseManager authority module the
1163
+ // updated console imports) must land BEFORE the swap and its resolution
1164
+ // link, same PRI-561 ordering as host-runtime/install-layout. Conditioned
1165
+ // on the staged component so updates from tarballs published before this
1166
+ // component existed simply skip it (their console does not import it).
1167
+ const releaseManagerSrc = path.join(tempDir, 'release-manager');
1168
+ if (fs.existsSync(releaseManagerSrc) &&
1169
+ fs.existsSync(path.join(releaseManagerSrc, 'package.json')) &&
1170
+ fs.existsSync(path.join(releaseManagerSrc, 'dist'))) {
1171
+ copyDirRecursive(releaseManagerSrc, layout.releaseManagerDir, SKIP_DIRS);
1172
+ }
1155
1173
  const { error: linkError, quarantined } = ensureRuntimeResolutionLinks(layout, tempDir);
1156
1174
  reconciledQuarantine = quarantined;
1157
1175
  if (linkError) {
@@ -1321,6 +1339,33 @@ async function doInlineFullUpdate(workspaceDir) {
1321
1339
  * registers under `release-manager` for the same kinds and this route layer
1322
1340
  * needs no further change.
1323
1341
  */
1342
+ /**
1343
+ * Compute the legacy update-check response body (PRI-659 handler body, split
1344
+ * out in PRI-672 so the ReleaseManager-governed check can serve the exact
1345
+ * same wire contract). Behavior is unchanged: degraded ERR-002 shape when the
1346
+ * current version cannot be determined, network checks otherwise.
1347
+ */
1348
+ async function computeLegacyUpdateCheck(pluginDir) {
1349
+ // ERR-002 / Runtime Contract Rule 9: 当无法确定当前版本时(如插件未安装),
1350
+ // 返回 degraded 状态 + reason,而非 500。前端 validateUpdateStatus 要求
1351
+ // currentVersion/latestVersion 为 string,hasUpdate 为 boolean。
1352
+ const currentVersion = readCurrentVersion(pluginDir);
1353
+ const codexInstalled = detectCodexInstall();
1354
+ if (!currentVersion) {
1355
+ return {
1356
+ currentVersion: undefined,
1357
+ body: {
1358
+ hasUpdate: false,
1359
+ currentVersion: 'unknown',
1360
+ latestVersion: '',
1361
+ codexInstalled,
1362
+ error: 'Could not determine current version (plugin not installed)',
1363
+ },
1364
+ };
1365
+ }
1366
+ const result = await doCheckForUpdates(currentVersion);
1367
+ return { currentVersion, body: { ...result, codexInstalled } };
1368
+ }
1324
1369
  function legacyCheckMutation(req, res, ctx) {
1325
1370
  return (async () => {
1326
1371
  const pluginDir = resolvePluginDir(ctx.workspaceDir);
@@ -1329,23 +1374,8 @@ function legacyCheckMutation(req, res, ctx) {
1329
1374
  return;
1330
1375
  }
1331
1376
  try {
1332
- // ERR-002 / Runtime Contract Rule 9: 当无法确定当前版本时(如插件未安装),
1333
- // 返回 degraded 状态 + reason,而非 500。前端 validateUpdateStatus 要求
1334
- // currentVersion/latestVersion 为 string,hasUpdate 为 boolean。
1335
- const currentVersion = readCurrentVersion(pluginDir);
1336
- const codexInstalled = detectCodexInstall();
1337
- if (!currentVersion) {
1338
- sendSuccess(res, {
1339
- hasUpdate: false,
1340
- currentVersion: 'unknown',
1341
- latestVersion: '',
1342
- codexInstalled,
1343
- error: 'Could not determine current version (plugin not installed)',
1344
- });
1345
- return;
1346
- }
1347
- const result = await doCheckForUpdates(currentVersion);
1348
- sendSuccess(res, { ...result, codexInstalled });
1377
+ const { body } = await computeLegacyUpdateCheck(pluginDir);
1378
+ sendSuccess(res, body);
1349
1379
  }
1350
1380
  catch (err) {
1351
1381
  sendError(res, 500, 'update_check_error', err instanceof Error ? err.message : 'Unknown error');
@@ -1473,6 +1503,140 @@ updateMutationController.register('check', { name: LEGACY_MUTATION_AUTHORITY, ha
1473
1503
  updateMutationController.register('apply', { name: LEGACY_MUTATION_AUTHORITY, handler: legacyApplyMutation });
1474
1504
  updateMutationController.register('apply-full', { name: LEGACY_MUTATION_AUTHORITY, handler: legacyApplyFullMutation });
1475
1505
  updateMutationController.register('rollback', { name: LEGACY_MUTATION_AUTHORITY, handler: legacyRollbackMutation });
1506
+ let releaseManagerModuleState = { state: 'unattempted' };
1507
+ function releaseManagerFlagEnabled(workspaceDir) {
1508
+ const flags = computeFlagsFromLoadResult(loadPdConfig(workspaceDir));
1509
+ return isFeatureEnabled(flags, 'release_manager_shadow');
1510
+ }
1511
+ function fallbackToLegacyForAllKinds(reason) {
1512
+ for (const kind of MUTATION_KINDS) {
1513
+ updateMutationController.unregister(kind, RELEASE_MANAGER_AUTHORITY);
1514
+ updateMutationController.setFallbackReason(kind, reason);
1515
+ }
1516
+ }
1517
+ /**
1518
+ * Governed check dispatch (kind `check` only, flag on, readiness ready at
1519
+ * registration time). Runs the ReleaseManager shadow check for governance and
1520
+ * parity evidence, then serves the legacy-computed response body — byte-for-
1521
+ * byte the legacy contract. On a ReleaseManager refusal the response headers
1522
+ * are re-annotated to the explicit fallback and the legacy body is served
1523
+ * anyway: check is read-only, so the fallback cannot leave partial state.
1524
+ */
1525
+ async function runReleaseManagerCheckDispatch(mod, req, res, ctx) {
1526
+ if (req.method !== 'GET') {
1527
+ sendMethodNotAllowed(res);
1528
+ return;
1529
+ }
1530
+ const pluginDir = resolvePluginDir(ctx.workspaceDir);
1531
+ // One legacy computation feeds BOTH the shadow comparison (via legacyCheck)
1532
+ // and the response body — a governed check never doubles network cost.
1533
+ let legacyOnce = null;
1534
+ const legacyComputed = () => {
1535
+ legacyOnce ??= () => computeLegacyUpdateCheck(pluginDir);
1536
+ return legacyOnce();
1537
+ };
1538
+ let decisionSource = null;
1539
+ const authority = mod.createReleaseManagerAuthority({
1540
+ pdHome: path.join(os.homedir(), '.pd'),
1541
+ metadataBaseUrl: process.env.PD_RELEASE_METADATA_URL,
1542
+ legacyCheck: async (currentVersion) => {
1543
+ if (decisionSource === null)
1544
+ return null;
1545
+ return decisionSource(currentVersion);
1546
+ },
1547
+ });
1548
+ decisionSource = async () => {
1549
+ const computed = await legacyComputed();
1550
+ if (computed.currentVersion === undefined)
1551
+ return null;
1552
+ const raw = computed.body;
1553
+ return {
1554
+ source: 'legacy-updater',
1555
+ latestVersion: typeof raw.latestVersion === 'string' && raw.latestVersion.length > 0 ? raw.latestVersion : null,
1556
+ updateAvailable: raw.hasUpdate === true,
1557
+ };
1558
+ };
1559
+ if (authority.installStatus === null || !authority.kinds.check.ready) {
1560
+ // Readiness flipped between registration sync and dispatch — explicit
1561
+ // fallback, never a half-governed check.
1562
+ const reasons = authority.installStatus === null
1563
+ ? 'install_state_corrupt'
1564
+ : authority.kinds.check.reasons.join(',');
1565
+ res.setHeader('X-PD-Mutation-Authority', `${LEGACY_MUTATION_AUTHORITY} (preferred: ${RELEASE_MANAGER_AUTHORITY} unavailable)`);
1566
+ res.setHeader('X-PD-Mutation-Fallback-Reason', `release_manager_unavailable:${reasons}`);
1567
+ await legacyCheckMutation(req, res, ctx);
1568
+ return;
1569
+ }
1570
+ try {
1571
+ const check = await authority.manager.check(authority.installStatus.channel);
1572
+ const comparison = check.shadowComparison;
1573
+ const agrees = comparison.agrees === null ? 'unknown' : String(comparison.agrees);
1574
+ console.log(`[release-manager] governed update check served (channel=${check.channel}, agrees=${agrees}${comparison.note ? `, note: ${comparison.note}` : ''})`);
1575
+ }
1576
+ catch (error) {
1577
+ const mapped = mod.mapReleaseManagerErrorToFallback(error);
1578
+ console.log(`[release-manager] governed update check refused (${mapped.reason}) — explicit fallback to ${LEGACY_MUTATION_AUTHORITY}`);
1579
+ res.setHeader('X-PD-Mutation-Authority', `${LEGACY_MUTATION_AUTHORITY} (preferred: ${RELEASE_MANAGER_AUTHORITY} unavailable: ${mapped.reason})`);
1580
+ res.setHeader('X-PD-Mutation-Fallback-Reason', `release_manager_unavailable:${mapped.reason}`);
1581
+ }
1582
+ try {
1583
+ const { body } = await legacyComputed();
1584
+ sendSuccess(res, body);
1585
+ }
1586
+ catch (err) {
1587
+ sendError(res, 500, 'update_check_error', err instanceof Error ? err.message : 'Unknown error');
1588
+ }
1589
+ }
1590
+ /**
1591
+ * Bring the authority registration in line with current flag + readiness
1592
+ * state, then dispatch happens through the controller as usual. Idempotent;
1593
+ * the dynamic import is attempted once per server run.
1594
+ */
1595
+ async function syncReleaseManagerAuthority(workspaceDir) {
1596
+ if (!releaseManagerFlagEnabled(workspaceDir)) {
1597
+ fallbackToLegacyForAllKinds('release_manager_shadow_disabled');
1598
+ return;
1599
+ }
1600
+ if (releaseManagerModuleState.state === 'unattempted') {
1601
+ try {
1602
+ const module = await import('create-principles-disciple/dist/update/release-manager-authority.js');
1603
+ releaseManagerModuleState = { state: 'loaded', module };
1604
+ }
1605
+ catch (error) {
1606
+ releaseManagerModuleState = { state: 'missing', detail: error instanceof Error ? error.message : String(error) };
1607
+ }
1608
+ }
1609
+ if (releaseManagerModuleState.state === 'missing') {
1610
+ fallbackToLegacyForAllKinds('installer_missing');
1611
+ return;
1612
+ }
1613
+ const mod = releaseManagerModuleState.module;
1614
+ let authority;
1615
+ try {
1616
+ authority = mod.createReleaseManagerAuthority({
1617
+ pdHome: path.join(os.homedir(), '.pd'),
1618
+ metadataBaseUrl: process.env.PD_RELEASE_METADATA_URL,
1619
+ });
1620
+ }
1621
+ catch {
1622
+ fallbackToLegacyForAllKinds('authority_module_unavailable');
1623
+ return;
1624
+ }
1625
+ for (const rmKind of mod.RELEASE_MANAGER_AUTHORITY_KINDS) {
1626
+ const readiness = authority.kinds[rmKind];
1627
+ if (readiness.ready && rmKind === 'check') {
1628
+ updateMutationController.register('check', {
1629
+ name: RELEASE_MANAGER_AUTHORITY,
1630
+ handler: (req, res, ctx) => runReleaseManagerCheckDispatch(mod, req, res, ctx),
1631
+ });
1632
+ updateMutationController.setFallbackReason('check', null);
1633
+ }
1634
+ else {
1635
+ updateMutationController.unregister(rmKind, RELEASE_MANAGER_AUTHORITY);
1636
+ updateMutationController.setFallbackReason(rmKind, `release_manager_unavailable:${readiness.reasons.join(',')}`);
1637
+ }
1638
+ }
1639
+ }
1476
1640
  const UPDATE_MUTATION_KINDS = new Map([
1477
1641
  ['/check', 'check'],
1478
1642
  ['/apply', 'apply'],
@@ -1485,5 +1649,9 @@ export async function handleUpdateRoute(req, res, workspaceDir, subPath) {
1485
1649
  sendNotFound(res, `Update route not found: ${subPath}`);
1486
1650
  return;
1487
1651
  }
1652
+ // PRI-672: align the authority registration with the current flag +
1653
+ // readiness state before the controller resolves the authority. Pure
1654
+ // routing/decision work — no runtime mutation happens here.
1655
+ await syncReleaseManagerAuthority(workspaceDir);
1488
1656
  await updateMutationController.dispatch(req, res, { workspaceDir }, kind);
1489
1657
  }
@@ -57,6 +57,13 @@ export interface MutationGovernanceInfo {
57
57
  readonly preferred: string;
58
58
  readonly fallback: boolean;
59
59
  readonly available: readonly string[];
60
+ /**
61
+ * PRI-672: why the fallback authority is serving (set by the wiring when the
62
+ * preferred authority is unregistered/unavailable). Omitted when the wiring
63
+ * has no reason to report — e.g. before any dispatch, or while the preferred
64
+ * authority serves.
65
+ */
66
+ readonly fallbackReason?: string;
60
67
  }
61
68
  export interface ResolvedAuthority {
62
69
  readonly authority: MutationAuthority;
@@ -64,6 +71,17 @@ export interface ResolvedAuthority {
64
71
  }
65
72
  export declare class MutationController {
66
73
  private readonly authorities;
74
+ /** PRI-672: per-kind reason the fallback is serving (machine-readable, rc-9). */
75
+ private readonly fallbackReasons;
76
+ /**
77
+ * Record why the fallback authority is currently serving `kind` (e.g.
78
+ * `release_manager_shadow_disabled` or `release_manager_unavailable:…`).
79
+ * Emitted as the `X-PD-Mutation-Fallback-Reason` header whenever a dispatch
80
+ * actually resolves to the fallback, and surfaced by describeGovernance().
81
+ * Pass null to clear.
82
+ */
83
+ setFallbackReason(kind: MutationKind, reason: string | null): void;
84
+ getFallbackReason(kind: MutationKind): string | undefined;
67
85
  register(kind: MutationKind, authority: MutationAuthority): void;
68
86
  unregister(kind: MutationKind, name: string): boolean;
69
87
  hasAuthority(kind: MutationKind, name: string): boolean;
@@ -13,6 +13,26 @@ export const PREFERRED_MUTATION_AUTHORITY = RELEASE_MANAGER_AUTHORITY;
13
13
  export const MUTATION_KINDS = ['check', 'apply', 'apply-full', 'rollback'];
14
14
  export class MutationController {
15
15
  authorities = new Map();
16
+ /** PRI-672: per-kind reason the fallback is serving (machine-readable, rc-9). */
17
+ fallbackReasons = new Map();
18
+ /**
19
+ * Record why the fallback authority is currently serving `kind` (e.g.
20
+ * `release_manager_shadow_disabled` or `release_manager_unavailable:…`).
21
+ * Emitted as the `X-PD-Mutation-Fallback-Reason` header whenever a dispatch
22
+ * actually resolves to the fallback, and surfaced by describeGovernance().
23
+ * Pass null to clear.
24
+ */
25
+ setFallbackReason(kind, reason) {
26
+ if (reason === null) {
27
+ this.fallbackReasons.delete(kind);
28
+ }
29
+ else {
30
+ this.fallbackReasons.set(kind, reason);
31
+ }
32
+ }
33
+ getFallbackReason(kind) {
34
+ return this.fallbackReasons.get(kind);
35
+ }
16
36
  register(kind, authority) {
17
37
  let table = this.authorities.get(kind);
18
38
  if (table === undefined) {
@@ -61,6 +81,10 @@ export class MutationController {
61
81
  ? `${authority.name} (preferred: ${PREFERRED_MUTATION_AUTHORITY} not yet available)`
62
82
  : authority.name;
63
83
  res.setHeader('X-PD-Mutation-Authority', headerValue);
84
+ const fallbackReason = fallback ? this.fallbackReasons.get(kind) : undefined;
85
+ if (fallbackReason !== undefined) {
86
+ res.setHeader('X-PD-Mutation-Fallback-Reason', fallbackReason);
87
+ }
64
88
  await authority.handler(req, res, ctx);
65
89
  }
66
90
  /** Governance snapshot for observability and migration tests. */
@@ -77,6 +101,11 @@ export class MutationController {
77
101
  const { authority, fallback } = this.resolveAuthority(kind);
78
102
  info = { active: authority.name, preferred: PREFERRED_MUTATION_AUTHORITY, fallback, available };
79
103
  }
104
+ if (info.fallback) {
105
+ const fallbackReason = this.fallbackReasons.get(kind);
106
+ if (fallbackReason !== undefined)
107
+ info = { ...info, fallbackReason };
108
+ }
80
109
  snapshot[kind] = info;
81
110
  }
82
111
  return snapshot;
@@ -7,6 +7,7 @@ export interface UpdateLayout {
7
7
  hostRuntimeDir: string;
8
8
  pdCliDir: string;
9
9
  installLayoutDir: string;
10
+ releaseManagerDir: string;
10
11
  hosts: InstallHost[];
11
12
  }
12
13
  export declare function resolveUpdateLayout(): UpdateLayout | undefined;
@@ -45,6 +45,7 @@ export function resolveUpdateLayout() {
45
45
  hostRuntimeDir: paths.hostRuntimeDir,
46
46
  pdCliDir: paths.pdCliDir,
47
47
  installLayoutDir: paths.installLayoutDir,
48
+ releaseManagerDir: paths.releaseManagerDir,
48
49
  hosts: resolution.manifest?.hosts ?? [],
49
50
  };
50
51
  }
@@ -55,6 +56,7 @@ export function resolveUpdateLayout() {
55
56
  hostRuntimeDir: path.join(legacyPluginDir, 'host-runtime'),
56
57
  pdCliDir: path.join(legacyPluginDir, 'pd-cli'),
57
58
  installLayoutDir: path.join(legacyPluginDir, 'install-layout'),
59
+ releaseManagerDir: path.join(legacyPluginDir, 'release-manager'),
58
60
  hosts: ['openclaw'],
59
61
  };
60
62
  }
@@ -23,6 +23,7 @@
23
23
  "@principles/core": "file:../core",
24
24
  "@principles/host-runtime": "file:../host-runtime",
25
25
  "@principles/install-layout": "file:../install-layout",
26
+ "create-principles-disciple": "file:../release-manager",
26
27
  "principles-disciple": "file:../plugin",
27
28
  "@radix-ui/react-alert-dialog": "^1.1.15",
28
29
  "@radix-ui/react-dialog": "^1.1.15",
@@ -3722,6 +3722,16 @@ describe('SEC-BASE-4: log secret redaction & SQL injection guards', () => {
3722
3722
  describe('SEC-BASE-5: network & config isolation guards', () => {
3723
3723
  const REPO_ROOT = pathSync.resolve(__dirname, '../../../../..');
3724
3724
  it('core does not import node:http / node:https / undici / fetch for business', () => {
3725
+ // PRI-683: pi-ai-http-transport.ts is the registered exception
3726
+ // (io-seam-registry.json `pi-ai-http-transport` seam). It owns the LLM
3727
+ // transport's undici Agent config; requests still originate from pi-ai.
3728
+ const registryPath = pathSync.join(REPO_ROOT, 'packages', 'principles-core', 'io-seam-registry.json');
3729
+ const registry = JSON.parse(fsSync.readFileSync(registryPath, 'utf8'));
3730
+ const registeredFiles = new Set();
3731
+ for (const seam of registry.seams) {
3732
+ for (const file of seam.files)
3733
+ registeredFiles.add(file);
3734
+ }
3725
3735
  const coreDir = pathSync.join(REPO_ROOT, 'packages', 'principles-core', 'src');
3726
3736
  const files = fsSync.readdirSync(coreDir, { recursive: true, encoding: 'utf8' })
3727
3737
  .filter((f) => typeof f === 'string' && f.endsWith('.ts') && !f.includes('__tests__'));
@@ -3729,14 +3739,19 @@ describe('SEC-BASE-5: network & config isolation guards', () => {
3729
3739
  for (const f of files) {
3730
3740
  const content = fsSync.readFileSync(pathSync.join(coreDir, f), 'utf8');
3731
3741
  const lines = content.split('\n');
3742
+ const isRegisteredSeam = registeredFiles.has(f.replace(/\\/g, '/'));
3732
3743
  lines.forEach((line, idx) => {
3733
3744
  if (/^import\s+type/.test(line.trim()))
3734
3745
  return;
3735
3746
  if (/from\s+['"]node:http['"]/.test(line) || /from\s+['"]node:https['"]/.test(line)
3736
3747
  || /from\s+['"]undici['"]/.test(line) || /from\s+['"]node-fetch['"]/.test(line)) {
3748
+ if (isRegisteredSeam)
3749
+ return;
3737
3750
  violations.push(`${f}:${idx + 1}: ${line.trim()}`);
3738
3751
  }
3739
3752
  if (!/^\s*(\/\/|\/\*|\*)/.test(line) && /\bfetch\s*\(/.test(line) && !/import/.test(line)) {
3753
+ if (isRegisteredSeam)
3754
+ return;
3740
3755
  violations.push(`${f}:${idx + 1}: ${line.trim()}`);
3741
3756
  }
3742
3757
  });