create-principles-disciple 1.133.13 → 1.134.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.
- package/console/dist/server/routes/update.js +38 -7
- package/console/dist/server/update/legacy-mutation-journal.d.ts +118 -0
- package/console/dist/server/update/legacy-mutation-journal.js +220 -0
- package/console/dist/web/assets/app.js +81 -11
- package/console/package.json +2 -2
- package/core/dist/runtime-v2/__tests__/recovery-sweep-service.test.js +130 -0
- package/core/dist/runtime-v2/__tests__/recovery-sweep-service.test.js.map +1 -1
- package/core/dist/runtime-v2/recovery-sweep-service.d.ts +9 -0
- package/core/dist/runtime-v2/recovery-sweep-service.d.ts.map +1 -1
- package/core/dist/runtime-v2/recovery-sweep-service.js +7 -2
- package/core/dist/runtime-v2/recovery-sweep-service.js.map +1 -1
- package/core/package.json +1 -1
- package/dist/installer.d.ts +48 -0
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +115 -13
- package/dist/installer.js.map +1 -1
- package/dist/uninstaller.d.ts.map +1 -1
- package/dist/uninstaller.js +7 -3
- package/dist/uninstaller.js.map +1 -1
- package/dist/update/install-layout.d.ts +39 -2
- package/dist/update/install-layout.d.ts.map +1 -1
- package/dist/update/install-layout.js +69 -3
- package/dist/update/install-layout.js.map +1 -1
- package/dist/update/release-manager-authority.d.ts +8 -0
- package/dist/update/release-manager-authority.d.ts.map +1 -1
- package/dist/update/release-manager-authority.js +26 -4
- package/dist/update/release-manager-authority.js.map +1 -1
- package/dist/update/release-metadata-source.d.ts +85 -0
- package/dist/update/release-metadata-source.d.ts.map +1 -0
- package/dist/update/release-metadata-source.js +102 -0
- package/dist/update/release-metadata-source.js.map +1 -0
- package/package.json +2 -2
- package/pd-cli/dist/commands/runtime-recovery-failed-tasks.d.ts.map +1 -1
- package/pd-cli/dist/commands/runtime-recovery-failed-tasks.js +82 -6
- package/pd-cli/dist/commands/runtime-recovery-failed-tasks.js.map +1 -1
- package/pd-cli/dist/index.js +6 -3
- package/pd-cli/dist/index.js.map +1 -1
- package/pd-cli/package.json +1 -1
- package/plugin/dist/bundle.js +3 -3
- package/plugin/dist/governance-audit.js +139 -139
- package/plugin/dist/rulehost-evidence.js +144 -144
- package/release-manager/dist/installer.d.ts +48 -0
- package/release-manager/dist/installer.d.ts.map +1 -1
- package/release-manager/dist/installer.js +115 -13
- package/release-manager/dist/installer.js.map +1 -1
- package/release-manager/dist/uninstaller.d.ts.map +1 -1
- package/release-manager/dist/uninstaller.js +7 -3
- package/release-manager/dist/uninstaller.js.map +1 -1
- package/release-manager/dist/update/install-layout.d.ts +39 -2
- package/release-manager/dist/update/install-layout.d.ts.map +1 -1
- package/release-manager/dist/update/install-layout.js +69 -3
- package/release-manager/dist/update/install-layout.js.map +1 -1
- package/release-manager/dist/update/release-manager-authority.d.ts +8 -0
- package/release-manager/dist/update/release-manager-authority.d.ts.map +1 -1
- package/release-manager/dist/update/release-manager-authority.js +26 -4
- package/release-manager/dist/update/release-manager-authority.js.map +1 -1
- package/release-manager/dist/update/release-metadata-source.d.ts +85 -0
- package/release-manager/dist/update/release-metadata-source.d.ts.map +1 -0
- package/release-manager/dist/update/release-metadata-source.js +102 -0
- package/release-manager/dist/update/release-metadata-source.js.map +1 -0
- package/release-manager/package.json +2 -2
|
@@ -17,6 +17,54 @@ export declare const CONVERSATION_ACCESS_CONFIG_KEY: 'allowConversationAccess';
|
|
|
17
17
|
export declare function ensureConversationAccess(config: Record<string, unknown>): Record<string, unknown>;
|
|
18
18
|
export declare function resolveConsolePortBase(): number;
|
|
19
19
|
export declare function mergeInstallManifestHosts(current: unknown, host: HostTarget): ('codex' | 'openclaw')[];
|
|
20
|
+
/**
|
|
21
|
+
* PRI-709 P0-2 — active record commit point (ADR-0024 D-2).
|
|
22
|
+
*
|
|
23
|
+
* `~/.pd/active.json` is the deployment identity source: it records WHAT is
|
|
24
|
+
* actually deployed, keyed to the transaction that deployed it. Before PRI-709
|
|
25
|
+
* the installer never wrote it (the only writer was legacy-migration.ts), so
|
|
26
|
+
* every real install and every ReleaseManager apply left active.json absent or
|
|
27
|
+
* stale — the PRI-698 audit finding F-2.
|
|
28
|
+
*
|
|
29
|
+
* Identity is taken from the transaction, never recomputed here: the journal
|
|
30
|
+
* was opened with the payload's own identity (`_release/manifest.json` digest
|
|
31
|
+
* when the self-contained asset ships one), and active.json must agree with
|
|
32
|
+
* the journal of the transaction that produced it. A divergent second
|
|
33
|
+
* computation would break the audit trail.
|
|
34
|
+
*
|
|
35
|
+
* Ordering: journal-first. The caller appends `confirmed` and only then calls
|
|
36
|
+
* this, so a crash between the two is recoverable from the journal (the
|
|
37
|
+
* reverse order would leave an unjournaled active.json).
|
|
38
|
+
*
|
|
39
|
+
* Failure policy — Tier 2: this runs AFTER the backup was discarded, so the
|
|
40
|
+
* install is already committed and must not be failed here. A write failure is
|
|
41
|
+
* reported loud (rc-9) and returned to the caller; it never bricks the
|
|
42
|
+
* installation.
|
|
43
|
+
*/
|
|
44
|
+
export interface ActiveRecordCommitResult {
|
|
45
|
+
readonly written: boolean;
|
|
46
|
+
readonly activeRecordPath: string;
|
|
47
|
+
readonly generation: number;
|
|
48
|
+
readonly previousReleaseId: string | null;
|
|
49
|
+
/** Set when the record could not be written or the previous one was unreadable. */
|
|
50
|
+
readonly reason?: string;
|
|
51
|
+
}
|
|
52
|
+
export declare function commitInstallerActiveRecord(journal: InstallerJournal): ActiveRecordCommitResult;
|
|
53
|
+
/**
|
|
54
|
+
* PRI-709 P0-1 — installer supply path for the release metadata source.
|
|
55
|
+
*
|
|
56
|
+
* The installer is the only component that legitimately knows the metadata
|
|
57
|
+
* repository at install time, so it persists `PD_RELEASE_METADATA_URL` into
|
|
58
|
+
* `~/.pd/install.json` (the durable `install_config` tier). Without this the
|
|
59
|
+
* variable had to be exported in every shell that wanted a governed update
|
|
60
|
+
* check (PRI-698 audit F-4).
|
|
61
|
+
*
|
|
62
|
+
* Absent env is a no-op — an install with no metadata source stays
|
|
63
|
+
* unconfigured rather than persisting a guessed URL. A malformed env value is
|
|
64
|
+
* reported and skipped: it must never be written into install.json, where the
|
|
65
|
+
* strict reader would then fail loud and mark the install corrupt.
|
|
66
|
+
*/
|
|
67
|
+
export declare function persistReleaseMetadataSource(): void;
|
|
20
68
|
/**
|
|
21
69
|
* 验证原生模块:better-sqlite3 随发布资产携带 prebuilt 二进制
|
|
22
70
|
* (prebuilds/*.node),node-gyp-build 在 require 时解析——无需(也没有)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../src/installer.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAmBL,KAAK,eAAe,EACpB,KAAK,kBAAkB,EAExB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAqB,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAsB,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAGnF,OAAO,EAA+B,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../src/installer.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,7 +16,9 @@ import { mergeInstallManifestWorkspaces, parseInstallManifest } from '@principle
|
|
|
16
16
|
import { detectOpenClawMainWorkspaceDivergence } from './utils/workspace-divergence.js';
|
|
17
17
|
import { applySkillLanguageSelection } from './skill-language.js';
|
|
18
18
|
import { parseReleaseAssetIdentity, parseReleaseAssetManifest, ReleaseAssetManifestError, verifyReleaseAssetManifestAsync, verifyReleaseAssetTarget, } from './update/release-asset-manifest.js';
|
|
19
|
-
import {
|
|
19
|
+
import { mergeIntoInstallJson, readInstallJsonRecord, resolvePdHomePaths, } from './update/install-layout.js';
|
|
20
|
+
import { RELEASE_METADATA_URL_ENV, normalizeReleaseMetadataUrl } from './update/release-metadata-source.js';
|
|
21
|
+
import { appendJournalTransition, readActiveRecord, writeActiveRecord, } from './update/transaction-journal.js';
|
|
20
22
|
/** PRI-343: Keep in sync with @principles/core CONVERSATION_ACCESS_CONFIG_KEY */
|
|
21
23
|
export const CONVERSATION_ACCESS_CONFIG_KEY = 'allowConversationAccess';
|
|
22
24
|
function isRecord(value) {
|
|
@@ -155,7 +157,90 @@ function resolveInstallManifestWorkspaces(workspaceDir) {
|
|
|
155
157
|
}
|
|
156
158
|
function writeInstallManifest(hosts, workspaces) {
|
|
157
159
|
mkdirSync(getPdDir(), { recursive: true });
|
|
158
|
-
|
|
160
|
+
// PRI-709 P0-1: merge into the existing record. This file has more than one
|
|
161
|
+
// writer (the update side owns `channel` / `autoCheck` / `releaseMetadataUrl`);
|
|
162
|
+
// a wholesale replace silently deleted those fields.
|
|
163
|
+
const existing = readInstallJsonRecord(getInstallManifestPath());
|
|
164
|
+
const payload = {
|
|
165
|
+
...(existing ?? {}),
|
|
166
|
+
layoutVersion: 1,
|
|
167
|
+
mode: 'canonical',
|
|
168
|
+
hosts,
|
|
169
|
+
workspaces,
|
|
170
|
+
};
|
|
171
|
+
writeFileSync(getInstallManifestPath(), JSON.stringify(payload, null, 2) + '\n', 'utf8');
|
|
172
|
+
}
|
|
173
|
+
export function commitInstallerActiveRecord(journal) {
|
|
174
|
+
const paths = resolvePdHomePaths(getPdDir());
|
|
175
|
+
let previous = null;
|
|
176
|
+
let previousWarning = null;
|
|
177
|
+
try {
|
|
178
|
+
previous = readActiveRecord(paths.activeRecordPath);
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
// A corrupt previous record must not block committing the new identity —
|
|
182
|
+
// overwriting it with a valid record is strictly an improvement.
|
|
183
|
+
previousWarning = error instanceof Error ? error.message : String(error);
|
|
184
|
+
logger.warn(`active.json was unreadable and is being replaced (${paths.activeRecordPath}): ${previousWarning}`);
|
|
185
|
+
}
|
|
186
|
+
// Generation continuity: never move backwards. A standalone install already
|
|
187
|
+
// carries generation 1, but re-installing over an existing deployment must
|
|
188
|
+
// advance past it — otherwise the deployment identity source would regress.
|
|
189
|
+
const generation = Math.max(journal.generation, previous === null ? 1 : previous.generation + 1);
|
|
190
|
+
try {
|
|
191
|
+
writeActiveRecord(paths.activeRecordPath, {
|
|
192
|
+
generation,
|
|
193
|
+
releaseId: journal.releaseId,
|
|
194
|
+
releaseMetadataDigest: journal.releaseMetadataDigest,
|
|
195
|
+
previousReleaseId: previous?.releaseId ?? null,
|
|
196
|
+
transactionId: journal.transactionId,
|
|
197
|
+
productVersion: journal.productVersion,
|
|
198
|
+
});
|
|
199
|
+
return {
|
|
200
|
+
written: true,
|
|
201
|
+
activeRecordPath: paths.activeRecordPath,
|
|
202
|
+
generation,
|
|
203
|
+
previousReleaseId: previous?.releaseId ?? null,
|
|
204
|
+
...(previousWarning !== null ? { reason: `previous_record_unreadable: ${previousWarning}` } : {}),
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
209
|
+
logger.error(`active.json could not be written after a committed install (${paths.activeRecordPath}): ${reason}. `
|
|
210
|
+
+ `Deployment identity is out of sync with the transaction ${journal.transactionId}; re-run the installer to repair it.`);
|
|
211
|
+
return {
|
|
212
|
+
written: false,
|
|
213
|
+
activeRecordPath: paths.activeRecordPath,
|
|
214
|
+
generation,
|
|
215
|
+
previousReleaseId: previous?.releaseId ?? null,
|
|
216
|
+
reason,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* PRI-709 P0-1 — installer supply path for the release metadata source.
|
|
222
|
+
*
|
|
223
|
+
* The installer is the only component that legitimately knows the metadata
|
|
224
|
+
* repository at install time, so it persists `PD_RELEASE_METADATA_URL` into
|
|
225
|
+
* `~/.pd/install.json` (the durable `install_config` tier). Without this the
|
|
226
|
+
* variable had to be exported in every shell that wanted a governed update
|
|
227
|
+
* check (PRI-698 audit F-4).
|
|
228
|
+
*
|
|
229
|
+
* Absent env is a no-op — an install with no metadata source stays
|
|
230
|
+
* unconfigured rather than persisting a guessed URL. A malformed env value is
|
|
231
|
+
* reported and skipped: it must never be written into install.json, where the
|
|
232
|
+
* strict reader would then fail loud and mark the install corrupt.
|
|
233
|
+
*/
|
|
234
|
+
export function persistReleaseMetadataSource() {
|
|
235
|
+
const raw = process.env[RELEASE_METADATA_URL_ENV];
|
|
236
|
+
if (raw === undefined || raw.trim().length === 0)
|
|
237
|
+
return;
|
|
238
|
+
const normalized = normalizeReleaseMetadataUrl(raw);
|
|
239
|
+
if (normalized === null) {
|
|
240
|
+
logger.warn(`${RELEASE_METADATA_URL_ENV} is not a valid http(s) URL and was not persisted to install.json: ${JSON.stringify(raw)}. Release metadata source stays unconfigured.`);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
mergeIntoInstallJson(getInstallManifestPath(), { releaseMetadataUrl: normalized });
|
|
159
244
|
}
|
|
160
245
|
function installBundledLayoutPackage(pluginDir) {
|
|
161
246
|
const source = path.join(pluginDir, 'install-layout');
|
|
@@ -1888,6 +1973,18 @@ async function runHostInstallers(host, ctx) {
|
|
|
1888
1973
|
function sha256File(filePath) {
|
|
1889
1974
|
return createHash('sha256').update(readFileSync(filePath)).digest('hex');
|
|
1890
1975
|
}
|
|
1976
|
+
function readPackageVersion(pkgPath) {
|
|
1977
|
+
if (!existsSync(pkgPath))
|
|
1978
|
+
return null;
|
|
1979
|
+
try {
|
|
1980
|
+
const parsed = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
1981
|
+
return typeof parsed.version === 'string' && parsed.version.length > 0 ? parsed.version : null;
|
|
1982
|
+
}
|
|
1983
|
+
catch {
|
|
1984
|
+
// Identity falls back; journaling must not brick install.
|
|
1985
|
+
return null;
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1891
1988
|
/**
|
|
1892
1989
|
* Identity of the payload being installed. Prefers the self-contained asset
|
|
1893
1990
|
* manifest (covers the whole payload); falls back to the bundled pd-cli
|
|
@@ -1896,20 +1993,19 @@ function sha256File(filePath) {
|
|
|
1896
1993
|
* legacy-migration.ts). The last-resort fallback hashes the literal reason
|
|
1897
1994
|
* string only to satisfy the journal's 64-hex format requirement; it is not
|
|
1898
1995
|
* part of any release-metadata identity chain.
|
|
1996
|
+
*
|
|
1997
|
+
* PRI-709 P0-2 (PRI-698 audit F-1): `productVersion` is the PRODUCT version —
|
|
1998
|
+
* the plugin package manifest. It previously read `pd-cli/package.json`, but
|
|
1999
|
+
* the two packages version independently (on the Owner machine: plugin
|
|
2000
|
+
* 1.230.2 vs pd-cli 1.147.5), so every confirmed journal recorded a version
|
|
2001
|
+
* that no runtime state could ever match. That is why active.json could not
|
|
2002
|
+
* serve as the deployment identity source.
|
|
1899
2003
|
*/
|
|
1900
2004
|
function resolveInstallerPayloadIdentity(pluginDir) {
|
|
1901
|
-
|
|
2005
|
+
const productVersion = readPackageVersion(path.join(pluginDir, 'package.json'))
|
|
2006
|
+
?? readPackageVersion(path.join(pluginDir, 'pd-cli', 'package.json'))
|
|
2007
|
+
?? 'unknown';
|
|
1902
2008
|
const pdCliPkgPath = path.join(pluginDir, 'pd-cli', 'package.json');
|
|
1903
|
-
if (existsSync(pdCliPkgPath)) {
|
|
1904
|
-
try {
|
|
1905
|
-
const parsed = JSON.parse(readFileSync(pdCliPkgPath, 'utf8'));
|
|
1906
|
-
if (typeof parsed.version === 'string' && parsed.version.length > 0)
|
|
1907
|
-
productVersion = parsed.version;
|
|
1908
|
-
}
|
|
1909
|
-
catch {
|
|
1910
|
-
// Identity falls back to 'unknown'; journaling must not brick install.
|
|
1911
|
-
}
|
|
1912
|
-
}
|
|
1913
2009
|
const assetManifestPath = path.join(pluginDir, '_release', 'manifest.json');
|
|
1914
2010
|
let releaseMetadataDigest;
|
|
1915
2011
|
let releaseMetadataDigestSource;
|
|
@@ -2405,6 +2501,9 @@ transaction) {
|
|
|
2405
2501
|
throw new Error(`Host installation failed: ${hostFailures.join(' | ')}`);
|
|
2406
2502
|
}
|
|
2407
2503
|
writeInstallManifest(installManifestHosts, resolveInstallManifestWorkspaces(options.workspaceDir));
|
|
2504
|
+
// PRI-709 P0-1: persist the metadata source after the manifest write, so
|
|
2505
|
+
// the durable tier cannot be clobbered by the same install.
|
|
2506
|
+
persistReleaseMetadataSource();
|
|
2408
2507
|
// ADR-0024 D-2: host installers completed and the install manifest is
|
|
2409
2508
|
// written — the new installation is fully activated (backups not yet
|
|
2410
2509
|
// discarded, so a crash here still recovers via the backup).
|
|
@@ -2412,6 +2511,9 @@ transaction) {
|
|
|
2412
2511
|
cleanupBackup(backupDir, runtimeBackupDir);
|
|
2413
2512
|
// ADR-0024 D-2: backup cleanup is the commit point of the transaction.
|
|
2414
2513
|
journalInstallerTransitionDegrading(journal, journal.lastState, 'confirmed', 'backup cleaned up; install complete');
|
|
2514
|
+
// PRI-709 P0-2: active.json is the deployment identity source, written
|
|
2515
|
+
// journal-first — after `confirmed`, never before it.
|
|
2516
|
+
commitInstallerActiveRecord(journal);
|
|
2415
2517
|
if (spinner) {
|
|
2416
2518
|
spinner.succeed('Install complete!');
|
|
2417
2519
|
}
|