chainlesschain 0.166.87 → 0.166.89
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/README.md +31 -17
- package/package.json +1 -1
- package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
- package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-DdQjhXg9.js → AIOps-C8AkN9R5.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CuwA3hPA.js → ActionButton-BrAzSQor.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DTVXJSAC.js → Analytics-Cu56X8Oh.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-j06JBfEQ.js → AppLayout-BP1Riofl.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-BFAK8LEW.js → Artifacts-CIW-nNAz.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-BiGxRpOf.js → Audit-CJtDabk-.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-B6uHaPkZ.js → BackgroundAgents-DYIHeQ_P.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BNAesB8q.js → Backup-B4CsFzj7.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BOuetfCd.js → BaseInput-3eoJ5kfb.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-cVzo3m_D.js → Chat-BBhX2L_E.js} +4 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-RN8cbv7w.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-BaCTS-H8.js → Checkbox-5UvmwHVk.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-CBE8NiYh.js → Codegen-BFy8zsBN.js} +1 -1
- package/src/assets/web-panel/assets/{Col-C9wLiUTN.js → Col-4M6bKRRO.js} +1 -1
- package/src/assets/web-panel/assets/{Community-jdClBSIp.js → Community-D6LC0j7_.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BIjauIlM.js → Compact-Dd48xMcv.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CZ-AoaNj.js → Compliance-Ba85ggmy.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-BbTKtDS4.js → Cowork-D1BXlkuK.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-ImKdtwNi.js → Cron-Ca2Uy7Ia.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-B54GSHf5.js → Crosschain-C2bDRXZg.js} +1 -1
- package/src/assets/web-panel/assets/{DID-BQt5WUzs.js → DID-DySZKAJf.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard--gNOffif.js → Dashboard-DDpYf-TT.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-342A5YJw.js → Dropdown-DGjROfPv.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CtIZ3ZHd.js → EmailListRenderer-DxX9QYiB.js} +1 -1
- package/src/assets/web-panel/assets/{EvolutionSettings-CyZPoTio.js → EvolutionSettings-TBCZyrSJ.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-B1MCkFEu.js → FamilyGuardDashboard-BeqwTXBa.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DZWoERUy.js → Federation-CiCpKJQ1.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-Onmb0mp3.js → FormItemContext-CdTmbLkU.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-u1qhNNc7.js → GenericCardRenderer-BwbkEY-5.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BEowR1C5.js → Git-VnAga2vv.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BiYd3AAg.js → Governance-i-4Ebs-H.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CsC4Vjh5.js → Inference-CirjTgNw.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-BXA7ikPM.js → KnowledgeGraph-CunS7vhA.js} +1 -1
- package/src/assets/web-panel/assets/Logs-DBuTF0c6.js +2 -0
- package/src/assets/web-panel/assets/MarkdownRenderer-B-iE-tt_.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-CCoJBfRL.js → Marketplace-BK6ZivTS.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-CzaOWBoA.js → McpTools-CUnCRnd3.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-BPwh7u1-.js → Memory-CBGGr8Gy.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-Bk47v6z2.js → MobileBridge-reB6iaWD.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-D-CY--Sb.js → MobileProjects-o1YdVB7i.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-ExVyAGlW.js → Mtc-if5OE3GH.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-Rrw10csE.js → MtcAudit-BTZWpq0j.js} +5 -5
- package/src/assets/web-panel/assets/{Multisig-8TxxwxZZ.js → Multisig-8cvMAYFL.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CNckjtnY.js → NLProgramming-BMvUXAWo.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-C4j6cZTu.js → Notes-BWWjColh.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-CchU8rWd.js → NotificationSettings-Ccr4lIhS.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-DhksGy6D.js +1 -0
- package/src/assets/web-panel/assets/{Organization-F0Je7EdZ.js → Organization-DciXQfdY.js} +2 -2
- package/src/assets/web-panel/assets/{Overflow-B2k-JA3u.js → Overflow-8DR7uMSx.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-yui9Xxe6.js → P2P-DE6euHYl.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-CegM7hT6.js → PdhVaultBrowser-ByuWoauq.js} +4 -4
- package/src/assets/web-panel/assets/{Permissions-CSFL0uvh.js → Permissions-DkjM87ac.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BrMcd-vr.js → PersonalDataHub-2DLp0KTL.js} +6 -6
- package/src/assets/web-panel/assets/{Pipeline-fzrliaVP.js → Pipeline-Ci2Qlkfr.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-BrkUjJ_g.js → Privacy-DlwDnDVA.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-CF_QCsW9.js → ProjectInit-CmMifW39.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-Duwrd8aC.js → ProjectSettings-DJVFIh-6.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-B0dLVXzU.js → Projects-P2nWBS70.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-Db8iS1xQ.js → Providers-B2cxaGCU.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-CHbNzEQs.js → QrScannerModal-CpO77kcE.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CIESMfeR.js → QuickAsk-BDQl1hb0.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-BTMbCMtR.js → Recommend-DTD2f3IN.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DavyK6J-.js → RemoteSession-DGZAnwvs.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-BFKtMelA.js → Reputation-B_R4vitb.js} +1 -1
- package/src/assets/web-panel/assets/{Row-BI9AZUvw.js → Row-4Jj6JyXN.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-1nwXt8NY.js → RssFeed-D1t1MCZ-.js} +2 -2
- package/src/assets/web-panel/assets/{Search-Ck8PDYbk.js → Search-CyOUlIn7.js} +1 -1
- package/src/assets/web-panel/assets/{Security-BgDqpCbq.js → Security-BmknPT5Q.js} +4 -4
- package/src/assets/web-panel/assets/{Services-DF8anXm4.js → Services-DkEK8mpa.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CoHyY4ZX.js → Skeleton-Bvo5bpuk.js} +1 -1
- package/src/assets/web-panel/assets/Skills-AMmG8fim.js +1 -0
- package/src/assets/web-panel/assets/{Sla-XuOawvQY.js → Sla-Dl7-OKOV.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DFJ7nAiu.js → SpeechSettings-DtiGKu0E.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-B2xYj-Pi.js → SyncSettings-Ch7mp3ES.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-Ck-sEgj-.js +1 -0
- package/src/assets/web-panel/assets/{Templates-BXFmKh7W.js → Templates-BlV22Il8.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CRg2AXbd.js → Tenant-CaaAu0mX.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-DQgxnuep.js → Terminal-lA9g3FtJ.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-BrPQhQVc.js → TimelineRenderer-CG26IFC3.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-RByy4USy.js → Tokens-iaJUBLBm.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-pE3y8u73.js → Trigger-DWQJtLK3.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DhID9C33.js → Trust-CTjmUwqp.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-CPxEPNBH.js → UkeySign-CMnxufgD.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-ZD8DUxeQ.js → VideoEditing-diCFSWJw.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-Br9JREEd.js → Wallet-Ba1oND1K.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-Cn-YacJg.js → WebAuthn-DZDqPS-S.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-BTu0oqMp.js → WorkflowEditor-CfN8fPMe.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CEjws_QF.js → chat-BiqMsO_i.js} +1 -1
- package/src/assets/web-panel/assets/{colors-Bv2RNebW.js → colors-By8LkjqH.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-gSc3EofP.js → compact-item-B0mxvRe3.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-kyFDaqWC.js → createContext-Li2ub348.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-D90arbUg.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-BuMWcjhx.js → hasIn-DYbHPkbl.js} +1 -1
- package/src/assets/web-panel/assets/{index-C9U9SjcT.js → index-1lVoRUrQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BUOCcXou.js → index-B0D0HkkM.js} +1 -1
- package/src/assets/web-panel/assets/{index-CNt2X-aK.js → index-BFhksbXp.js} +1 -1
- package/src/assets/web-panel/assets/{index-BCS5j4SQ.js → index-BRzewWeE.js} +1 -1
- package/src/assets/web-panel/assets/{index-42PTBO7a.js → index-BSk0xuXP.js} +1 -1
- package/src/assets/web-panel/assets/{index-DRa4R7vv.js → index-BZqTG7fP.js} +1 -1
- package/src/assets/web-panel/assets/{index-q65c1kp8.js → index-Bc6bxU24.js} +1 -1
- package/src/assets/web-panel/assets/{index-xfS_WO9b.js → index-BcOJEgBE.js} +1 -1
- package/src/assets/web-panel/assets/{index-Czo_hw97.js → index-Bd5znvCV.js} +1 -1
- package/src/assets/web-panel/assets/{index-CMS3Mk93.js → index-Bm2P2Kgp.js} +1 -1
- package/src/assets/web-panel/assets/{index-NQ0c4hJ1.js → index-ByqFKMWL.js} +1 -1
- package/src/assets/web-panel/assets/{index-CkfvP2dN.js → index-C-RE3mFh.js} +1 -1
- package/src/assets/web-panel/assets/{index-EpxWlmip.js → index-C5Se6Lnv.js} +1 -1
- package/src/assets/web-panel/assets/{index-jmMAqBAm.js → index-CA0AOURT.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dej4AGOz.js → index-CEp_3fKJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-GpvWtvw3.js → index-CGZzexNa.js} +1 -1
- package/src/assets/web-panel/assets/{index-OjZUHz5z.js → index-CHgiSV6R.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bg5jis0q.js → index-CMh3VxgO.js} +1 -1
- package/src/assets/web-panel/assets/{index-DR561Sqc.js → index-CTVPeUh3.js} +1 -1
- package/src/assets/web-panel/assets/{index-D3m3EXbL.js → index-CVZNYRzM.js} +1 -1
- package/src/assets/web-panel/assets/{index-C7Jo20JB.js → index-CYv3JIzl.js} +1 -1
- package/src/assets/web-panel/assets/index-CeP1oROI.js +1 -0
- package/src/assets/web-panel/assets/{index-DYcPWVN9.js → index-CgyrklzQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DYKSuD02.js → index-ClsJN8sW.js} +3 -3
- package/src/assets/web-panel/assets/{index-Cj4RA7oA.js → index-Cpfn4YbT.js} +1 -1
- package/src/assets/web-panel/assets/index-Cu9gkyRc.js +1 -0
- package/src/assets/web-panel/assets/{index-U-ytt84A.js → index-Czt7WAtA.js} +1 -1
- package/src/assets/web-panel/assets/{index-DbkyTMj-.js → index-D6qL3QBU.js} +1 -1
- package/src/assets/web-panel/assets/{index-C56Drzol.js → index-DAOpBv3C.js} +1 -1
- package/src/assets/web-panel/assets/{index-CF3TjDNz.js → index-DB4DCzqU.js} +1 -1
- package/src/assets/web-panel/assets/{index-sJ1F5Txa.js → index-DIImi0cd.js} +1 -1
- package/src/assets/web-panel/assets/{index-CvSuM_CB.js → index-DPRgnazi.js} +1 -1
- package/src/assets/web-panel/assets/{index-BSSIJ-rv.js → index-DgMFnBOv.js} +1 -1
- package/src/assets/web-panel/assets/{index-nLemnBZ2.js → index-KWt8Owo8.js} +1 -1
- package/src/assets/web-panel/assets/{index-DbVUA5l3.js → index-KqfqSdAC.js} +1 -1
- package/src/assets/web-panel/assets/{index--nrQmk8X.js → index-b4O_YBVR.js} +1 -1
- package/src/assets/web-panel/assets/{index-C-LPpwe9.js → index-beDji-cB.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cm8K8Evn.js → index-hw3sCYAz.js} +1 -1
- package/src/assets/web-panel/assets/{index-_0bfDTDu.js → index-zSzXsF9b.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-B-wqiSu7.js → initDefaultProps-TgDL_7OY.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BK4_B4MD.js → motion-fHosyV5c.js} +1 -1
- package/src/assets/web-panel/assets/{move-BU2TgDDO.js → move-C_QfW5qg.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DA3E4_EX.js → mtc-parser-u7ywDVOg.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CaHz1e_q.js → omit-BEJdUgE9.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-NXZ19amf.js → pickAttrs-DGkQFAJ5.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BCXI9AHO.js → placementArrow-DUyZXAjt.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-DdlZ9tLk.js → responsiveObserve-B4xDxO7Q.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DCZm_Vc4.js → slide-B8WuJtst.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-CuEULKQr.js → statusUtils-DLUqy7JO.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-Bo_UXG8x.js → styleChecker-BYOJOyqL.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-B9PaTcFH.js → useFlexGapSupport-WChWQURv.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DwSTGdVR.js → useFs-vLNpm3dv.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-FswSxnDC.js → usePersonalDataHub-DSZ8unoU.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-EUztvYTj.js → vnode-C4Xf7Kg1.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-D41MAgV-.js → zoom-BulmeAGy.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +1 -1
- package/src/commands/agent-controlled-host.js +220 -0
- package/src/commands/agent.js +3 -1
- package/src/commands/eval.js +3 -54
- package/src/data/changelog.json +26 -0
- package/src/lib/eval/stream-terminal.js +51 -0
- package/src/lib/eval/verify01-execution.js +16 -1
- package/src/lib/eval/verify01-host-capture.js +430 -0
- package/src/lib/eval/verify01-host-evidence.js +604 -0
- package/src/assets/web-panel/assets/ChatBubbleRenderer-DZ2Ys-CI.js +0 -1
- package/src/assets/web-panel/assets/Logs-C9WoplQm.js +0 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-DecEsXsy.js +0 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-ZJBoyJ16.js +0 -1
- package/src/assets/web-panel/assets/Skills-dOaD4Ztl.js +0 -1
- package/src/assets/web-panel/assets/Tasks-D_SzNTLi.js +0 -1
- package/src/assets/web-panel/assets/devWarning-Dcc8pILJ.js +0 -1
- package/src/assets/web-panel/assets/index-05NB95_V.js +0 -1
- package/src/assets/web-panel/assets/index-Cb6q8wlI.js +0 -1
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
|
+
import { evalDigest } from "./evidence.js";
|
|
5
|
+
import { outcomeDigest } from "./outcomes.js";
|
|
6
|
+
import {
|
|
7
|
+
requireValue,
|
|
8
|
+
relativeFile,
|
|
9
|
+
readBytes,
|
|
10
|
+
validateVerify01Review,
|
|
11
|
+
} from "./verify01-contracts.js";
|
|
12
|
+
import {
|
|
13
|
+
materializeVerify01Checkout,
|
|
14
|
+
snapshotVerify01Workspace,
|
|
15
|
+
diffVerify01Workspace,
|
|
16
|
+
runVerify01ReviewedProcess,
|
|
17
|
+
} from "./verify01-execution.js";
|
|
18
|
+
import { importVerify01HostCapture } from "./verify01-host-evidence.js";
|
|
19
|
+
|
|
20
|
+
const STATE_SCHEMA = "chainlesschain.verify01-host-preparation/v1";
|
|
21
|
+
const save = (root, file, value) => {
|
|
22
|
+
const bytes = Buffer.from(JSON.stringify(value, null, 2) + "\n");
|
|
23
|
+
fs.writeFileSync(path.join(root, file), bytes, { flag: "wx", mode: 0o600 });
|
|
24
|
+
return { path: file, digest: evalDigest(bytes) };
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export function captureArtifactReader(directory) {
|
|
28
|
+
const root = fs.realpathSync(directory);
|
|
29
|
+
return (relative) => {
|
|
30
|
+
relativeFile(relative);
|
|
31
|
+
let file = root;
|
|
32
|
+
for (const segment of relative.split("/")) {
|
|
33
|
+
file = path.join(file, segment);
|
|
34
|
+
requireValue(
|
|
35
|
+
!fs.lstatSync(file).isSymbolicLink(),
|
|
36
|
+
"capture path traverses a link",
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
return readBytes(file);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function outside(workspace, directory) {
|
|
44
|
+
const suffix = path.relative(workspace, directory);
|
|
45
|
+
requireValue(
|
|
46
|
+
suffix && (suffix.startsWith(`..${path.sep}`) || path.isAbsolute(suffix)),
|
|
47
|
+
"host control directories must be outside task workspace",
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function budget(deadline) {
|
|
52
|
+
return {
|
|
53
|
+
remainingMs(stage) {
|
|
54
|
+
const remaining = deadline - Date.now();
|
|
55
|
+
requireValue(
|
|
56
|
+
remaining > 0,
|
|
57
|
+
`host task deadline exhausted during ${stage}`,
|
|
58
|
+
);
|
|
59
|
+
return remaining;
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function select(bundle, preparation, sampleId) {
|
|
65
|
+
const artifacts = new Map();
|
|
66
|
+
const validated = validateVerify01Review(bundle, {
|
|
67
|
+
...preparation,
|
|
68
|
+
readReviewedFile(file) {
|
|
69
|
+
const bytes = Buffer.from(preparation.readReviewedFile(file));
|
|
70
|
+
artifacts.set(file, bytes);
|
|
71
|
+
return bytes;
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
const sample = validated.samples.get(sampleId);
|
|
75
|
+
requireValue(sample, "sample outside frozen population");
|
|
76
|
+
const target = bundle.bindings.matrix.find((row) =>
|
|
77
|
+
sample.stratum.startsWith(`${row.platform}-${row.entry}-`),
|
|
78
|
+
);
|
|
79
|
+
requireValue(
|
|
80
|
+
target && ["vscode", "jetbrains"].includes(target.entry),
|
|
81
|
+
"host capture requires an actual IDE entry",
|
|
82
|
+
);
|
|
83
|
+
const comparison = bundle.bindings.comparisons[sample.stratum];
|
|
84
|
+
requireValue(
|
|
85
|
+
process.platform === target.platform &&
|
|
86
|
+
process.arch === target.arch &&
|
|
87
|
+
process.version === target.node,
|
|
88
|
+
"actual capture runtime differs from frozen platform/arch/Node",
|
|
89
|
+
);
|
|
90
|
+
return {
|
|
91
|
+
sample,
|
|
92
|
+
target,
|
|
93
|
+
comparison,
|
|
94
|
+
artifacts,
|
|
95
|
+
task: validated.tasks.get(sample.taskId),
|
|
96
|
+
reviewed: validated.reviewed.get(sample.taskId),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Stores before bodies outside the candidate checkout. Each blob remains
|
|
101
|
+
* byte-bound; dependency files retain only their existing streamed identity.
|
|
102
|
+
*/
|
|
103
|
+
function storeBaseline(root, snapshot) {
|
|
104
|
+
const blobDirectory = path.join(root, "baseline-blobs");
|
|
105
|
+
fs.mkdirSync(blobDirectory, { mode: 0o700 });
|
|
106
|
+
const indexes = [];
|
|
107
|
+
let page = [],
|
|
108
|
+
pageBytes = 0;
|
|
109
|
+
const flush = () => {
|
|
110
|
+
if (!page.length) return;
|
|
111
|
+
indexes.push(save(root, `baseline-index-${indexes.length}.json`, page));
|
|
112
|
+
page = [];
|
|
113
|
+
pageBytes = 0;
|
|
114
|
+
};
|
|
115
|
+
for (const [file, value] of snapshot) {
|
|
116
|
+
let blob = null;
|
|
117
|
+
if (value.bytes !== null) {
|
|
118
|
+
blob = `baseline-blobs/${value.digest.slice(7)}.blob`;
|
|
119
|
+
const location = path.join(root, blob);
|
|
120
|
+
if (!fs.existsSync(location))
|
|
121
|
+
fs.writeFileSync(location, value.bytes, { flag: "wx", mode: 0o600 });
|
|
122
|
+
}
|
|
123
|
+
const entry = { path: file, ...value, bytes: undefined, blob };
|
|
124
|
+
const size = Buffer.byteLength(JSON.stringify(entry)) + 64;
|
|
125
|
+
if (pageBytes + size > 4 * 1024 * 1024) flush();
|
|
126
|
+
page.push(entry);
|
|
127
|
+
pageBytes += size;
|
|
128
|
+
}
|
|
129
|
+
flush();
|
|
130
|
+
return {
|
|
131
|
+
indexes,
|
|
132
|
+
files: snapshot.size,
|
|
133
|
+
dependencyBoundary: snapshot.dependencyBoundary,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function loadBaseline(root, baseline) {
|
|
138
|
+
const read = captureArtifactReader(root);
|
|
139
|
+
const entries = new Map();
|
|
140
|
+
let total = 0;
|
|
141
|
+
requireValue(
|
|
142
|
+
Number.isSafeInteger(baseline.files) &&
|
|
143
|
+
baseline.files <= 1100000 &&
|
|
144
|
+
Array.isArray(baseline.indexes),
|
|
145
|
+
"baseline file count exceeds scan bounds",
|
|
146
|
+
);
|
|
147
|
+
for (const index of baseline.indexes) {
|
|
148
|
+
const indexBytes = read(index.path);
|
|
149
|
+
requireValue(
|
|
150
|
+
evalDigest(indexBytes) === index.digest,
|
|
151
|
+
"baseline index byte binding differs",
|
|
152
|
+
);
|
|
153
|
+
for (const file of JSON.parse(indexBytes)) {
|
|
154
|
+
relativeFile(file.path);
|
|
155
|
+
requireValue(!entries.has(file.path), "duplicate baseline path");
|
|
156
|
+
const bytes = file.blob === null ? null : read(file.blob);
|
|
157
|
+
if (bytes !== null) {
|
|
158
|
+
total += bytes.length;
|
|
159
|
+
requireValue(
|
|
160
|
+
total <= 512 * 1024 * 1024 &&
|
|
161
|
+
bytes.length === file.size &&
|
|
162
|
+
evalDigest(bytes) === file.digest,
|
|
163
|
+
"before body differs from pinned baseline",
|
|
164
|
+
);
|
|
165
|
+
} else
|
|
166
|
+
requireValue(
|
|
167
|
+
file.dependency === true,
|
|
168
|
+
"nondependency baseline lacks its before body",
|
|
169
|
+
);
|
|
170
|
+
entries.set(file.path, { ...file, bytes });
|
|
171
|
+
requireValue(
|
|
172
|
+
entries.size <= baseline.files,
|
|
173
|
+
"baseline index has extra paths",
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
requireValue(entries.size === baseline.files, "baseline index is incomplete");
|
|
178
|
+
entries.dependencyBoundary = baseline.dependencyBoundary;
|
|
179
|
+
return entries;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export async function prepareVerify01HostTask(bundle, preparation, options) {
|
|
183
|
+
const { sample, target, comparison, artifacts, task, reviewed } = select(
|
|
184
|
+
bundle,
|
|
185
|
+
preparation,
|
|
186
|
+
options.sampleId,
|
|
187
|
+
);
|
|
188
|
+
requireValue(
|
|
189
|
+
options.os === target.os,
|
|
190
|
+
"operator OS declaration differs from frozen target",
|
|
191
|
+
);
|
|
192
|
+
requireValue(
|
|
193
|
+
/^[a-f0-9]{40}$/u.test(options.sourceCommit || ""),
|
|
194
|
+
"tested CLI source SHA required",
|
|
195
|
+
);
|
|
196
|
+
const workspace = path.resolve(options.workspace),
|
|
197
|
+
root = path.resolve(options.captureRoot);
|
|
198
|
+
const reviewRoot = fs.realpathSync(options.reviewRoot);
|
|
199
|
+
outside(workspace, root);
|
|
200
|
+
outside(workspace, reviewRoot);
|
|
201
|
+
requireValue(
|
|
202
|
+
!fs.existsSync(workspace) && !fs.existsSync(root),
|
|
203
|
+
"workspace and capture directory must be new; retry cannot overwrite an attempt",
|
|
204
|
+
);
|
|
205
|
+
const startedAt = new Date().toISOString(),
|
|
206
|
+
deadline = Date.now() + sample.timeBudgetMs;
|
|
207
|
+
fs.mkdirSync(workspace, { recursive: true, mode: 0o700 });
|
|
208
|
+
fs.mkdirSync(root, { recursive: true, mode: 0o700 });
|
|
209
|
+
const stageBudget = budget(deadline);
|
|
210
|
+
try {
|
|
211
|
+
const checkout = await materializeVerify01Checkout(
|
|
212
|
+
options.projectRoot,
|
|
213
|
+
bundle.catalog.projectCommit,
|
|
214
|
+
workspace,
|
|
215
|
+
stageBudget,
|
|
216
|
+
);
|
|
217
|
+
const setupBytes = artifacts.get(reviewed.setup.path);
|
|
218
|
+
const setup = runVerify01ReviewedProcess(
|
|
219
|
+
setupBytes,
|
|
220
|
+
workspace,
|
|
221
|
+
reviewRoot,
|
|
222
|
+
"setup",
|
|
223
|
+
stageBudget.remainingMs("setup"),
|
|
224
|
+
);
|
|
225
|
+
save(root, "setup.json", setup);
|
|
226
|
+
requireValue(
|
|
227
|
+
setup.exitCode === 0 && setup.signal === null && setup.error === null,
|
|
228
|
+
"reviewed host setup failed; preserve this first attempt",
|
|
229
|
+
);
|
|
230
|
+
const baseline = storeBaseline(
|
|
231
|
+
root,
|
|
232
|
+
snapshotVerify01Workspace(workspace, stageBudget, "baseline"),
|
|
233
|
+
);
|
|
234
|
+
const state = {
|
|
235
|
+
schema: STATE_SCHEMA,
|
|
236
|
+
sampleId: sample.id,
|
|
237
|
+
taskId: task.id,
|
|
238
|
+
planDigest: bundle.expectedPlanDigest,
|
|
239
|
+
reviewDigest: preparation.expectedReviewDigest,
|
|
240
|
+
projectCommit: bundle.catalog.projectCommit,
|
|
241
|
+
sourceCommit: options.sourceCommit,
|
|
242
|
+
entry: target.entry,
|
|
243
|
+
platform: process.platform,
|
|
244
|
+
arch: process.arch,
|
|
245
|
+
node: process.version,
|
|
246
|
+
os: options.os,
|
|
247
|
+
host: target.host,
|
|
248
|
+
workspace,
|
|
249
|
+
captureRoot: root,
|
|
250
|
+
startedAt,
|
|
251
|
+
deadline,
|
|
252
|
+
runId: `verify01-host-${randomUUID()}`,
|
|
253
|
+
checkout,
|
|
254
|
+
baseline,
|
|
255
|
+
provider: comparison.provider,
|
|
256
|
+
model: comparison.model,
|
|
257
|
+
permissionMode: comparison.permissionMode,
|
|
258
|
+
observationsCreated: false,
|
|
259
|
+
productionAttested: false,
|
|
260
|
+
};
|
|
261
|
+
save(root, "host-state.json", state);
|
|
262
|
+
fs.writeFileSync(path.join(root, "prompt.txt"), task.prompt, {
|
|
263
|
+
flag: "wx",
|
|
264
|
+
mode: 0o600,
|
|
265
|
+
});
|
|
266
|
+
return {
|
|
267
|
+
stateFile: path.join(root, "host-state.json"),
|
|
268
|
+
stateDigest: outcomeDigest(state),
|
|
269
|
+
state,
|
|
270
|
+
};
|
|
271
|
+
} catch (error) {
|
|
272
|
+
save(root, "prepare-failure.json", {
|
|
273
|
+
startedAt,
|
|
274
|
+
finishedAt: new Date().toISOString(),
|
|
275
|
+
sampleId: sample.id,
|
|
276
|
+
error: error.message,
|
|
277
|
+
observationsCreated: false,
|
|
278
|
+
});
|
|
279
|
+
throw error;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/** Execute the externally pinned acceptance bytes and assemble only actual
|
|
284
|
+
* driver files. Import into Eval/outcome is validated before writing output.
|
|
285
|
+
* First-run stage receipts are operator evidence, never inferred from setup.
|
|
286
|
+
*/
|
|
287
|
+
export function finishVerify01HostTask(bundle, preparation, options) {
|
|
288
|
+
requireValue(
|
|
289
|
+
Number.isSafeInteger(options.retries ?? 0) &&
|
|
290
|
+
(options.retries ?? 0) >= 0 &&
|
|
291
|
+
(options.retries ?? 0) <= 1 &&
|
|
292
|
+
Number.isSafeInteger(options.manualRepairs ?? 0) &&
|
|
293
|
+
(options.manualRepairs ?? 0) >= 0,
|
|
294
|
+
"host attempt and manual repair counts must retain the frozen bounds",
|
|
295
|
+
);
|
|
296
|
+
const state = options.state;
|
|
297
|
+
requireValue(
|
|
298
|
+
state?.schema === STATE_SCHEMA &&
|
|
299
|
+
outcomeDigest(state) === options.expectedStateDigest,
|
|
300
|
+
"host preparation state byte binding differs",
|
|
301
|
+
);
|
|
302
|
+
requireValue(
|
|
303
|
+
state.planDigest === bundle.expectedPlanDigest &&
|
|
304
|
+
state.reviewDigest === preparation.expectedReviewDigest &&
|
|
305
|
+
state.projectCommit === bundle.catalog.projectCommit &&
|
|
306
|
+
state.sourceCommit === options.sourceCommit,
|
|
307
|
+
"host preparation frozen identity differs",
|
|
308
|
+
);
|
|
309
|
+
const { sample, target, task, reviewed, artifacts } = select(
|
|
310
|
+
bundle,
|
|
311
|
+
preparation,
|
|
312
|
+
state.sampleId,
|
|
313
|
+
);
|
|
314
|
+
requireValue(
|
|
315
|
+
state.entry === target.entry &&
|
|
316
|
+
state.os === target.os &&
|
|
317
|
+
state.host === target.host &&
|
|
318
|
+
state.platform === target.platform &&
|
|
319
|
+
state.arch === target.arch &&
|
|
320
|
+
state.node === target.node,
|
|
321
|
+
"prepared host identity changed",
|
|
322
|
+
);
|
|
323
|
+
requireValue(
|
|
324
|
+
Number.isSafeInteger(state.deadline) &&
|
|
325
|
+
Number.isFinite(Date.parse(state.startedAt)) &&
|
|
326
|
+
state.deadline > Date.parse(state.startedAt) &&
|
|
327
|
+
state.deadline - Date.parse(state.startedAt) <= sample.timeBudgetMs + 1,
|
|
328
|
+
"host task deadline differs from frozen budget",
|
|
329
|
+
);
|
|
330
|
+
const stageBudget = budget(state.deadline),
|
|
331
|
+
root = fs.realpathSync(state.captureRoot),
|
|
332
|
+
workspace = fs.realpathSync(state.workspace);
|
|
333
|
+
outside(workspace, root);
|
|
334
|
+
outside(workspace, fs.realpathSync(options.reviewRoot));
|
|
335
|
+
const read = captureArtifactReader(root);
|
|
336
|
+
// Require raw host evidence before spending the remaining acceptance budget.
|
|
337
|
+
const protocol = read("protocol.json"),
|
|
338
|
+
ui = read("ui.json");
|
|
339
|
+
const before = loadBaseline(root, state.baseline);
|
|
340
|
+
const after = snapshotVerify01Workspace(workspace, stageBudget, "after-host");
|
|
341
|
+
const changes = diffVerify01Workspace(before, after);
|
|
342
|
+
const unrelatedChanges = changes
|
|
343
|
+
.filter(
|
|
344
|
+
(change) =>
|
|
345
|
+
!reviewed.allowedChangedPaths.includes(change.path) ||
|
|
346
|
+
change.before?.dependency ||
|
|
347
|
+
change.after?.dependency ||
|
|
348
|
+
change.after?.type === "link",
|
|
349
|
+
)
|
|
350
|
+
.map((change) => change.path);
|
|
351
|
+
save(root, "diff.json", changes);
|
|
352
|
+
save(root, "dependency-boundary.json", {
|
|
353
|
+
before: before.dependencyBoundary,
|
|
354
|
+
after: after.dependencyBoundary,
|
|
355
|
+
});
|
|
356
|
+
requireValue(
|
|
357
|
+
unrelatedChanges.length === 0,
|
|
358
|
+
"host task changed unreviewed/dependency paths; full diff preserved",
|
|
359
|
+
);
|
|
360
|
+
const processReceipt = runVerify01ReviewedProcess(
|
|
361
|
+
artifacts.get(reviewed.check.path),
|
|
362
|
+
workspace,
|
|
363
|
+
options.reviewRoot,
|
|
364
|
+
"check",
|
|
365
|
+
stageBudget.remainingMs("check"),
|
|
366
|
+
);
|
|
367
|
+
save(root, "check-process.json", processReceipt);
|
|
368
|
+
requireValue(
|
|
369
|
+
processReceipt.exitCode === 0 &&
|
|
370
|
+
processReceipt.signal === null &&
|
|
371
|
+
processReceipt.error === null,
|
|
372
|
+
"reviewed host check failed to complete; process receipt preserved",
|
|
373
|
+
);
|
|
374
|
+
const verdict = JSON.parse(processReceipt.stdout);
|
|
375
|
+
requireValue(
|
|
376
|
+
typeof verdict.pass === "boolean" && typeof verdict.detail === "string",
|
|
377
|
+
"reviewed host check did not emit a verdict",
|
|
378
|
+
);
|
|
379
|
+
const check = {
|
|
380
|
+
taskId: task.id,
|
|
381
|
+
reviewDigest: state.reviewDigest,
|
|
382
|
+
pass: verdict.pass,
|
|
383
|
+
detail: verdict.detail,
|
|
384
|
+
changedFiles: changes.map((change) => change.path),
|
|
385
|
+
unrelatedChanges,
|
|
386
|
+
process: processReceipt,
|
|
387
|
+
};
|
|
388
|
+
save(root, "check.json", check);
|
|
389
|
+
const observedAt = new Date().toISOString();
|
|
390
|
+
const manifest = {
|
|
391
|
+
schema: "chainlesschain.verify01-host-capture/v1",
|
|
392
|
+
sampleId: state.sampleId,
|
|
393
|
+
planDigest: state.planDigest,
|
|
394
|
+
reviewDigest: state.reviewDigest,
|
|
395
|
+
projectCommit: state.projectCommit,
|
|
396
|
+
sourceCommit: state.sourceCommit,
|
|
397
|
+
entry: state.entry,
|
|
398
|
+
platform: state.platform,
|
|
399
|
+
os: state.os,
|
|
400
|
+
arch: state.arch,
|
|
401
|
+
node: state.node,
|
|
402
|
+
host: state.host,
|
|
403
|
+
runId: state.runId,
|
|
404
|
+
observedAt,
|
|
405
|
+
elapsedMs: Date.parse(observedAt) - Date.parse(state.startedAt),
|
|
406
|
+
retries: options.retries ?? 0,
|
|
407
|
+
manualRepairs: options.manualRepairs ?? 0,
|
|
408
|
+
failureCause: options.failureCause ?? "unknown",
|
|
409
|
+
protocol: { path: "protocol.json", digest: evalDigest(protocol) },
|
|
410
|
+
ui: { path: "ui.json", digest: evalDigest(ui) },
|
|
411
|
+
check: { path: "check.json", digest: evalDigest(read("check.json")) },
|
|
412
|
+
diff: { path: "diff.json", digest: evalDigest(read("diff.json")) },
|
|
413
|
+
...(sample.kind === "first-run" ? { firstRun: options.firstRun } : {}),
|
|
414
|
+
};
|
|
415
|
+
const captureDigest = outcomeDigest(manifest);
|
|
416
|
+
const imported = importVerify01HostCapture(bundle, preparation, {
|
|
417
|
+
manifest,
|
|
418
|
+
expectedManifestDigest: captureDigest,
|
|
419
|
+
readArtifact: read,
|
|
420
|
+
sourceCommit: state.sourceCommit,
|
|
421
|
+
});
|
|
422
|
+
save(root, "capture.json", manifest);
|
|
423
|
+
save(root, "host-import.json", imported);
|
|
424
|
+
return {
|
|
425
|
+
manifestFile: path.join(root, "capture.json"),
|
|
426
|
+
captureDigest,
|
|
427
|
+
imported,
|
|
428
|
+
observationsSavedToFormalPlan: false,
|
|
429
|
+
};
|
|
430
|
+
}
|