create-principles-disciple 1.132.0 → 1.132.1
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 +183 -35
- package/host-runtime/dist/evaluator-runtime-context.d.ts +63 -0
- package/host-runtime/dist/evaluator-runtime-context.js +61 -0
- package/host-runtime/dist/index.d.ts +1 -0
- package/host-runtime/dist/index.js +2 -0
- package/host-runtime/package.json +1 -1
- package/package.json +2 -2
- package/pd-cli/dist/commands/health.d.ts.map +1 -1
- package/pd-cli/dist/commands/health.js +39 -0
- package/pd-cli/dist/commands/health.js.map +1 -1
- package/pd-cli/dist/commands/runtime-internalization-run-once.d.ts.map +1 -1
- package/pd-cli/dist/commands/runtime-internalization-run-once.js +41 -1
- package/pd-cli/dist/commands/runtime-internalization-run-once.js.map +1 -1
- package/pd-cli/dist/services/rulehost-pipeline-runner.d.ts.map +1 -1
- package/pd-cli/dist/services/rulehost-pipeline-runner.js +22 -1
- package/pd-cli/dist/services/rulehost-pipeline-runner.js.map +1 -1
- package/pd-cli/package.json +1 -1
- package/plugin/dist/bundle.js +140 -140
|
@@ -713,8 +713,148 @@ function depsMeaningfullyChanged(oldDeps, newDeps) {
|
|
|
713
713
|
return aKeys.some((k, i) => bKeys[i] !== k || a[k] !== b[k]);
|
|
714
714
|
}
|
|
715
715
|
/**
|
|
716
|
-
*
|
|
717
|
-
*
|
|
716
|
+
* Move the current occupant of a dependency slot aside (same-directory
|
|
717
|
+
* rename: same volume, atomic, reversible). The quarantine name starts with
|
|
718
|
+
* a dot and is not a valid package name, so npm module resolution ignores it.
|
|
719
|
+
*/
|
|
720
|
+
function quarantineSlot(slot) {
|
|
721
|
+
try {
|
|
722
|
+
const quarantinePath = path.join(path.dirname(slot), `.${path.basename(slot)}.update-quarantine-${Date.now()}`);
|
|
723
|
+
fs.renameSync(slot, quarantinePath);
|
|
724
|
+
return { slot, quarantinePath };
|
|
725
|
+
}
|
|
726
|
+
catch {
|
|
727
|
+
return undefined;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* Restore quarantined slots to their original locations (update failure
|
|
732
|
+
* path). The slot at that point holds the link reconciliation created —
|
|
733
|
+
* unlink removes the link itself, never its target. Best-effort, never
|
|
734
|
+
* throws; failures are logged (rc-9: observable degradation).
|
|
735
|
+
*/
|
|
736
|
+
function restoreQuarantined(quarantined) {
|
|
737
|
+
for (const entry of [...quarantined].reverse()) {
|
|
738
|
+
try {
|
|
739
|
+
try {
|
|
740
|
+
fs.unlinkSync(entry.slot);
|
|
741
|
+
}
|
|
742
|
+
catch { /* slot may already be gone */ }
|
|
743
|
+
fs.renameSync(entry.quarantinePath, entry.slot);
|
|
744
|
+
}
|
|
745
|
+
catch (error) {
|
|
746
|
+
console.error(`[pd-console:update] failed to restore quarantined dependency entry ${entry.slot}: ${error instanceof Error ? error.message : String(error)}`);
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Discard quarantined slots (update success path). The quarantined entries
|
|
752
|
+
* are stale pre-update copies of internal @principles packages; the new
|
|
753
|
+
* canonical components are installed by the copy steps. Best-effort,
|
|
754
|
+
* failures are logged and non-fatal (rc-9).
|
|
755
|
+
*/
|
|
756
|
+
function cleanupQuarantined(quarantined) {
|
|
757
|
+
for (const entry of quarantined) {
|
|
758
|
+
try {
|
|
759
|
+
fs.rmSync(entry.quarantinePath, { recursive: true, force: true });
|
|
760
|
+
}
|
|
761
|
+
catch (error) {
|
|
762
|
+
console.warn(`[pd-console:update] failed to clean quarantined dependency entry ${entry.quarantinePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* True when the link at linkPath resolves to exactly `target` (string
|
|
768
|
+
* comparison — the target dir may legitimately not exist yet at
|
|
769
|
+
* reconciliation time). Windows paths compare case-insensitively.
|
|
770
|
+
*/
|
|
771
|
+
function linkPointsAt(linkPath, target) {
|
|
772
|
+
const resolved = path.resolve(path.dirname(linkPath), fs.readlinkSync(linkPath));
|
|
773
|
+
const expected = path.resolve(target);
|
|
774
|
+
return process.platform === 'win32'
|
|
775
|
+
? resolved.toLowerCase() === expected.toLowerCase()
|
|
776
|
+
: resolved === expected;
|
|
777
|
+
}
|
|
778
|
+
function createResolutionLink(linkPath, target) {
|
|
779
|
+
try {
|
|
780
|
+
fs.mkdirSync(path.dirname(linkPath), { recursive: true });
|
|
781
|
+
if (process.platform === 'win32') {
|
|
782
|
+
fs.symlinkSync(target, linkPath, 'junction');
|
|
783
|
+
}
|
|
784
|
+
else {
|
|
785
|
+
fs.symlinkSync(path.relative(path.dirname(linkPath), target), linkPath, 'dir');
|
|
786
|
+
}
|
|
787
|
+
return undefined;
|
|
788
|
+
}
|
|
789
|
+
catch (error) {
|
|
790
|
+
return `Failed to create runtime resolution link at ${linkPath}: ${error instanceof Error ? error.message : String(error)}`;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Reconcile ONE deployed dependency slot against its canonical target
|
|
795
|
+
* (PRI-665, 2026-09-03 incident). The previous "existsSync → skip" logic
|
|
796
|
+
* silently kept stale PHYSICAL copies of internal @principles packages that
|
|
797
|
+
* legacy installs had left in these slots, so the updated dist resolved the
|
|
798
|
+
* old components and crashed at startup. Semantics:
|
|
799
|
+
*
|
|
800
|
+
* - missing slot → create the link (fresh installs);
|
|
801
|
+
* - link pointing at target → keep (npm- or installer-created);
|
|
802
|
+
* - wrong-target link → quarantine + replace;
|
|
803
|
+
* - physical dir / plain file → quarantine + replace (the incident shape).
|
|
804
|
+
*
|
|
805
|
+
* Returns an error message on failure (the slot is rolled back first), or
|
|
806
|
+
* undefined; a successful quarantine is recorded in `quarantined` for the
|
|
807
|
+
* caller to restore on failure / discard on success.
|
|
808
|
+
*/
|
|
809
|
+
function reconcileResolutionLink(linkPath, target, quarantined) {
|
|
810
|
+
let stat;
|
|
811
|
+
try {
|
|
812
|
+
stat = fs.lstatSync(linkPath);
|
|
813
|
+
}
|
|
814
|
+
catch {
|
|
815
|
+
stat = undefined; // ENOENT — create below
|
|
816
|
+
}
|
|
817
|
+
if (stat === undefined) {
|
|
818
|
+
return createResolutionLink(linkPath, target);
|
|
819
|
+
}
|
|
820
|
+
if (stat.isSymbolicLink()) {
|
|
821
|
+
try {
|
|
822
|
+
if (linkPointsAt(linkPath, target))
|
|
823
|
+
return undefined; // correct link — keep
|
|
824
|
+
}
|
|
825
|
+
catch {
|
|
826
|
+
// Unreadable link target — fall through to replace.
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
const entry = quarantineSlot(linkPath);
|
|
830
|
+
if (entry === undefined) {
|
|
831
|
+
return `Failed to quarantine the existing dependency entry at ${linkPath} (required to install the canonical resolution link). Resolve any file locks and retry the update.`;
|
|
832
|
+
}
|
|
833
|
+
const error = createResolutionLink(linkPath, target);
|
|
834
|
+
if (error) {
|
|
835
|
+
// Roll this slot back before failing — the install stays untouched
|
|
836
|
+
// (the PRI-561 fail-closed ordering contract).
|
|
837
|
+
try {
|
|
838
|
+
fs.unlinkSync(linkPath);
|
|
839
|
+
}
|
|
840
|
+
catch { /* nothing we created */ }
|
|
841
|
+
try {
|
|
842
|
+
fs.renameSync(entry.quarantinePath, entry.slot);
|
|
843
|
+
}
|
|
844
|
+
catch {
|
|
845
|
+
// The in-slot rename failed (e.g. a transient lock). Hand the entry to
|
|
846
|
+
// the outer rollback so it retries the restore — restoreQuarantined
|
|
847
|
+
// tolerates a missing slot when unlinking before renaming back.
|
|
848
|
+
quarantined.push(entry);
|
|
849
|
+
}
|
|
850
|
+
return error;
|
|
851
|
+
}
|
|
852
|
+
quarantined.push(entry);
|
|
853
|
+
return undefined;
|
|
854
|
+
}
|
|
855
|
+
/**
|
|
856
|
+
* Create or RECONCILE the node_modules resolution links for the installed
|
|
857
|
+
* components.
|
|
718
858
|
*
|
|
719
859
|
* Mirrors installer.ts syncPdCli: junction on Windows (no elevation needed),
|
|
720
860
|
* relative symlink elsewhere. Fresh installs get these links via npm install
|
|
@@ -738,8 +878,11 @@ function depsMeaningfullyChanged(oldDeps, newDeps) {
|
|
|
738
878
|
* host-runtime/node_modules/@principles/install-layout missing and
|
|
739
879
|
* every pd-cli runtime command failing with ERR_MODULE_NOT_FOUND.
|
|
740
880
|
*
|
|
741
|
-
* Returns
|
|
742
|
-
* silent — a missing link means the
|
|
881
|
+
* Returns { error } on failure with every quarantine rolled back (rc-9:
|
|
882
|
+
* observable, never silent — a missing or unreconciled link means the
|
|
883
|
+
* updated console cannot start), or { quarantined } listing the dependency
|
|
884
|
+
* entries replaced during reconciliation. The caller restores the
|
|
885
|
+
* quarantined entries if a LATER step fails, and discards them on success.
|
|
743
886
|
*/
|
|
744
887
|
function ensureRuntimeResolutionLinks(layout, tempDir) {
|
|
745
888
|
const links = [
|
|
@@ -784,47 +927,35 @@ function ensureRuntimeResolutionLinks(layout, tempDir) {
|
|
|
784
927
|
}
|
|
785
928
|
};
|
|
786
929
|
const fileDepSpecs = collectFileDepLinkSpecs(stagedComponents, readStagedDependencies);
|
|
787
|
-
const
|
|
788
|
-
// Idempotent: never overwrite an existing link or directory (fresh
|
|
789
|
-
// installs have npm-created real dirs in these slots).
|
|
790
|
-
if (fs.existsSync(linkPath))
|
|
791
|
-
return undefined;
|
|
792
|
-
try {
|
|
793
|
-
fs.mkdirSync(path.dirname(linkPath), { recursive: true });
|
|
794
|
-
if (process.platform === 'win32') {
|
|
795
|
-
fs.symlinkSync(target, linkPath, 'junction');
|
|
796
|
-
}
|
|
797
|
-
else {
|
|
798
|
-
fs.symlinkSync(path.relative(path.dirname(linkPath), target), linkPath, 'dir');
|
|
799
|
-
}
|
|
800
|
-
return undefined;
|
|
801
|
-
}
|
|
802
|
-
catch (error) {
|
|
803
|
-
return `Failed to create runtime resolution link at ${linkPath}: ${error instanceof Error ? error.message : String(error)}`;
|
|
804
|
-
}
|
|
805
|
-
};
|
|
930
|
+
const quarantined = [];
|
|
806
931
|
// Pass 1 — explicit known-critical links, fail-closed BEFORE any byte is
|
|
807
|
-
// swapped (a link-
|
|
808
|
-
// untouched: the PRI-561 ordering contract).
|
|
932
|
+
// swapped (a link-reconciliation failure aborts with the installed packages
|
|
933
|
+
// untouched: the PRI-561 ordering contract). Existing entries are
|
|
934
|
+
// RECONCILED, not skipped: a correct link is kept, but a stale physical
|
|
935
|
+
// copy or a wrong-target link is quarantined and replaced (PRI-665,
|
|
936
|
+
// 2026-09-03: legacy installs left physical @principles copies in these
|
|
937
|
+
// slots and updated dists crashed resolving them).
|
|
809
938
|
for (const { linkPath, target } of links) {
|
|
810
939
|
if (!fs.existsSync(target))
|
|
811
940
|
continue;
|
|
812
|
-
const error =
|
|
813
|
-
if (error)
|
|
814
|
-
|
|
941
|
+
const error = reconcileResolutionLink(linkPath, target, quarantined);
|
|
942
|
+
if (error) {
|
|
943
|
+
restoreQuarantined(quarantined);
|
|
944
|
+
return { error, quarantined: [] };
|
|
945
|
+
}
|
|
815
946
|
}
|
|
816
947
|
// Pass 2 — data-driven derived links. Their deployed target dir may be
|
|
817
948
|
// created by the copy steps that follow (a brand-new component's dir does
|
|
818
949
|
// not exist yet); each staged target's existence was already proven by the
|
|
819
950
|
// extraction, and the copies below run unconditionally.
|
|
820
951
|
for (const spec of fileDepSpecs) {
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
952
|
+
const error = reconcileResolutionLink(spec.linkPath, spec.target, quarantined);
|
|
953
|
+
if (error) {
|
|
954
|
+
restoreQuarantined(quarantined);
|
|
955
|
+
return { error, quarantined: [] };
|
|
956
|
+
}
|
|
826
957
|
}
|
|
827
|
-
return
|
|
958
|
+
return { quarantined };
|
|
828
959
|
}
|
|
829
960
|
async function doInlineFullUpdate(workspaceDir) {
|
|
830
961
|
const layout = resolveUpdateLayout();
|
|
@@ -861,6 +992,9 @@ async function doInlineFullUpdate(workspaceDir) {
|
|
|
861
992
|
// overwrites it (PR #1332 companion — see reapplySkillLanguage).
|
|
862
993
|
const skillLanguage = detectInstalledSkillLanguage(extDir);
|
|
863
994
|
let tempDir;
|
|
995
|
+
// Dependency entries quarantined during resolution-link reconciliation;
|
|
996
|
+
// restored on failure, discarded on success (PRI-665).
|
|
997
|
+
let reconciledQuarantine = [];
|
|
864
998
|
try {
|
|
865
999
|
// 2. Fetch installer package info from npm
|
|
866
1000
|
const response = await fetchWithRetry(NPM_REGISTRY_INSTALLER, 'Installer registry check');
|
|
@@ -1018,7 +1152,8 @@ async function doInlineFullUpdate(workspaceDir) {
|
|
|
1018
1152
|
if (fs.existsSync(path.join(installLayoutSrc, 'package.json')) && fs.existsSync(path.join(installLayoutSrc, 'dist'))) {
|
|
1019
1153
|
copyDirRecursive(installLayoutSrc, layout.installLayoutDir, SKIP_DIRS);
|
|
1020
1154
|
}
|
|
1021
|
-
const linkError = ensureRuntimeResolutionLinks(layout, tempDir);
|
|
1155
|
+
const { error: linkError, quarantined } = ensureRuntimeResolutionLinks(layout, tempDir);
|
|
1156
|
+
reconciledQuarantine = quarantined;
|
|
1022
1157
|
if (linkError) {
|
|
1023
1158
|
appendUpdateHistory(workspaceDir, {
|
|
1024
1159
|
fromVersion,
|
|
@@ -1078,6 +1213,13 @@ async function doInlineFullUpdate(workspaceDir) {
|
|
|
1078
1213
|
if (tempDir && fs.existsSync(tempDir)) {
|
|
1079
1214
|
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
1080
1215
|
}
|
|
1216
|
+
// 6.5 Discard the quarantined stale dependency copies — the canonical
|
|
1217
|
+
// components are in place now (PRI-665). Both the success return and the
|
|
1218
|
+
// version-drift failure return flow through here with files already
|
|
1219
|
+
// swapped, so restoring the stale copies would re-break resolution.
|
|
1220
|
+
if (reconciledQuarantine.length > 0) {
|
|
1221
|
+
cleanupQuarantined(reconciledQuarantine);
|
|
1222
|
+
}
|
|
1081
1223
|
// 7. Version-advance check (drift guard). The full update installs the
|
|
1082
1224
|
// plugin bundled inside the installer. If the installer is stale (its
|
|
1083
1225
|
// bundled plugin is NOT newer than what is installed), the "update" is a
|
|
@@ -1122,6 +1264,12 @@ async function doInlineFullUpdate(workspaceDir) {
|
|
|
1122
1264
|
};
|
|
1123
1265
|
}
|
|
1124
1266
|
catch (error) {
|
|
1267
|
+
// PRI-665: restore any dependency slots quarantined during link
|
|
1268
|
+
// reconciliation FIRST — a failed update must not leave the install
|
|
1269
|
+
// half-migrated (new dist with the old resolution quarantined away).
|
|
1270
|
+
if (reconciledQuarantine.length > 0) {
|
|
1271
|
+
restoreQuarantined(reconciledQuarantine);
|
|
1272
|
+
}
|
|
1125
1273
|
// Clean up temp dir on failure
|
|
1126
1274
|
if (tempDir && fs.existsSync(tempDir)) {
|
|
1127
1275
|
try {
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evaluator Runtime Context — PRI-661: ONE builder for the deterministic
|
|
3
|
+
* adversarial-replay context every HOST-NEUTRAL evaluator entry uses.
|
|
4
|
+
*
|
|
5
|
+
* WHY THIS EXISTS: PR #1495 wired the shared consumer cycle (in-host
|
|
6
|
+
* auto-consumer / Codex worker) with production gateDeps + the host-threaded
|
|
7
|
+
* tool registry, but the host-neutral CLI entries kept divergent wiring:
|
|
8
|
+
*
|
|
9
|
+
* - `pd runtime internalization run-once --runner evaluator` assembled
|
|
10
|
+
* EvaluatorRunner with NO gateDeps at all — the deterministic adversarial
|
|
11
|
+
* replay was structurally unreachable (the code-bearing guard fails loud
|
|
12
|
+
* with an assembly defect instead of evaluating anything);
|
|
13
|
+
* - `pd runtime internalization run-rulehost` (rulehost-pipeline-runner)
|
|
14
|
+
* replayed through the bare sandbox gate — no workspace root, no host
|
|
15
|
+
* tool registry — so a rule could pass generation-time replay and fail
|
|
16
|
+
* the production activation gate on the SAME workspace (the exact
|
|
17
|
+
* drift class PRI-634-F closed everywhere else).
|
|
18
|
+
*
|
|
19
|
+
* WHAT THIS MODULE IS NOT: it is not a second tool registry and not a new
|
|
20
|
+
* authority. Host-threaded callers (the consumer cycle) keep passing their
|
|
21
|
+
* live in-memory registry — the running host IS the authority for its own
|
|
22
|
+
* session. Host-neutral callers omit it and the DURABLE workspace provenance
|
|
23
|
+
* (`.pd/host-tool-semantics/<hostKind>.json`, persisted by every host on
|
|
24
|
+
* startup) is resolved through the ONE resolver
|
|
25
|
+
* (`resolveWorkspaceHostToolSemantics`). Unresolvable provenance is a
|
|
26
|
+
* structured refusal — never a silent fallback to the core baseline (an
|
|
27
|
+
* existence check against baseline names is a forged proof; ERR-114).
|
|
28
|
+
*
|
|
29
|
+
* Parity contract (pinned by evaluator-runtime-context.test.ts and the
|
|
30
|
+
* run-once evaluator parity test): the same artifact + workspace + declared
|
|
31
|
+
* host produces the SAME deterministic replay verdict whether it travels the
|
|
32
|
+
* consumer cycle (live registry) or a CLI entry (durable declaration), because
|
|
33
|
+
* hosts persist the same mapping constants they pass in memory.
|
|
34
|
+
*/
|
|
35
|
+
import { type RefinerRuleHostGateDeps, type ToolSemanticRegistry } from '@principles/core/runtime-v2';
|
|
36
|
+
export interface EvaluatorRuntimeContextInput {
|
|
37
|
+
/** Workspace root the replay normalizes paths against (projectDir). */
|
|
38
|
+
readonly workspaceDir: string;
|
|
39
|
+
/**
|
|
40
|
+
* Host-threaded callers pass their live registry here (consumer-cycle
|
|
41
|
+
* ports). Host-neutral CLI callers omit it — the durable workspace
|
|
42
|
+
* declaration is resolved instead.
|
|
43
|
+
*/
|
|
44
|
+
readonly toolSemantics?: ToolSemanticRegistry;
|
|
45
|
+
}
|
|
46
|
+
export type EvaluatorRuntimeContextResolution = {
|
|
47
|
+
readonly ok: true;
|
|
48
|
+
readonly gateDeps: RefinerRuleHostGateDeps;
|
|
49
|
+
} | {
|
|
50
|
+
readonly ok: false;
|
|
51
|
+
readonly reason: string;
|
|
52
|
+
readonly nextAction: string;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Build the evaluator's deterministic replay context.
|
|
56
|
+
*
|
|
57
|
+
* Mirrors the consumer-cycle assembly (PRI-634 A1/A3):
|
|
58
|
+
* gateDeps: createProductionGateDeps({ toolSemantics, projectDir: workspaceDir })
|
|
59
|
+
* — gateDeps belongs to evaluator PRODUCTION semantics, never to host-optional
|
|
60
|
+
* capability, and always travels in the runner OPTIONS (second constructor
|
|
61
|
+
* argument), never the deps argument.
|
|
62
|
+
*/
|
|
63
|
+
export declare function createEvaluatorRuntimeContext(input: EvaluatorRuntimeContextInput): EvaluatorRuntimeContextResolution;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evaluator Runtime Context — PRI-661: ONE builder for the deterministic
|
|
3
|
+
* adversarial-replay context every HOST-NEUTRAL evaluator entry uses.
|
|
4
|
+
*
|
|
5
|
+
* WHY THIS EXISTS: PR #1495 wired the shared consumer cycle (in-host
|
|
6
|
+
* auto-consumer / Codex worker) with production gateDeps + the host-threaded
|
|
7
|
+
* tool registry, but the host-neutral CLI entries kept divergent wiring:
|
|
8
|
+
*
|
|
9
|
+
* - `pd runtime internalization run-once --runner evaluator` assembled
|
|
10
|
+
* EvaluatorRunner with NO gateDeps at all — the deterministic adversarial
|
|
11
|
+
* replay was structurally unreachable (the code-bearing guard fails loud
|
|
12
|
+
* with an assembly defect instead of evaluating anything);
|
|
13
|
+
* - `pd runtime internalization run-rulehost` (rulehost-pipeline-runner)
|
|
14
|
+
* replayed through the bare sandbox gate — no workspace root, no host
|
|
15
|
+
* tool registry — so a rule could pass generation-time replay and fail
|
|
16
|
+
* the production activation gate on the SAME workspace (the exact
|
|
17
|
+
* drift class PRI-634-F closed everywhere else).
|
|
18
|
+
*
|
|
19
|
+
* WHAT THIS MODULE IS NOT: it is not a second tool registry and not a new
|
|
20
|
+
* authority. Host-threaded callers (the consumer cycle) keep passing their
|
|
21
|
+
* live in-memory registry — the running host IS the authority for its own
|
|
22
|
+
* session. Host-neutral callers omit it and the DURABLE workspace provenance
|
|
23
|
+
* (`.pd/host-tool-semantics/<hostKind>.json`, persisted by every host on
|
|
24
|
+
* startup) is resolved through the ONE resolver
|
|
25
|
+
* (`resolveWorkspaceHostToolSemantics`). Unresolvable provenance is a
|
|
26
|
+
* structured refusal — never a silent fallback to the core baseline (an
|
|
27
|
+
* existence check against baseline names is a forged proof; ERR-114).
|
|
28
|
+
*
|
|
29
|
+
* Parity contract (pinned by evaluator-runtime-context.test.ts and the
|
|
30
|
+
* run-once evaluator parity test): the same artifact + workspace + declared
|
|
31
|
+
* host produces the SAME deterministic replay verdict whether it travels the
|
|
32
|
+
* consumer cycle (live registry) or a CLI entry (durable declaration), because
|
|
33
|
+
* hosts persist the same mapping constants they pass in memory.
|
|
34
|
+
*/
|
|
35
|
+
import { createProductionGateDeps, } from '@principles/core/runtime-v2';
|
|
36
|
+
import { resolveWorkspaceHostToolSemantics } from './host-tool-semantic-resolver.js';
|
|
37
|
+
/**
|
|
38
|
+
* Build the evaluator's deterministic replay context.
|
|
39
|
+
*
|
|
40
|
+
* Mirrors the consumer-cycle assembly (PRI-634 A1/A3):
|
|
41
|
+
* gateDeps: createProductionGateDeps({ toolSemantics, projectDir: workspaceDir })
|
|
42
|
+
* — gateDeps belongs to evaluator PRODUCTION semantics, never to host-optional
|
|
43
|
+
* capability, and always travels in the runner OPTIONS (second constructor
|
|
44
|
+
* argument), never the deps argument.
|
|
45
|
+
*/
|
|
46
|
+
export function createEvaluatorRuntimeContext(input) {
|
|
47
|
+
if (input.toolSemantics) {
|
|
48
|
+
return {
|
|
49
|
+
ok: true,
|
|
50
|
+
gateDeps: createProductionGateDeps({ projectDir: input.workspaceDir, toolSemantics: input.toolSemantics }),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const resolved = resolveWorkspaceHostToolSemantics(input.workspaceDir);
|
|
54
|
+
if (!resolved.ok) {
|
|
55
|
+
return { ok: false, reason: resolved.reason, nextAction: resolved.nextAction };
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
ok: true,
|
|
59
|
+
gateDeps: createProductionGateDeps({ projectDir: input.workspaceDir, toolSemantics: resolved.registry }),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
@@ -17,6 +17,7 @@ export * from './internalization-consumer-governance.js';
|
|
|
17
17
|
export * from './internalization-consumer-cycle.js';
|
|
18
18
|
export * from './host-tool-declaration.js';
|
|
19
19
|
export * from './host-tool-semantic-resolver.js';
|
|
20
|
+
export * from './evaluator-runtime-context.js';
|
|
20
21
|
export * from './workspace-telemetry-emitter.js';
|
|
21
22
|
export * from './product-telemetry/consent-store.js';
|
|
22
23
|
export * from './product-telemetry/eligibility.js';
|
|
@@ -21,6 +21,8 @@ export * from './internalization-consumer-cycle.js';
|
|
|
21
21
|
// neutral consumers (pd-cli/pd-console) resolve through the ONE resolver.
|
|
22
22
|
export * from './host-tool-declaration.js';
|
|
23
23
|
export * from './host-tool-semantic-resolver.js';
|
|
24
|
+
// PRI-661: ONE evaluator replay-context builder for host-neutral CLI entries.
|
|
25
|
+
export * from './evaluator-runtime-context.js';
|
|
24
26
|
// PRI-634 A3: workspace-scoped critical telemetry — canonical implementation
|
|
25
27
|
// moved from openclaw-plugin so both hosts share ONE semantics.
|
|
26
28
|
export * from './workspace-telemetry-emitter.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-principles-disciple",
|
|
3
|
-
"version": "1.132.
|
|
3
|
+
"version": "1.132.1",
|
|
4
4
|
"description": "Interactive CLI installer for Principles Disciple OpenClaw plugin",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"author": "csuzngjh",
|
|
42
42
|
"license": "MIT",
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@principles/install-layout": "0.
|
|
44
|
+
"@principles/install-layout": "^0.2.0",
|
|
45
45
|
"@tufjs/models": "3.0.1",
|
|
46
46
|
"@inquirer/prompts": "^8.5.2",
|
|
47
47
|
"commander": "^14.0.3",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/commands/health.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/commands/health.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AA2EtD,UAAU,aAAa;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAoBD,wBAAsB,YAAY,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuI1E;AAED;;;;GAIG;AACH,UAAU,qBAAqB;IAC7B,MAAM,CAAC,EAAE,OAAO,YAAY,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,iBAAiB,CAAC;CACxC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,GAAE,qBAA0B,GAAG,IAAI,CAkClG"}
|
|
@@ -13,7 +13,35 @@ import Database from 'better-sqlite3';
|
|
|
13
13
|
import { resolveWorkspaceDir } from '../resolve-workspace.js';
|
|
14
14
|
import { PruningReadModel, PainChainReadModel, auditCandidateLedgerConsistency } from '@principles/core/runtime-v2';
|
|
15
15
|
import { getLedgerFilePathPublic } from '@principles/core/principle-tree-ledger';
|
|
16
|
+
import { createEvaluatorRuntimeContext, loadHostToolDeclarations, resolveWorkspaceHostToolSemantics, } from '@principles/host-runtime';
|
|
16
17
|
import { handleHealthCodex } from './health-codex.js';
|
|
18
|
+
function assessReliability(workspaceDir) {
|
|
19
|
+
const loaded = loadHostToolDeclarations(workspaceDir);
|
|
20
|
+
const resolver = resolveWorkspaceHostToolSemantics(workspaceDir);
|
|
21
|
+
const replay = createEvaluatorRuntimeContext({ workspaceDir });
|
|
22
|
+
if (loaded.ok) {
|
|
23
|
+
return {
|
|
24
|
+
registry: {
|
|
25
|
+
status: 'ok',
|
|
26
|
+
hosts: loaded.declarations.map((d) => d.hostKind).sort(),
|
|
27
|
+
declaredTools: loaded.declarations.reduce((n, d) => n + d.mappings.length, 0),
|
|
28
|
+
},
|
|
29
|
+
resolver: resolver.ok ? 'ready' : 'not_ready',
|
|
30
|
+
replay: replay.ok ? 'ready' : 'not_ready',
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
// Fresh-install expected state until each host starts once — explicit, never
|
|
34
|
+
// a silent baseline fallback (ERR-114). Informational: the refusal authority
|
|
35
|
+
// lives in the activation/evaluator paths, so the health exit code is
|
|
36
|
+
// unchanged by this section.
|
|
37
|
+
return {
|
|
38
|
+
registry: { status: 'degraded', hosts: [], declaredTools: 0 },
|
|
39
|
+
resolver: 'not_ready',
|
|
40
|
+
replay: 'not_ready',
|
|
41
|
+
reason: loaded.reason,
|
|
42
|
+
nextAction: loaded.nextAction,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
17
45
|
function painChainTraceToLastSuccessfulChain(trace) {
|
|
18
46
|
const totalMs = (trace.latencyMs.painToTask ?? 0)
|
|
19
47
|
+ (trace.latencyMs.taskToRun ?? 0)
|
|
@@ -42,6 +70,7 @@ export async function handleHealth(opts = {}) {
|
|
|
42
70
|
const healthSummary = pruningModel.getHealthSummary();
|
|
43
71
|
const ledgerByStatus = healthSummary.byStatus;
|
|
44
72
|
const { missingLedgerCount } = await auditCandidateLedgerConsistency(workspaceDir);
|
|
73
|
+
const reliability = assessReliability(workspaceDir);
|
|
45
74
|
let candidatesTotal = 0, candidatesConsumed = 0, candidatesPending = 0;
|
|
46
75
|
let tasksTotal = 0;
|
|
47
76
|
const tasksByStatus = {};
|
|
@@ -66,6 +95,7 @@ export async function handleHealth(opts = {}) {
|
|
|
66
95
|
status: missingLedgerCount === 0 ? 'ok' : 'degraded',
|
|
67
96
|
missing: missingLedgerCount,
|
|
68
97
|
},
|
|
98
|
+
reliability,
|
|
69
99
|
lastSuccessfulChain,
|
|
70
100
|
};
|
|
71
101
|
}
|
|
@@ -92,6 +122,15 @@ export async function handleHealth(opts = {}) {
|
|
|
92
122
|
console.log(`tasks.byStatus: ${JSON.stringify(health.tasks.byStatus)}`);
|
|
93
123
|
console.log(`candidateLedgerConsistency.status: ${health.candidateLedgerConsistency.status}`);
|
|
94
124
|
console.log(`candidateLedgerConsistency.missing: ${health.candidateLedgerConsistency.missing}`);
|
|
125
|
+
console.log(`reliability.registry.status: ${health.reliability.registry.status}`);
|
|
126
|
+
console.log(`reliability.registry.hosts: ${health.reliability.registry.hosts.join('+') || '(none)'}`);
|
|
127
|
+
console.log(`reliability.registry.declaredTools: ${health.reliability.registry.declaredTools}`);
|
|
128
|
+
console.log(`reliability.resolver: ${health.reliability.resolver}`);
|
|
129
|
+
console.log(`reliability.replay: ${health.reliability.replay}`);
|
|
130
|
+
if (health.reliability.reason) {
|
|
131
|
+
console.log(`reliability.reason: ${health.reliability.reason}`);
|
|
132
|
+
console.log(`reliability.nextAction: ${health.reliability.nextAction}`);
|
|
133
|
+
}
|
|
95
134
|
if (health.lastSuccessfulChain) {
|
|
96
135
|
console.log('lastSuccessfulChain:');
|
|
97
136
|
console.log(` taskId: ${health.lastSuccessfulChain.taskId}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/commands/health.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,+BAA+B,EAAE,MAAM,6BAA6B,CAAC;AAEpH,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/commands/health.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,+BAA+B,EAAE,MAAM,6BAA6B,CAAC;AAEpH,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AACjF,OAAO,EACL,6BAA6B,EAC7B,wBAAwB,EACxB,iCAAiC,GAClC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAiCtD,SAAS,iBAAiB,CAAC,YAAoB;IAC7C,MAAM,MAAM,GAAG,wBAAwB,CAAC,YAAY,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,iCAAiC,CAAC,YAAY,CAAC,CAAC;IACjE,MAAM,MAAM,GAAG,6BAA6B,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;IAE/D,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;QACd,OAAO;YACL,QAAQ,EAAE;gBACR,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE;gBACxD,aAAa,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;aAC9E;YACD,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW;YAC7C,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW;SAC1C,CAAC;IACJ,CAAC;IACD,6EAA6E;IAC7E,6EAA6E;IAC7E,sEAAsE;IACtE,6BAA6B;IAC7B,OAAO;QACL,QAAQ,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC,EAAE;QAC7D,QAAQ,EAAE,WAAW;QACrB,MAAM,EAAE,WAAW;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,UAAU,EAAE,MAAM,CAAC,UAAU;KAC9B,CAAC;AACJ,CAAC;AAoBD,SAAS,mCAAmC,CAAC,KAAqB;IAChE,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,IAAI,CAAC,CAAC;UAC7C,CAAC,KAAK,CAAC,SAAS,CAAC,SAAS,IAAI,CAAC,CAAC;UAChC,CAAC,KAAK,CAAC,SAAS,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC;IAEzC,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;QACxB,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,EAAE;QAClC,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,SAAS,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE;QACzD,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAI,GAAkB,EAAE;IACzD,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS;QACjC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;QAC9B,CAAC,CAAC,mBAAmB,EAAE,CAAC;IAE1B,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAC5D,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IACzD,MAAM,UAAU,GAAG,uBAAuB,CAAC,cAAc,CAAC,CAAC;IAE3D,MAAM,YAAY,GAAG,IAAI,gBAAgB,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;IAC5D,MAAM,aAAa,GAAG,YAAY,CAAC,gBAAgB,EAAE,CAAC;IACtD,MAAM,cAAc,GAAG,aAAa,CAAC,QAAQ,CAAC;IAE9C,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,+BAA+B,CAAC,YAAY,CAAC,CAAC;IACnF,MAAM,WAAW,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAEpD,IAAI,eAAe,GAAG,CAAC,EAAE,kBAAkB,GAAG,CAAC,EAAE,iBAAiB,GAAG,CAAC,CAAC;IACvE,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,MAAM,aAAa,GAA2B,EAAE,CAAC;IACjD,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,mBAAmB,GAAoC,SAAS,CAAC;IACrE,IAAI,aAAa,GAAG,KAAK,CAAC;IAE1B,SAAS,WAAW;QAClB,OAAO;YACL,WAAW;YACX,SAAS,EAAE,YAAY;YACvB,aAAa;YACb,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE;YACjD,MAAM,EAAE;gBACN,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;gBACjC,eAAe,EAAE,aAAa,CAAC,eAAe;gBAC9C,QAAQ,EAAE,cAAc;aACzB;YACD,UAAU,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,kBAAkB,EAAE,OAAO,EAAE,iBAAiB,EAAE;YAChG,KAAK,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE;YACrD,0BAA0B,EAAE;gBAC1B,MAAM,EAAE,kBAAkB,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU;gBACpD,OAAO,EAAE,kBAAkB;aAC5B;YACD,WAAW;YACX,mBAAmB;SACpB,CAAC;IACJ,CAAC;IAED,SAAS,WAAW;QAClB,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC;QAE7B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7C,IAAI,MAAM,CAAC,0BAA0B,CAAC,MAAM,KAAK,UAAU;gBAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC7E,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,qBAAqB,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5D,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,kBAAkB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,2BAA2B,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC1E,OAAO,CAAC,GAAG,CAAC,qBAAqB,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5D,OAAO,CAAC,GAAG,CAAC,wBAAwB,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC,uBAAuB,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;QAChE,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,sCAAsC,MAAM,CAAC,0BAA0B,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9F,OAAO,CAAC,GAAG,CAAC,uCAAuC,MAAM,CAAC,0BAA0B,CAAC,OAAO,EAAE,CAAC,CAAC;QAChG,OAAO,CAAC,GAAG,CAAC,gCAAgC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAClF,OAAO,CAAC,GAAG,CAAC,+BAA+B,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC;QACtG,OAAO,CAAC,GAAG,CAAC,uCAAuC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;QAChG,OAAO,CAAC,GAAG,CAAC,yBAAyB,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,uBAAuB,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;QAChE,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,uBAAuB,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;YAChE,OAAO,CAAC,GAAG,CAAC,2BAA2B,MAAM,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC,CAAC;QAC1E,CAAC;QACD,IAAI,MAAM,CAAC,mBAAmB,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,mBAAmB,CAAC,MAAM,EAAE,CAAC,CAAC;YACpE,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAC,CAAC;YACnE,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,CAAC,CAAC;YACxE,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,mBAAmB,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACrF,OAAO,CAAC,GAAG,CAAC,oBAAoB,MAAM,CAAC,mBAAmB,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1F,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,IAAI,MAAM,CAAC,0BAA0B,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YAC5D,OAAO,CAAC,IAAI,CAAC,qFAAqF,GAAG,YAAY,GAAG,UAAU,CAAC,CAAC;YAChI,OAAO,CAAC,IAAI,CAAC,qFAAqF,GAAG,YAAY,GAAG,UAAU,CAAC,CAAC;YAChI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,UAAU,GAAG,IAAI,CAAC;QAClB,MAAM,EAAE,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,4EAA4E,CAAC,CAAC,GAAG,EAAyC,CAAC;YACnJ,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;gBACrB,eAAe,IAAI,CAAC,CAAC,KAAK,CAAC;gBAC3B,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU;oBAAE,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC;gBAC1D,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS;oBAAE,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC;YAC1D,CAAC;YAED,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,6DAA6D,CAAC,CAAC,GAAG,EAAyC,CAAC;YACrI,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,UAAU,IAAI,CAAC,CAAC,KAAK,CAAC;gBACtB,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;YACpC,CAAC;YAED,MAAM,cAAc,GAAG,IAAI,kBAAkB,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;YAChE,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,sBAAsB,EAAE,CAAC;gBAC5D,IAAI,KAAK,EAAE,CAAC;oBACV,mBAAmB,GAAG,mCAAmC,CAAC,KAAK,CAAC,CAAC;gBACnE,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,aAAa,GAAG,IAAI,CAAC;YACvB,CAAC;oBAAS,CAAC;gBACT,MAAM,cAAc,CAAC,KAAK,EAAE,CAAC;YAC/B,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,OAAO,CAAC,IAAI,CAAC,wEAAwE,GAAG,EAAE,CAAC,CAAC;YAC5F,aAAa,GAAG,IAAI,CAAC;QACvB,CAAC;gBAAS,CAAC;YACT,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC;IACH,CAAC;IAED,WAAW,EAAE,CAAC;AAChB,CAAC;AAYD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAgB,EAAE,QAAQ,GAA0B,EAAE;IAC1F,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,IAAI,YAAY,CAAC;IACtD,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,IAAI,iBAAiB,CAAC;IAC/D,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,4CAA4C,CAAC;SACzD,MAAM,CAAC,wBAAwB,EAAE,qBAAqB,CAAC;SACvD,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC;SACnC,MAAM,CAAC,eAAe,EAAE,0EAA0E,CAAC;SACnG,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,UAAU,CAAC;QACrC,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YAC5C,qDAAqD;YACrD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;oBACzB,EAAE,EAAE,KAAK;oBACT,MAAM,EAAE,cAAc;oBACtB,IAAI;oBACJ,UAAU,EAAE,0CAA0C;iBACvD,CAAC,CAAC,CAAC;gBACJ,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;YACD,OAAO,CAAC,KAAK,CAAC,mBAAmB,IAAI,sCAAsC,CAAC,CAAC;YAC7E,OAAO,CAAC,KAAK,CAAC,8EAA8E,CAAC,CAAC;YAC9F,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACrB,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;YACzB,OAAO;QACT,CAAC;QACD,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-internalization-run-once.d.ts","sourceRoot":"","sources":["../../src/commands/runtime-internalization-run-once.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtime-internalization-run-once.d.ts","sourceRoot":"","sources":["../../src/commands/runtime-internalization-run-once.ts"],"names":[],"mappings":"AAoCA,UAAU,cAAc;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAyXD,wBAAsB,mCAAmC,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAkR7F"}
|
|
@@ -9,6 +9,7 @@ import { resolveRuntimeAdapterFromConfig, ConfigResolutionError, } from '../serv
|
|
|
9
9
|
// path. EP-02: prior code passed only the 5 base deps, leaving the repair
|
|
10
10
|
// loop as dead code at runtime.
|
|
11
11
|
import { createEvaluatorRunnerDeps, contentHashFn } from '../services/rulehost-pipeline-runner.js';
|
|
12
|
+
import { createEvaluatorRuntimeContext } from '@principles/host-runtime';
|
|
12
13
|
const OWNER = 'pd-cli-internalization-run-once';
|
|
13
14
|
const RUNTIME_KIND = 'local-worker';
|
|
14
15
|
// PRI-458: philosopher, evaluator, rollout_reviewer are MVP-Quiet (default off).
|
|
@@ -367,6 +368,33 @@ export async function handleRuntimeInternalizationRunOnce(opts) {
|
|
|
367
368
|
process.exitCode = 1;
|
|
368
369
|
return;
|
|
369
370
|
}
|
|
371
|
+
// PRI-661: the evaluator's deterministic adversarial replay needs the
|
|
372
|
+
// production gate context (workspace root + host tool registry from durable
|
|
373
|
+
// provenance) — the SAME context the consumer cycle replays with. Refuse
|
|
374
|
+
// BEFORE leasing any task (cli-5: no mutation on refusal) with the same
|
|
375
|
+
// structured semantics as runtime-activation's code_tool_hook refusal.
|
|
376
|
+
let evaluatorGateDeps;
|
|
377
|
+
if (runnerKind === 'evaluator') {
|
|
378
|
+
const evaluatorContext = createEvaluatorRuntimeContext({ workspaceDir });
|
|
379
|
+
if (!evaluatorContext.ok) {
|
|
380
|
+
const refused = {
|
|
381
|
+
decision: 'refused',
|
|
382
|
+
reason: evaluatorContext.reason,
|
|
383
|
+
nextAction: evaluatorContext.nextAction,
|
|
384
|
+
};
|
|
385
|
+
if (opts.json) {
|
|
386
|
+
console.log(JSON.stringify(refused, null, 2));
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
console.log(`Run-once: refused`);
|
|
390
|
+
console.log(` reason: ${refused.reason}`);
|
|
391
|
+
console.log(` nextAction: ${refused.nextAction}`);
|
|
392
|
+
}
|
|
393
|
+
process.exitCode = 1;
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
evaluatorGateDeps = evaluatorContext.gateDeps;
|
|
397
|
+
}
|
|
370
398
|
const stateManager = new RuntimeStateManager({ workspaceDir });
|
|
371
399
|
await stateManager.initialize();
|
|
372
400
|
// Issue 2: resolve effective config for feature-flag-aware runners
|
|
@@ -447,7 +475,19 @@ export async function handleRuntimeInternalizationRunOnce(opts) {
|
|
|
447
475
|
// `context_manifest_budget` were structurally unreadable on this
|
|
448
476
|
// path — the two-stage evaluator could never be enabled from the
|
|
449
477
|
// CLI. Mirrors line 525 (artificer) and rulehost runnerOptsFor.
|
|
450
|
-
|
|
478
|
+
//
|
|
479
|
+
// PRI-661: gateDeps resolved ABOVE via the ONE
|
|
480
|
+
// createEvaluatorRuntimeContext builder (durable workspace
|
|
481
|
+
// provenance + workspace root) — replay/production parity with
|
|
482
|
+
// the consumer cycle. Options argument (2nd), never deps (1st).
|
|
483
|
+
{
|
|
484
|
+
owner: OWNER,
|
|
485
|
+
runtimeKind: runtimeAdapter.kind(),
|
|
486
|
+
pollIntervalMs: 100,
|
|
487
|
+
timeoutMs: effectiveTimeoutMs,
|
|
488
|
+
effectiveConfig,
|
|
489
|
+
gateDeps: evaluatorGateDeps,
|
|
490
|
+
});
|
|
451
491
|
runnerResult = await runner.run(wakeResult.taskId);
|
|
452
492
|
}
|
|
453
493
|
else if (runnerKind === 'rollout_reviewer') {
|