@ornexus/neocortex 4.60.63 → 4.60.64
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/dist/release-source.json +1 -1
- package/dist/sbom.cdx.json +23 -23
- package/install.ps1 +1 -1
- package/install.sh +1 -1
- package/package.json +7 -2
- package/packages/client/dist/cli.js +8 -3
- package/packages/client/dist/commands/activate.js +8 -8
- package/packages/client/dist/commands/architecture-memory-terminal.js +4 -2
- package/packages/client/dist/commands/architecture-non-ui-continuation.d.ts +3 -0
- package/packages/client/dist/commands/architecture-non-ui-continuation.js +1 -0
- package/packages/client/dist/commands/invoke.d.ts +19 -16
- package/packages/client/dist/commands/invoke.js +85 -80
- package/packages/client/dist/commands/planning-generation.js +1 -1
- package/packages/client/dist/commands/planning-memory.d.ts +1 -0
- package/packages/client/dist/commands/planning-memory.js +1 -0
- package/packages/client/dist/commands/private-session.d.ts +1 -0
- package/packages/client/dist/commands/private-session.js +1 -0
- package/packages/client/dist/commands/qa-control.d.ts +4 -0
- package/packages/client/dist/commands/qa-control.js +1 -0
- package/packages/client/dist/commands/qa-scan-browser-launch.d.ts +8 -0
- package/packages/client/dist/commands/qa-scan-browser-launch.js +1 -0
- package/packages/client/dist/commands/qa-scan-browser-route.d.ts +3 -0
- package/packages/client/dist/commands/qa-scan-browser-route.js +1 -0
- package/packages/client/dist/commands/qa-scan-capture.d.ts +43 -0
- package/packages/client/dist/commands/qa-scan-capture.js +5 -5
- package/packages/client/dist/commands/qa-scan-discovery.d.ts +7 -0
- package/packages/client/dist/commands/qa-scan-discovery.js +3 -3
- package/packages/client/dist/commands/qa-scan-review.d.ts +8 -1
- package/packages/client/dist/commands/qa-scan-review.js +5 -5
- package/packages/client/dist/commands/qa-synthetic-backend-capture.d.ts +62 -0
- package/packages/client/dist/commands/qa-synthetic-backend-capture.js +1 -0
- package/packages/client/dist/commands/qa-synthetic-backend-review.d.ts +104 -0
- package/packages/client/dist/commands/qa-synthetic-backend-review.js +1 -0
- package/packages/client/dist/commands/qa-synthetic-backend.d.ts +52 -0
- package/packages/client/dist/commands/qa-synthetic-backend.js +7 -0
- package/packages/client/dist/commands/qa-synthetic-broker-port.d.ts +30 -0
- package/packages/client/dist/commands/qa-synthetic-broker-port.js +1 -0
- package/packages/client/dist/commands/qa-synthetic-browser.d.ts +1 -0
- package/packages/client/dist/commands/qa-synthetic-browser.js +1 -0
- package/packages/client/dist/commands/refactor-characterization.d.ts +12 -3
- package/packages/client/dist/commands/refactor-characterization.js +21 -12
- package/packages/client/dist/commands/refactor-control.d.ts +17 -0
- package/packages/client/dist/commands/refactor-control.js +3 -0
- package/packages/client/dist/commands/refactor-cpp-assertions.d.ts +4 -0
- package/packages/client/dist/commands/refactor-cpp-assertions.js +3 -0
- package/packages/client/dist/commands/refactor-review.d.ts +13 -0
- package/packages/client/dist/commands/refactor-review.js +6 -5
- package/packages/client/dist/commands/refactor-root.d.ts +165 -1
- package/packages/client/dist/commands/refactor-root.js +12 -7
- package/packages/client/dist/commands/refresh-memory.d.ts +1 -0
- package/packages/client/dist/commands/refresh-memory.js +3 -3
- package/packages/client/dist/commands/shared-architecture-non-ui-contract.d.ts +19 -0
- package/packages/client/dist/commands/shared-architecture-non-ui-contract.js +1 -0
- package/packages/client/dist/errors/error-messages.js +1 -1
- package/packages/client/dist/git/direct-yolo-checkpoint.js +4 -4
- package/packages/client/dist/git/git-lifecycle-store.js +7 -7
- package/packages/client/dist/license/license-client.d.ts +3 -1
- package/packages/client/dist/license/license-client.js +1 -1
- package/packages/client/dist/memory/project-memory-path-scope.d.ts +4 -0
- package/packages/client/dist/memory/project-memory-path-scope.js +1 -0
- package/packages/client/dist/memory/project-memory-writer.d.ts +4 -1
- package/packages/client/dist/memory/project-memory-writer.js +16 -16
- package/packages/client/dist/private-execution/clean-baseline.d.ts +6 -0
- package/packages/client/dist/private-execution/clean-baseline.js +2 -2
- package/packages/client/dist/private-execution/codex-executor.d.ts +48 -4
- package/packages/client/dist/private-execution/codex-executor.js +9 -2
- package/packages/client/dist/private-execution/codex-host-runtime.d.ts +10 -0
- package/packages/client/dist/private-execution/codex-host-runtime.js +1 -0
- package/packages/client/dist/private-execution/codex-lifecycle-guard.d.ts +4 -0
- package/packages/client/dist/private-execution/codex-lifecycle-guard.js +1 -0
- package/packages/client/dist/private-execution/codex-scoped-permissions.d.ts +8 -0
- package/packages/client/dist/private-execution/codex-scoped-permissions.js +1 -0
- package/packages/client/dist/private-execution/delivery.d.ts +18 -1
- package/packages/client/dist/private-execution/delivery.js +11 -3
- package/packages/client/dist/private-execution/diagnosis-root-review.d.ts +112 -0
- package/packages/client/dist/private-execution/diagnosis-root-review.js +2 -0
- package/packages/client/dist/private-execution/frozen-handoff.d.ts +2 -0
- package/packages/client/dist/private-execution/frozen-handoff.js +7 -0
- package/packages/client/dist/private-execution/implementation-validation.d.ts +24 -0
- package/packages/client/dist/private-execution/implementation-validation.js +2 -0
- package/packages/client/dist/private-execution/isolated-admission.d.ts +11 -7
- package/packages/client/dist/private-execution/isolated-admission.js +17 -10
- package/packages/client/dist/private-execution/isolated-session.d.ts +68 -0
- package/packages/client/dist/private-execution/isolated-session.js +5 -2
- package/packages/client/dist/private-execution/pact-test-source.d.ts +1 -1
- package/packages/client/dist/private-execution/pact-test-source.js +1 -1
- package/packages/client/dist/private-execution/planning-diagnosis-checkpoint.d.ts +2 -0
- package/packages/client/dist/private-execution/planning-diagnosis-checkpoint.js +5 -5
- package/packages/client/dist/private-execution/planning-generation-checkpoint.d.ts +13 -0
- package/packages/client/dist/private-execution/planning-generation-checkpoint.js +4 -3
- package/packages/client/dist/private-execution/planning-memory-checkpoint.d.ts +32 -0
- package/packages/client/dist/private-execution/planning-memory-checkpoint.js +3 -0
- package/packages/client/dist/private-execution/planning-research-checkpoint.js +4 -4
- package/packages/client/dist/private-execution/root-checkpoint.js +1 -1
- package/packages/client/dist/private-execution/root-memory-git-evidence.d.ts +30 -0
- package/packages/client/dist/private-execution/root-memory-git-evidence.js +3 -0
- package/packages/client/dist/private-execution/root-memory-recovery.d.ts +16 -0
- package/packages/client/dist/private-execution/root-memory-recovery.js +1 -0
- package/packages/client/dist/private-execution/root-memory-request.d.ts +28 -0
- package/packages/client/dist/private-execution/root-memory-request.js +1 -0
- package/packages/client/dist/private-execution/root-memory-scope.d.ts +28 -0
- package/packages/client/dist/private-execution/root-memory-scope.js +1 -0
- package/packages/client/dist/private-execution/root-memory-writer.d.ts +22 -0
- package/packages/client/dist/private-execution/root-memory-writer.js +1 -0
- package/packages/client/dist/private-execution/session-lease.d.ts +19 -0
- package/packages/client/dist/private-execution/session-lease.js +1 -0
- package/packages/client/dist/private-execution/ux-source-validation.js +1 -1
- package/packages/client/dist/runner-cli.js +0 -0
- package/packages/client/dist/yolo/change-evidence-collector.d.ts +2 -2
- package/packages/client/dist/yolo/change-evidence-collector.js +1 -1
- package/packages/client/dist/yolo/spec-envelope-collector.js +2 -2
- package/packages/shared/dist/invocation/index.js +4 -2
- package/packages/shared/dist/invocation/packed-invoke.d.ts +12 -0
- package/packages/shared/dist/invocation/packed-invoke.js +58 -0
- package/packages/shared/dist/invocation/packed-invoke.test.d.ts +1 -0
- package/packages/shared/dist/invocation/packed-invoke.test.js +21 -0
- package/packages/shared/dist/planning/diagnosis-state.js +5 -2
- package/packages/shared/dist/private-qa-structural-admission.js +14 -0
- package/packages/shared/dist/private-yolo-predecessor-decision.js +32 -0
- package/packages/shared/dist/project-memory-targets.js +243 -0
- package/packages/shared/dist/project-validation-commands.js +96 -0
- package/packages/shared/dist/yolo/change-evidence.js +35 -0
- package/packages/shared/dist/yoloop/branch-unit.js +10 -1
- package/packages/shared/dist/yoloop/root-memory-effect.js +57 -0
- package/targets-stubs/antigravity/gemini.md +1 -1
- package/targets-stubs/antigravity/skill/SKILL.md +1 -1
- package/targets-stubs/claude-code/neocortex-root.agent.yaml +1 -1
- package/targets-stubs/claude-code/neocortex-root.md +2 -2
- package/targets-stubs/claude-code/neocortex.agent.yaml +1 -1
- package/targets-stubs/claude-code/neocortex.md +2 -2
- package/targets-stubs/codex/AGENTS.md +1 -1
- package/targets-stubs/cursor/agent.md +2 -2
- package/targets-stubs/gemini-cli/agent.md +2 -2
- package/targets-stubs/opencode/neocortex-root.md +1 -1
- package/targets-stubs/vscode/neocortex.agent.md +2 -2
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { captureSyntheticBackendScenario } from './qa-synthetic-backend-capture.js';
|
|
2
|
+
type Observation = Omit<Awaited<ReturnType<typeof captureSyntheticBackendScenario>>, 'observationSha256'>;
|
|
3
|
+
/** Source and all artifacts are recomputed; an arbitrary JSON/200 response is no proof. */
|
|
4
|
+
export declare function readSyntheticBackendObservation(root: string, surface: string, targetUrl: string, digest: string): {
|
|
5
|
+
receipt: Observation;
|
|
6
|
+
observationSha256: string;
|
|
7
|
+
rejectedKinds: ("performance" | "accessibility" | "responsive" | "visual" | "responsive-tablet" | "responsive-desktop" | "interaction" | "console-network")[];
|
|
8
|
+
};
|
|
9
|
+
export interface SyntheticBackendRootReport {
|
|
10
|
+
readonly schemaVersion: 3;
|
|
11
|
+
readonly kind: 'root-qa-synthetic-backend-report';
|
|
12
|
+
readonly observationSha256: string;
|
|
13
|
+
readonly verdict: 'approved' | 'issues-found';
|
|
14
|
+
readonly issues: readonly {
|
|
15
|
+
readonly severity: 'critical' | 'high' | 'medium' | 'low';
|
|
16
|
+
readonly evidenceArtifactId: string;
|
|
17
|
+
readonly summary: string;
|
|
18
|
+
}[];
|
|
19
|
+
}
|
|
20
|
+
export declare function acceptSyntheticBackendRootReview(options: {
|
|
21
|
+
readonly projectRoot: string;
|
|
22
|
+
readonly surface: string;
|
|
23
|
+
readonly targetUrl: string;
|
|
24
|
+
readonly report: unknown;
|
|
25
|
+
readonly authorizeRootReview: boolean;
|
|
26
|
+
}): {
|
|
27
|
+
schemaVersion: 3;
|
|
28
|
+
kind: "root-qa-synthetic-backend-review";
|
|
29
|
+
sourceHead: string;
|
|
30
|
+
planSha256: string;
|
|
31
|
+
observationSha256: string;
|
|
32
|
+
reviewSha256: string;
|
|
33
|
+
verdict: "approved" | "issues-found";
|
|
34
|
+
evidenceCount: 8;
|
|
35
|
+
issueCount: number;
|
|
36
|
+
qaAccepted: boolean;
|
|
37
|
+
checkpointAccepted: false;
|
|
38
|
+
workflowContinuationAuthorized: false;
|
|
39
|
+
};
|
|
40
|
+
export declare function readSyntheticBackendReviewedObservation(root: string, surface: string, targetUrl: string, observationSha256: string): {
|
|
41
|
+
report: SyntheticBackendRootReport;
|
|
42
|
+
receipt: {
|
|
43
|
+
schemaVersion: 3;
|
|
44
|
+
kind: "root-qa-synthetic-backend-review";
|
|
45
|
+
sourceHead: string;
|
|
46
|
+
planSha256: string;
|
|
47
|
+
observationSha256: string;
|
|
48
|
+
reviewSha256: string;
|
|
49
|
+
verdict: "approved" | "issues-found";
|
|
50
|
+
evidenceCount: 8;
|
|
51
|
+
issueCount: number;
|
|
52
|
+
qaAccepted: boolean;
|
|
53
|
+
checkpointAccepted: false;
|
|
54
|
+
workflowContinuationAuthorized: false;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
export declare function readSyntheticBackendRootReview(root: string, surface: string, targetUrl: string, digest: string): {
|
|
58
|
+
report: SyntheticBackendRootReport;
|
|
59
|
+
receipt: {
|
|
60
|
+
schemaVersion: 3;
|
|
61
|
+
kind: "root-qa-synthetic-backend-review";
|
|
62
|
+
sourceHead: string;
|
|
63
|
+
planSha256: string;
|
|
64
|
+
observationSha256: string;
|
|
65
|
+
reviewSha256: string;
|
|
66
|
+
verdict: "approved" | "issues-found";
|
|
67
|
+
evidenceCount: 8;
|
|
68
|
+
issueCount: number;
|
|
69
|
+
qaAccepted: boolean;
|
|
70
|
+
checkpointAccepted: false;
|
|
71
|
+
workflowContinuationAuthorized: false;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
export interface SyntheticBackendPhaseTarget {
|
|
75
|
+
readonly surface: string;
|
|
76
|
+
readonly targetUrl: string;
|
|
77
|
+
readonly observationSha256: string;
|
|
78
|
+
readonly reviewSha256: string;
|
|
79
|
+
}
|
|
80
|
+
export declare function acceptSyntheticBackendDiscoveredPhase(root: string, discoverySha256: string, targets: readonly SyntheticBackendPhaseTarget[]): {
|
|
81
|
+
schemaVersion: 3;
|
|
82
|
+
kind: "root-qa-synthetic-backend-discovered-phase";
|
|
83
|
+
sourceHead: string;
|
|
84
|
+
discoverySha256: string;
|
|
85
|
+
aggregateSha256: string;
|
|
86
|
+
surfaceCount: number;
|
|
87
|
+
qaAccepted: boolean;
|
|
88
|
+
issueCount: number;
|
|
89
|
+
workflowContinuationAuthorized: false;
|
|
90
|
+
checkpointAccepted: false;
|
|
91
|
+
};
|
|
92
|
+
export declare function readSyntheticBackendDiscoveredPhase(root: string, discoverySha256: string, targets: readonly SyntheticBackendPhaseTarget[]): {
|
|
93
|
+
schemaVersion: 3;
|
|
94
|
+
kind: "root-qa-synthetic-backend-discovered-phase";
|
|
95
|
+
sourceHead: string;
|
|
96
|
+
discoverySha256: string;
|
|
97
|
+
aggregateSha256: string;
|
|
98
|
+
surfaceCount: number;
|
|
99
|
+
qaAccepted: boolean;
|
|
100
|
+
issueCount: number;
|
|
101
|
+
workflowContinuationAuthorized: false;
|
|
102
|
+
checkpointAccepted: false;
|
|
103
|
+
};
|
|
104
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createHash as B}from"node:crypto";import{closeSync as v,constants as l,fstatSync as R,fsyncSync as I,openSync as w,readFileSync as C,writeFileSync as $}from"node:fs";import{join as q}from"node:path";import{planRootQaScan as j,rootQaScanEvidenceDirectory as J,validateRootQaScanArtifact as M}from"./qa-scan-review.js";import{validateRootQaScanScenario as z,scenarioRequirementDigest as L}from"./qa-scan-capture.js";import{validateSyntheticBackendContract as _}from"./qa-synthetic-backend.js";import{readRootQaScanDiscovery as E,readRootQaScanDiscoveryTargets as F}from"./qa-scan-discovery.js";const p=/^[a-f0-9]{64}$/,x=["visual","responsive","responsive-tablet","responsive-desktop","accessibility","interaction","console-network","performance"],T={visual:"browser-screenshot",responsive:"browser-screenshot","responsive-tablet":"browser-screenshot","responsive-desktop":"browser-screenshot",accessibility:"axe-scan",interaction:"browser-interaction","console-network":"console-capture",performance:"performance-trace"},m=t=>B("sha256").update(t).digest("hex");function s(){throw new Error("qa-synthetic-backend-review-unverified")}function h(t,i){return!!t&&typeof t=="object"&&!Array.isArray(t)&&Object.keys(t).sort().join(",")===[...i].sort().join(",")}function g(t,i,o){const n=w(q(J(t),i),l.O_RDONLY|l.O_NOFOLLOW);try{const a=R(n);(!a.isFile()||a.nlink!==1||a.uid!==process.getuid?.()||a.mode&63||a.size<1||a.size>o)&&s();const d=C(n),e=R(n);return(d.length!==a.size||e.size!==a.size||e.mtimeMs!==a.mtimeMs||e.ctimeMs!==a.ctimeMs)&&s(),d}finally{v(n)}}function y(t){const i=new TextDecoder("utf-8",{fatal:!0}).decode(t),o=JSON.parse(i);return(!o||typeof o!="object"||Array.isArray(o)||JSON.stringify(o)!==i)&&s(),o}function A(t,i,o){const n=J(t);let a;try{a=w(q(n,i),l.O_WRONLY|l.O_CREAT|l.O_EXCL|l.O_NOFOLLOW,384)}catch(e){(e.code!=="EEXIST"||g(t,i,131072).toString("utf8")!==o)&&s();return}try{$(a,o),I(a)}finally{v(a)}const d=w(n,l.O_RDONLY|l.O_DIRECTORY|l.O_NOFOLLOW);try{I(d)}finally{v(d)}}function W(t,i,o,n){try{p.test(n)||s();const a=j(t,i,o),d=g(t,`synthetic-backend-${n}.json`,131072);m(d)!==n&&s();const e=y(d);if((!h(e,["schemaVersion","kind","sourceHead","planSha256","surface","targetSha256","generation","scenarioSha256","backendContractSha256","requirementSourceSha256","requirementIds","capturedAt","checks","scenario","grantId","evidenceCount","observations","initialRequests","allowedActionRequests","deniedRequests","backend","sandboxNetwork","browserNetwork","browserHostWorkspaceMounted","browserVersion","qaAccepted","checkpointAccepted","workflowContinuationAuthorized",..."producerJob"in e?["producerJob"]:[]])||e.schemaVersion!==3||e.kind!=="root-qa-synthetic-backend-observation"||e.sourceHead!==a.sourceHead||e.planSha256!==a.planSha256||e.surface!==i||e.targetSha256!==a.targetSha256||typeof e.generation!="string"||!p.test(e.generation)||typeof e.scenarioSha256!="string"||!p.test(e.scenarioSha256)||typeof e.grantId!="string"||!/^[a-f0-9]{8}-[a-f0-9-]{27}$/.test(e.grantId)||typeof e.capturedAt!="string"||!Number.isFinite(Date.parse(e.capturedAt))||new Date(e.capturedAt).toISOString()!==e.capturedAt||Date.parse(e.capturedAt)>Date.now()||Date.now()-Date.parse(e.capturedAt)>36e5||e.evidenceCount!==8||!Array.isArray(e.observations)||e.observations.length!==8||e.sandboxNetwork!=="none"||!["unshared","docker-none"].includes(String(e.browserNetwork))||e.browserHostWorkspaceMounted!==!1||typeof e.browserVersion!="string"||!/^[0-9]+(?:\.[0-9]+){2,3}$/.test(e.browserVersion)||!Number.isSafeInteger(e.allowedActionRequests)||Number(e.allowedActionRequests)<1||Number(e.allowedActionRequests)>64||!Number.isSafeInteger(e.initialRequests)||Number(e.initialRequests)<1||Number(e.initialRequests)>64||e.deniedRequests!==0||e.qaAccepted!==!1||e.checkpointAccepted!==!1||e.workflowContinuationAuthorized!==!1)&&s(),e.browserNetwork==="docker-none"){const r=e.producerJob;(!h(r,["imageId","containerId","jobBindingSha256"])||typeof r.imageId!="string"||!/^sha256:[a-f0-9]{64}$/.test(r.imageId)||typeof r.containerId!="string"||!p.test(r.containerId)||typeof r.jobBindingSha256!="string"||!p.test(r.jobBindingSha256))&&s();const f=y(g(t,`producer-job-${r.jobBindingSha256}-${r.containerId}.json`,4096));(!h(f,["schemaVersion","kind","containerId","imageId","jobBindingSha256","sourceHead","requestSha256","phase","bindingSha256","network","producerDockerSocketMounted","createdVerified","completedVerified"])||f.schemaVersion!==1||f.kind!=="root-synthetic-producer-job-attestation"||f.containerId!==r.containerId||f.imageId!==r.imageId||f.jobBindingSha256!==r.jobBindingSha256||f.sourceHead!==a.sourceHead||typeof f.requestSha256!="string"||!p.test(f.requestSha256)||typeof f.bindingSha256!="string"||!p.test(f.bindingSha256)||f.phase!=="completed"||f.network!=="none"||f.producerDockerSocketMounted!==!1||f.createdVerified!==!0||f.completedVerified!==!0)&&s()}else"producerJob"in e&&s();const c=z(e.scenario);(m(JSON.stringify(c))!==e.scenarioSha256||L(t,c)!==e.requirementSourceSha256||JSON.stringify(c.requirementIds)!==JSON.stringify(e.requirementIds)||JSON.stringify(e.checks)!==JSON.stringify(c.checks.map(r=>({id:`functional-${r.id}`,passed:!0}))))&&s();const u=y(g(t,`backend-grant-${e.grantId}.json`,32768));(!h(u,["schemaVersion","contract","planSha256","sourceHead","surface","targetUrl","expiresAt"])||u.schemaVersion!==1||u.planSha256!==a.planSha256||u.sourceHead!==a.sourceHead||u.surface!==i||u.targetUrl!==o||typeof u.expiresAt!="string"||!Number.isFinite(Date.parse(u.expiresAt)))&&s();const b=_(u.contract);(b.generation!==e.generation||b.scenarioSha256!==e.scenarioSha256||m(JSON.stringify(b))!==e.backendContractSha256||Date.parse(e.capturedAt)>Date.parse(u.expiresAt)||Date.parse(e.capturedAt)<Date.parse(u.expiresAt)-b.durationMs||g(t,`backend-consumed-${e.grantId}`,16).toString("utf8")!=="consumed")&&s(),(!Array.isArray(e.backend)||e.backend.length<2||e.backend.length>b.maxRequests)&&s();for(const r of e.backend)(!h(r,["path","method","status","responseSha256"])||!b.routes.some(f=>f.path===r.path&&f.method===r.method)||!Number.isSafeInteger(r.status)||Number(r.status)<200||Number(r.status)>599||Number(r.status)>=300&&Number(r.status)<400||typeof r.responseSha256!="string"||!p.test(r.responseSha256))&&s();Number(e.allowedActionRequests)+Number(e.initialRequests)!==e.backend.length&&s();const k=new Map,O=new Set;for(const r of e.observations){(!h(r,["kind","artifactId","sha256","captureMethod","capturedAt","rationale"])||!x.includes(r.kind)||k.has(r.kind)||typeof r.artifactId!="string"||!/^[a-z][a-z0-9-]{0,63}\.(?:png|json)$/.test(r.artifactId)||O.has(r.artifactId)||r.captureMethod!==T[r.kind]||typeof r.sha256!="string"||!p.test(r.sha256)||r.capturedAt!==e.capturedAt||typeof r.rationale!="string"||r.rationale.length<30||r.rationale.length>500||/[\x00-\x1f\x7f]/.test(r.rationale))&&s();const f=g(t,r.artifactId,8*1024*1024);(m(f)!==r.sha256||r.captureMethod==="browser-screenshot"!==r.artifactId.endsWith(".png"))&&s(),O.add(r.artifactId),k.set(r.kind,f)}const S=y(k.get("interaction"));(!h(S,["schemaVersion","syntheticTarget","allowedActionRequests","deniedRequests","generation","scenarioSha256","checks","backend"])||S.schemaVersion!==3||S.syntheticTarget!==!0||S.allowedActionRequests!==e.allowedActionRequests||S.deniedRequests!==0||S.generation!==e.generation||S.scenarioSha256!==e.scenarioSha256||JSON.stringify(S.checks)!==JSON.stringify(e.checks)||JSON.stringify(S.backend)!==JSON.stringify(e.backend))&&s(),j(t,i,o).planSha256!==a.planSha256&&s();const V=x.filter(r=>r!=="interaction"&&!M(r,k.get(r)));return{receipt:e,observationSha256:n,rejectedKinds:V}}catch{return s()}}function N(t,i,o,n){(!h(n,["schemaVersion","kind","observationSha256","verdict","issues"])||n.schemaVersion!==3||n.kind!=="root-qa-synthetic-backend-report"||typeof n.observationSha256!="string"||!["approved","issues-found"].includes(String(n.verdict))||!Array.isArray(n.issues)||n.issues.length>128)&&s();const a=W(t,i,o,n.observationSha256);(n.verdict==="approved"&&(n.issues.length||a.rejectedKinds.length)||n.verdict==="issues-found"&&!n.issues.length)&&s();const d=new Set(a.receipt.observations.map(c=>c.artifactId));for(const c of n.issues)(!h(c,["severity","evidenceArtifactId","summary"])||!["critical","high","medium","low"].includes(String(c.severity))||!d.has(String(c.evidenceArtifactId))||typeof c.summary!="string"||c.summary.length<20||c.summary.length>500||/[\x00-\x1f\x7f]/.test(c.summary))&&s();const e=n;return{report:e,receipt:{schemaVersion:3,kind:"root-qa-synthetic-backend-review",sourceHead:a.receipt.sourceHead,planSha256:a.receipt.planSha256,observationSha256:a.observationSha256,reviewSha256:m(JSON.stringify(e)),verdict:e.verdict,evidenceCount:8,issueCount:e.issues.length,qaAccepted:e.verdict==="approved",checkpointAccepted:!1,workflowContinuationAuthorized:!1}}}function ee(t){try{t.authorizeRootReview!==!0&&s();const i=N(t.projectRoot,t.surface,t.targetUrl,t.report),o=JSON.stringify(i);A(t.projectRoot,`backend-review-${i.receipt.reviewSha256}.json`,o),JSON.stringify(N(t.projectRoot,t.surface,t.targetUrl,i.report))!==o&&s();const n=JSON.stringify({observationSha256:i.receipt.observationSha256,reviewSha256:i.receipt.reviewSha256});return A(t.projectRoot,`backend-reviewed-${i.receipt.observationSha256}.json`,n),i.receipt}catch{return s()}}function te(t,i,o,n){try{p.test(n)||s();const a=y(g(t,`backend-reviewed-${n}.json`,4096));(!h(a,["observationSha256","reviewSha256"])||a.observationSha256!==n||typeof a.reviewSha256!="string")&&s();const d=D(t,i,o,a.reviewSha256);return d.receipt.observationSha256!==n&&s(),d}catch{return s()}}function D(t,i,o,n){try{p.test(n)||s();const a=y(g(t,`backend-review-${n}.json`,131072));h(a,["report","receipt"])||s();const d=N(t,i,o,a.report);return(d.receipt.reviewSha256!==n||JSON.stringify(d.receipt)!==JSON.stringify(a.receipt))&&s(),d}catch{return s()}}function H(t,i,o){(!Array.isArray(o)||!o.length||o.length>32)&&s();const n=E(t,i),a=F(t,i),d=new Set,e=o.map(c=>{(!h(c,["surface","targetUrl","observationSha256","reviewSha256"])||typeof c.surface!="string"||d.has(c.surface)||typeof c.targetUrl!="string"||typeof c.observationSha256!="string"||typeof c.reviewSha256!="string")&&s(),d.add(c.surface);const u=D(t,c.surface,c.targetUrl,c.reviewSha256);return(u.receipt.sourceHead!==n.sourceHead||u.receipt.observationSha256!==c.observationSha256)&&s(),u.receipt});return JSON.stringify(o.map(c=>c.targetUrl).sort((c,u)=>Buffer.from(c).compare(Buffer.from(u))))!==JSON.stringify(a)&&s(),{schemaVersion:3,kind:"root-qa-synthetic-backend-discovered-phase",sourceHead:n.sourceHead,discoverySha256:i,aggregateSha256:m(JSON.stringify({discoverySha256:i,targets:o,receipts:e})),surfaceCount:o.length,qaAccepted:e.every(c=>c.qaAccepted),issueCount:e.reduce((c,u)=>c+u.issueCount,0),workflowContinuationAuthorized:!1,checkpointAccepted:!1}}function re(t,i,o){try{const n=H(t,i,o),a=JSON.stringify(n),d=`backend-phase-${n.aggregateSha256}.json`;return A(t,d,a),Q(t,i,o)}catch{return s()}}function Q(t,i,o){try{const n=H(t,i,o),a=y(g(t,`backend-phase-${n.aggregateSha256}.json`,4096));return JSON.stringify(a)!==JSON.stringify(n)&&s(),n}catch{return s()}}export{re as acceptSyntheticBackendDiscoveredPhase,ee as acceptSyntheticBackendRootReview,Q as readSyntheticBackendDiscoveredPhase,W as readSyntheticBackendObservation,te as readSyntheticBackendReviewedObservation,D as readSyntheticBackendRootReview};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export interface SyntheticBackendContract {
|
|
2
|
+
readonly generation: string;
|
|
3
|
+
readonly scenarioSha256: string;
|
|
4
|
+
readonly containerId: string;
|
|
5
|
+
readonly imageId: string;
|
|
6
|
+
readonly programSha256: string;
|
|
7
|
+
readonly port: number;
|
|
8
|
+
readonly routes: readonly {
|
|
9
|
+
readonly path: string;
|
|
10
|
+
readonly method: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
11
|
+
readonly fields: Readonly<Record<string, readonly string[]>>;
|
|
12
|
+
}[];
|
|
13
|
+
readonly maxRequests: number;
|
|
14
|
+
readonly maxBodyBytes: number;
|
|
15
|
+
readonly maxResponseBytes: number;
|
|
16
|
+
readonly durationMs: number;
|
|
17
|
+
}
|
|
18
|
+
export declare function validateSyntheticBackendContract(v: unknown): SyntheticBackendContract;
|
|
19
|
+
export declare function verifySyntheticBackendSandbox(contract: SyntheticBackendContract): Promise<void>;
|
|
20
|
+
/** Separate SDK command. Registration requires explicit root consent; capture
|
|
21
|
+
* consumes that source-bound grant and cannot emit a QA/checkpoint approval. */
|
|
22
|
+
export declare function syntheticBackendCliHandler(args: readonly string[]): Promise<number>;
|
|
23
|
+
/** Host operator consent is required; no DOM marker or scenario JSON grants network. */
|
|
24
|
+
export declare function registerSyntheticBackendGrant(options: {
|
|
25
|
+
readonly projectRoot: string;
|
|
26
|
+
readonly surface: string;
|
|
27
|
+
readonly targetUrl: string;
|
|
28
|
+
readonly contract: SyntheticBackendContract;
|
|
29
|
+
readonly authorizeSyntheticBackend: boolean;
|
|
30
|
+
}): Promise<string>;
|
|
31
|
+
export declare function openSyntheticBackendSession(options: {
|
|
32
|
+
readonly projectRoot: string;
|
|
33
|
+
readonly surface: string;
|
|
34
|
+
readonly targetUrl: string;
|
|
35
|
+
readonly grantId: string;
|
|
36
|
+
readonly scenarioSha256: string;
|
|
37
|
+
readonly generation: string;
|
|
38
|
+
}): Promise<{
|
|
39
|
+
request: (url: string, method: string, body: string | null, headers: Readonly<Record<string, string>>) => Promise<{
|
|
40
|
+
status: number;
|
|
41
|
+
body: Buffer;
|
|
42
|
+
contentType: string;
|
|
43
|
+
}>;
|
|
44
|
+
verify: () => Promise<void>;
|
|
45
|
+
contractSha256: string;
|
|
46
|
+
observations: () => readonly {
|
|
47
|
+
path: string;
|
|
48
|
+
method: string;
|
|
49
|
+
status: number;
|
|
50
|
+
responseSha256: string;
|
|
51
|
+
}[];
|
|
52
|
+
}>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{spawn as F}from"node:child_process";import{createHash as H,randomUUID as P}from"node:crypto";import{closeSync as b,constants as u,fstatSync as j,fsyncSync as q,openSync as w,readFileSync as D,writeFileSync as T}from"node:fs";import{join as A}from"node:path";import{planRootQaScan as z,rootQaScanEvidenceDirectory as C}from"./qa-scan-review.js";const B=/^[a-f0-9]{64}$/,I=e=>H("sha256").update(e).digest("hex");function s(e){throw new Error(`qa-synthetic-backend-${e}`)}const k=(e,r)=>!!e&&typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).sort().join(",")===[...r].sort().join(","),R=(e,r)=>Number.isSafeInteger(e)&&Number(e)>0&&Number(e)<=r;function _(e){(!k(e,["generation","scenarioSha256","containerId","imageId","programSha256","port","routes","maxRequests","maxBodyBytes","maxResponseBytes","durationMs"])||typeof e.generation!="string"||!B.test(e.generation)||typeof e.scenarioSha256!="string"||!B.test(e.scenarioSha256)||typeof e.containerId!="string"||!B.test(e.containerId)||typeof e.imageId!="string"||!/^sha256:[a-f0-9]{64}$/.test(e.imageId)||typeof e.programSha256!="string"||!B.test(e.programSha256)||!R(e.port,65535)||!R(e.maxRequests,64)||!R(e.maxBodyBytes,16384)||!R(e.maxResponseBytes,1048576)||!R(e.durationMs,3e4)||!Array.isArray(e.routes)||!e.routes.length||e.routes.length>32)&&s("contract-invalid");const r=new Set;for(const t of e.routes){(!k(t,["path","method","fields"])||typeof t.path!="string"||!/^\/[a-zA-Z0-9/_-]*$/.test(t.path)||t.path.length>256||!["GET","POST","PUT","DELETE"].includes(String(t.method))||!t.fields||typeof t.fields!="object"||Array.isArray(t.fields)||Object.keys(t.fields).length>16||t.method==="GET"&&Object.keys(t.fields).length)&&s("contract-invalid");for(const[a,i]of Object.entries(t.fields))(!/^[a-z][a-z0-9_]{0,31}$/.test(a)||["constructor","prototype","__proto__"].includes(a)||!Array.isArray(i)||!i.length||i.length>32||i.some(d=>typeof d!="string"||d.length>256||/[\x00-\x1f\x7f]/.test(d)))&&s("contract-invalid");const n=`${t.method} ${t.path}`;r.has(n)&&s("contract-invalid"),r.add(n)}return Buffer.byteLength(JSON.stringify(e))>24576&&s("contract-invalid"),JSON.parse(JSON.stringify(e))}async function J(e,r="",t=131072,n=5e3){return new Promise((a,i)=>{if(process.platform!=="linux"){i(new Error("qa-synthetic-backend-host-unsupported"));return}const d=F("docker",["--host","unix:///var/run/docker.sock",...e],{stdio:["pipe","pipe","pipe"]}),p=[];let g=0,S=!1;const f=c=>{S||(S=!0,clearTimeout(o),c?(d.kill("SIGKILL"),i(c)):a(Buffer.concat(p).toString("utf8")))},o=setTimeout(()=>f(new Error("qa-synthetic-backend-transport-timeout")),n);d.stdout.on("data",c=>{g+=c.length,g>t?f(new Error("qa-synthetic-backend-response-limit")):p.push(c)}),d.stderr.resume(),d.on("error",()=>f(new Error("qa-synthetic-backend-transport-unavailable"))),d.stdin.on("error",()=>f(new Error("qa-synthetic-backend-transport-unavailable"))),d.on("close",c=>f(c===0?void 0:new Error("qa-synthetic-backend-transport-failed"))),d.stdin.end(r)})}async function N(e){let r;try{const a=JSON.parse(await J(["inspect",e.containerId]));(!Array.isArray(a)||a.length!==1)&&s("sandbox-unverified"),r=a[0]}catch{return s("sandbox-unverified")}const t=r.HostConfig,n=r.Config;(r.Id!==e.containerId||r.Image!==e.imageId||!r.State?.Running||!t||!n||t.NetworkMode!=="none"||t.Privileged!==!1||t.ReadonlyRootfs!==!0||!Array.isArray(t.CapDrop)||!t.CapDrop.includes("ALL")||(t.CapAdd?.length??0)!==0||!t.SecurityOpt?.includes("no-new-privileges")||!/^[1-9][0-9]*(?::[1-9][0-9]*)?$/.test(n.User)||(r.Mounts?.length??0)!==0||Object.keys(t.PortBindings??{}).length!==0||t.PublishAllPorts||t.PidMode||t.IpcMode!=="private"||t.Devices?.length||t.Binds?.length||t.VolumesFrom?.length||t.ExtraHosts?.length||t.Memory<=0||t.Memory>512*1024*1024||t.PidsLimit<=0||t.PidsLimit>128||t.NanoCpus<=0||t.NanoCpus>1e9||t.DeviceRequests?.length||t.SecurityOpt.length!==1||t.UsernsMode==="host"||t.CgroupnsMode==="host"||Object.keys(t.Tmpfs??{}).some(a=>a!=="/tmp")||n.Labels?.["neocortex.qa.synthetic-generation"]!==e.generation||!Array.isArray(n.Cmd)||!n.Cmd.every(a=>typeof a=="string")||n.Entrypoint!==null&&(!Array.isArray(n.Entrypoint)||!n.Entrypoint.every(a=>typeof a=="string"))||I(JSON.stringify({entrypoint:n.Entrypoint,command:n.Cmd}))!==e.programSha256||(n.Env??[]).some(a=>!/^(PATH|NODE_VERSION|YARN_VERSION|HOME)=/.test(a)))&&s("sandbox-unverified")}async function Z(e){try{const r=e[0];let t=process.cwd(),n="",a="",i=!1,d=!1;const p=new Set;["register","capture","accept","status","observation"].includes(String(r))||s("action-invalid");for(let c=1;c<e.length;c++){const l=e[c];if(p.has(l)&&s("argument-invalid"),p.add(l),l==="--authorize-synthetic-backend")i=!0;else if(l==="--authorize-root-review")d=!0;else{const O=e[++c];(!O||O.startsWith("--"))&&s("argument-invalid"),l==="--project-root"?t=O:l==="--surface"?n=O:l==="--target-url"?a=O:s("argument-invalid")}}(!n||!a||i!==(r==="register")||d!==(r==="accept"))&&s("operator-approval-required");let g="";for await(const c of process.stdin)g+=String(c),Buffer.byteLength(g)>32768&&s("input-limit");const{parseDocument:S}=await import("yaml"),f=S(g,{strict:!0,uniqueKeys:!0,schema:"core",customTags:[]});(f.errors.length||f.warnings.length)&&s("input-invalid");const o=JSON.parse(g);if(r==="register"){const c=await W({projectRoot:t,surface:n,targetUrl:a,contract:_(o),authorizeSyntheticBackend:i});console.log(JSON.stringify({schemaVersion:1,grantId:c,qaAccepted:!1,checkpointAccepted:!1}))}else if(r==="capture"){(!k(o,["scenario","generation","grantId"])||typeof o.generation!="string"||typeof o.grantId!="string")&&s("input-invalid");const{captureSyntheticBackendScenario:c}=await import("./qa-synthetic-backend-capture.js");console.log(JSON.stringify(await c({projectRoot:t,surface:n,targetUrl:a,scenario:o.scenario,generation:o.generation,grantId:o.grantId})))}else{const c=await import("./qa-synthetic-backend-review.js");if(r==="accept"){const l=c.acceptSyntheticBackendRootReview({projectRoot:t,surface:n,targetUrl:a,report:o,authorizeRootReview:d});return console.log(JSON.stringify(l)),l.qaAccepted?0:2}if((!k(o,["sha256"])||typeof o.sha256!="string")&&s("input-invalid"),r==="observation")console.log(JSON.stringify(c.readSyntheticBackendObservation(t,n,a,o.sha256)));else{const l=c.readSyntheticBackendRootReview(t,n,a,o.sha256);return console.log(JSON.stringify(l.receipt)),l.receipt.qaAccepted?0:2}}return 0}catch(r){const t=r instanceof Error&&/^qa-(synthetic-backend|scan-review)-[a-z-]+$/.test(r.message)?r.message:"qa-synthetic-backend-unavailable";return console.error(t),1}}async function W(e){e.authorizeSyntheticBackend!==!0&&s("operator-approval-required");const r=_(e.contract),t=z(e.projectRoot,e.surface,e.targetUrl);await N(r);const n={schemaVersion:1,contract:r,planSha256:t.planSha256,sourceHead:t.sourceHead,surface:e.surface,targetUrl:e.targetUrl,expiresAt:new Date(Date.now()+r.durationMs).toISOString()},a=P(),i=C(e.projectRoot),d=w(A(i,`backend-grant-${a}.json`),u.O_WRONLY|u.O_CREAT|u.O_EXCL|u.O_NOFOLLOW,384);try{T(d,JSON.stringify(n)),q(d)}finally{b(d)}const p=w(i,u.O_RDONLY|u.O_DIRECTORY|u.O_NOFOLLOW);try{q(p)}finally{b(p)}return a}const Y=`let input='';for await(const b of process.stdin)input+=b;
|
|
2
|
+
const q=JSON.parse(input); const r=await fetch('http://127.0.0.1:'+q.port+q.path,{method:q.method,
|
|
3
|
+
headers:q.body===null?{}:{'content-type':'application/json'},body:q.body===null?undefined:q.body,
|
|
4
|
+
redirect:'manual',signal:AbortSignal.timeout(q.timeout)});
|
|
5
|
+
if(r.status>=300&&r.status<400||r.headers.has('set-cookie'))process.exit(3);
|
|
6
|
+
let size=0;const parts=[];for await(const b of r.body){size+=b.length;if(size>q.maxResponseBytes)process.exit(4);parts.push(Buffer.from(b));}
|
|
7
|
+
process.stdout.write(JSON.stringify({status:r.status,body:Buffer.concat(parts).toString('base64'),contentType:r.headers.get('content-type')||'application/octet-stream'}));`;async function ee(e){/^[a-f0-9-]{36}$/.test(e.grantId)||s("grant-invalid");const r=C(e.projectRoot),t=w(A(r,`backend-grant-${e.grantId}.json`),u.O_RDONLY|u.O_NOFOLLOW);let n,a;try{const o=j(t);(!o.isFile()||o.nlink!==1||o.uid!==process.getuid?.()||o.mode&63||o.size<1||o.size>32768)&&s("grant-invalid"),a=D(t,"utf8"),n=JSON.parse(a),k(n,["schemaVersion","contract","planSha256","sourceHead","surface","targetUrl","expiresAt"])||s("grant-invalid")}finally{b(t)}const i=_(n.contract),d=()=>{const o=w(A(r,`backend-grant-${e.grantId}.json`),u.O_RDONLY|u.O_NOFOLLOW);try{const l=j(o);(!l.isFile()||l.nlink!==1||l.uid!==process.getuid?.()||l.mode&63||l.size!==Buffer.byteLength(a)||D(o,"utf8")!==a)&&s("grant-stale")}finally{b(o)}const c=z(e.projectRoot,e.surface,e.targetUrl);(n.schemaVersion!==1||n.surface!==e.surface||n.targetUrl!==e.targetUrl||n.planSha256!==c.planSha256||n.sourceHead!==c.sourceHead||i.scenarioSha256!==e.scenarioSha256||i.generation!==e.generation||!Number.isFinite(Date.parse(n.expiresAt))||Date.parse(n.expiresAt)<=Date.now())&&s("grant-stale")};d(),await N(i);const p=w(A(r,`backend-consumed-${e.grantId}`),u.O_WRONLY|u.O_CREAT|u.O_EXCL|u.O_NOFOLLOW,384);try{T(p,"consumed"),q(p)}finally{b(p)}const g=w(r,u.O_RDONLY|u.O_DIRECTORY|u.O_NOFOLLOW);try{q(g)}finally{b(g)}let S=0;const f=[];return{contractSha256:I(JSON.stringify(i)),verify:async()=>{d(),await N(i),d()},observations:()=>f.map(o=>({...o})),request:async(o,c,l,O)=>{d();const U=new URL(e.targetUrl),h=new URL(o);(h.origin!==U.origin||h.username||h.password||h.hash||h.search||Object.keys(O).some(m=>/^(authorization|proxy-authorization|cookie)$/i.test(m)))&&s("request-denied");const x=i.routes.find(m=>m.path===h.pathname&&m.method===c);if((!x||++S>i.maxRequests)&&s("request-denied"),Object.keys(x.fields).length){(l===null||Buffer.byteLength(l)>i.maxBodyBytes)&&s("request-denied");let m;try{m=JSON.parse(l)}catch{return s("request-denied")}(!k(m,Object.keys(x.fields))||Object.entries(m).some(([M,v])=>typeof v!="string"||!x.fields[M].includes(v)))&&s("request-denied")}else l!==null&&l!==""&&s("request-denied");await N(i),d();const L=Math.min(5e3,Date.parse(n.expiresAt)-Date.now());L<1&&s("grant-stale");const $=await J(["exec","-i",i.containerId,"node","--input-type=module","-e",Y],JSON.stringify({port:i.port,path:h.pathname,method:c,body:l,maxResponseBytes:i.maxResponseBytes,timeout:L}),Math.ceil(i.maxResponseBytes*4/3)+1024,L+250);d(),await N(i);const y=JSON.parse($),E=Buffer.from(y.body,"base64");return(!R(y.status,599)||y.status<200||y.status>=300&&y.status<400||E.length>i.maxResponseBytes||typeof y.contentType!="string"||y.contentType.length>128||/[\r\n]/.test(y.contentType))&&s("response-denied"),f.push({path:h.pathname,method:c,status:y.status,responseSha256:I(E.toString("base64"))}),{status:y.status,body:E,contentType:y.contentType}}}}export{ee as openSyntheticBackendSession,W as registerSyntheticBackendGrant,Z as syntheticBackendCliHandler,_ as validateSyntheticBackendContract,N as verifySyntheticBackendSandbox};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface SyntheticBrokerPortConfiguration {
|
|
2
|
+
readonly projectRoot: string;
|
|
3
|
+
readonly surface: string;
|
|
4
|
+
readonly targetUrl: string;
|
|
5
|
+
readonly sourceHead: string;
|
|
6
|
+
readonly generation: string;
|
|
7
|
+
readonly scenarioSha256: string;
|
|
8
|
+
readonly grantId: string;
|
|
9
|
+
readonly contractSha256: string;
|
|
10
|
+
readonly socketPath: string;
|
|
11
|
+
readonly expiresAt: string;
|
|
12
|
+
}
|
|
13
|
+
export interface SyntheticBackendCapturePort {
|
|
14
|
+
readonly contractSha256: string;
|
|
15
|
+
readonly scopeSha256: string;
|
|
16
|
+
readonly request: (url: string, method: string, body: string | null, headers: Readonly<Record<string, string>>) => Promise<{
|
|
17
|
+
status: number;
|
|
18
|
+
body: Buffer;
|
|
19
|
+
contentType: string;
|
|
20
|
+
}>;
|
|
21
|
+
readonly verify: () => Promise<void>;
|
|
22
|
+
readonly observations: () => readonly {
|
|
23
|
+
path: string;
|
|
24
|
+
method: string;
|
|
25
|
+
status: number;
|
|
26
|
+
responseSha256: string;
|
|
27
|
+
}[];
|
|
28
|
+
}
|
|
29
|
+
/** Trusted worker composition only. Public capture CLI never accepts a port. */
|
|
30
|
+
export declare function createSyntheticBrokerPort(value: SyntheticBrokerPortConfiguration): SyntheticBackendCapturePort;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createHash as D}from"node:crypto";import{request as M}from"node:http";import{lstatSync as m,realpathSync as U}from"node:fs";import{dirname as z,isAbsolute as O}from"node:path";import{planRootQaScan as T}from"./qa-scan-review.js";function s(e="unverified"){throw new Error(`qa-synthetic-backend-broker-port-${e}`)}function N(e){(!e||Object.keys(e).sort().join(",")!=="contractSha256,expiresAt,generation,grantId,projectRoot,scenarioSha256,socketPath,sourceHead,surface,targetUrl"||!/^[a-f0-9]{64}$/.test(e.contractSha256)||!/^[a-f0-9]{64}$/.test(e.generation)||!/^[a-f0-9]{64}$/.test(e.scenarioSha256)||!/^[a-f0-9-]{36}$/.test(e.grantId)||!O(e.socketPath)||Buffer.byteLength(e.socketPath)>100||!Number.isFinite(Date.parse(e.expiresAt))||Date.parse(e.expiresAt)>Date.now()+3e4)&&s();const t=Object.freeze({...e}),i=z(t.socketPath),b=m(i),c=m(t.socketPath),A=new URL(t.targetUrl),$=performance.now()+Math.max(0,Date.parse(t.expiresAt)-Date.now()),h=()=>{const a=m(i),r=m(t.socketPath);(Date.now()>=Date.parse(t.expiresAt)||performance.now()>=$)&&s("expired"),(U(i)!==i||!a.isDirectory()||a.isSymbolicLink()||a.uid!==process.getuid?.()||(a.mode&511)!==448||a.dev!==b.dev||a.ino!==b.ino||!r.isSocket()||r.isSymbolicLink()||r.uid!==process.getuid?.()||(r.mode&511)!==384||r.dev!==c.dev||r.ino!==c.ino||r.ctimeMs!==c.ctimeMs||r.mtimeMs!==c.mtimeMs)&&s("custody"),T(t.projectRoot,t.surface,t.targetUrl).sourceHead!==t.sourceHead&&s("source")};h();let q=0;const S=[],E=D("sha256").update(JSON.stringify([t.sourceHead,t.surface,t.targetUrl,t.generation,t.scenarioSha256,t.grantId])).digest("hex");return Object.freeze({contractSha256:t.contractSha256,scopeSha256:E,verify:async()=>h(),observations:()=>S.map(a=>({...a})),request:async(a,r,d,L)=>{h();const n=new URL(a);(n.origin!==A.origin||n.username||n.password||n.search||n.hash||!/^\/[a-zA-Z0-9/_-]*$/.test(n.pathname)||!["GET","POST","PUT","DELETE"].includes(r)||Object.keys(L).some(y=>/^(authorization|proxy-authorization|cookie)$/i.test(y))||d!==null&&Buffer.byteLength(d)>16384||++q>64)&&s("request");const g=await new Promise((y,p)=>{const k=d===null?void 0:Buffer.from(d),f=M({socketPath:t.socketPath,path:n.pathname,method:r,agent:!1,headers:{...k?{"content-type":"application/json","content-length":String(k.length)}:{}}},o=>{const u=o.statusCode??502,l=o.headers["content-length"];if(u>=300&&u<400||u>=400||o.headers["set-cookie"]||l!==void 0&&(!/^[0-9]+$/.test(l)||Number(l)>1048576)){o.destroy(),p(new Error("qa-synthetic-backend-broker-port-unverified"));return}let w=0;const x=[];o.on("data",P=>{w+=P.length,w>1048576?(o.destroy(),p(new Error("qa-synthetic-backend-broker-port-unverified"))):x.push(P)}),o.on("error",()=>p(new Error("qa-synthetic-backend-broker-port-unverified"))),o.on("end",()=>y({status:u,body:Buffer.concat(x),contentType:o.headers["content-type"]??"application/octet-stream"}))});f.setTimeout(Math.max(1,Math.min(5e3,Date.parse(t.expiresAt)-Date.now())),()=>f.destroy()),f.on("error",o=>p(new Error(`qa-synthetic-backend-broker-port-${/^[A-Z_]+$/.test(o.code??"")?o.code.toLowerCase().replaceAll("_","-"):"transport"}`))),f.end(k)});return h(),S.push({path:n.pathname,method:r,status:g.status,responseSha256:D("sha256").update(g.body.toString("base64")).digest("hex")}),g}})}export{N as createSyntheticBrokerPort};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function launchSyntheticBackendBrowser(): Promise<import("playwright-core").Browser>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{lstatSync as s,realpathSync as c}from"node:fs";import{chromium as i}from"playwright-core";async function h(){if(process.platform!=="linux")throw new Error("qa-synthetic-backend-host-unsupported");const e=process.arch==="arm64",r=e?"/usr/bin/chromium":"/opt/google/chrome/chrome",n=["/usr/bin/bwrap","/usr","/usr/lib","/usr/lib64","/etc/fonts","/etc/ld.so.cache",...e?[r]:["/opt","/opt/google","/opt/google/chrome",r]];try{for(const o of n){const t=s(o);if(t.uid!==0||t.mode&18||t.isSymbolicLink()||c(o)!==o)throw new Error}}catch{throw new Error("qa-synthetic-backend-browser-unverified")}try{return await i.launch({executablePath:"/usr/bin/bwrap",ignoreDefaultArgs:!0,timeout:1e4,env:{PATH:"/usr/bin:/bin",LANG:"C.UTF-8"},args:["--unshare-all","--die-with-parent","--ro-bind","/usr","/usr","--ro-bind","/lib","/lib","--ro-bind","/lib64","/lib64",...e?[]:["--ro-bind","/opt/google/chrome","/opt/google/chrome"],"--ro-bind","/etc/fonts","/etc/fonts","--ro-bind","/etc/ld.so.cache","/etc/ld.so.cache","--proc","/proc","--dev","/dev","--tmpfs","/tmp","--dir","/tmp/home","--chdir","/tmp","--clearenv","--setenv","HOME","/tmp/home","--setenv","PATH","/usr/bin:/bin",r,"--headless=new","--no-sandbox","--remote-debugging-pipe","--user-data-dir=/tmp/qa-profile","--disable-dev-shm-usage","--no-first-run","--disable-background-networking","--disable-component-update","--disable-sync"]})}catch{throw new Error("qa-synthetic-backend-browser-unavailable")}}export{h as launchSyntheticBackendBrowser};
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
import { type RefactorRootTargetV2 } from './refactor-root.js';
|
|
2
|
+
export type RefactorCharacterizationRunner = 'native' | 'vitest' | 'cpp';
|
|
2
3
|
/** Node's native type-stripping switch first exists in 22.6.0. */
|
|
3
4
|
export declare function supportsNativeTypeStrippingVersion(version: string): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Prefer Node's runtime capability declaration when available. Older eligible
|
|
7
|
+
* releases did not expose `process.features.typescript`, so retain the version
|
|
8
|
+
* fallback only when the property is absent. An explicit false/unknown value
|
|
9
|
+
* means this binary cannot safely run the native TypeScript path.
|
|
10
|
+
*/
|
|
11
|
+
export declare function supportsNativeTypeStrippingRuntime(version: string, feature: unknown): boolean;
|
|
4
12
|
interface FileDigest {
|
|
5
13
|
readonly path: string;
|
|
6
14
|
readonly sha256: string;
|
|
@@ -20,7 +28,7 @@ export interface RefactorCharacterizationBaselineV1 {
|
|
|
20
28
|
}
|
|
21
29
|
export interface RefactorCharacterizationBaselineV2 extends Omit<RefactorCharacterizationBaselineV1, 'schemaVersion'> {
|
|
22
30
|
readonly schemaVersion: 2;
|
|
23
|
-
readonly runner: 'vitest';
|
|
31
|
+
readonly runner: 'vitest' | 'cpp';
|
|
24
32
|
readonly toolchainSha256: string;
|
|
25
33
|
}
|
|
26
34
|
export type RefactorCharacterizationBaseline = RefactorCharacterizationBaselineV1 | RefactorCharacterizationBaselineV2;
|
|
@@ -42,6 +50,7 @@ export interface RefactorCharacterizationReceiptV1 {
|
|
|
42
50
|
readonly gitCommitAuthorized: false;
|
|
43
51
|
readonly publicSafe: true;
|
|
44
52
|
}
|
|
45
|
-
export declare function runRootRefactorCharacterization(projectRoot: string, admissionSha256: string, testPaths: readonly string[], dependencyPaths: readonly string[], phase: 'baseline' | 'after', authorizeRun: boolean, causalPath: string, baselineSha256?: string, runner?: RefactorCharacterizationRunner): RefactorCharacterizationReceiptV1;
|
|
53
|
+
export declare function runRootRefactorCharacterization(projectRoot: string, admissionSha256: string, testPaths: readonly string[], dependencyPaths: readonly string[], phase: 'baseline' | 'after', authorizeRun: boolean, causalPath: string, baselineSha256?: string, runner?: RefactorCharacterizationRunner, target?: RefactorRootTargetV2): RefactorCharacterizationReceiptV1;
|
|
46
54
|
export declare function refactorCharacterizationCliHandler(args: readonly string[]): number;
|
|
55
|
+
export declare function runRootRefactorTargetCharacterization(projectRoot: string, admissionSha256: string, target: RefactorRootTargetV2, testPaths: readonly string[], dependencyPaths: readonly string[], phase: 'baseline' | 'after', authorizeRun: boolean, causalPath: string, baselineSha256?: string, runner?: RefactorCharacterizationRunner): RefactorCharacterizationReceiptV1;
|
|
47
56
|
export {};
|
|
@@ -1,12 +1,21 @@
|
|
|
1
|
-
import{spawnSync as
|
|
2
|
-
`)))throw new Error("refactor-root-baseline-invalid");return
|
|
3
|
-
`);if(
|
|
4
|
-
`,{mode:384,flag:"wx"})}const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
`)
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
import{spawnSync as Q}from"node:child_process";import{createHash as pt,randomBytes as ht}from"node:crypto";import{closeSync as K,constants as B,existsSync as C,fsyncSync as tt,lstatSync as z,mkdirSync as Z,mkdtempSync as mt,openSync as et,readFileSync as H,realpathSync as F,rmSync as wt,writeFileSync as A}from"node:fs";import{tmpdir as vt}from"node:os";import{basename as yt,dirname as N,join as g,resolve as gt}from"node:path";import{mutationQaGit as rt}from"./mutation-qa-git.js";import{exactCommittedRefactorFile as bt,privateRefactorDirectory as ot,readPrivateRefactorAdmission as St,verifyRootRefactorForCharacterization as Et,readPrivateRefactorTargetAdmission as kt,verifyRootRefactorTargetForCharacterization as Ot}from"./refactor-root.js";const R=/^[a-f0-9]{64}$/,xt=64*1024*1024,st=32,nt=128;function _t(e){const t=e.match(/^(\d+)\.(\d+)\.(\d+)$/);if(!t)return!1;const r=Number(t[1]),n=Number(t[2]);return r>22||r===22&&n>=6}function Nt(e,t){return _t(e)?t===void 0?!0:t==="strip"||t==="transform":!1}function b(e){return pt("sha256").update(e).digest("hex")}function D(e){return e.length>0&&e.length<=512&&/^[A-Za-z0-9_.-]+(?:\/[A-Za-z0-9_.-]+)*$/.test(e)&&e.split("/").every(t=>t!=="."&&t!==".."&&![".git",".neocortex","node_modules"].includes(t.toLowerCase()))}function V(e){return[...e].sort((t,r)=>Buffer.from(t).compare(Buffer.from(r)))}function jt(e,t,r){if(!t.endsWith(".js")&&!t.endsWith(".ts"))return;let n=N(t);for(;;){const f=n==="."?"package.json":`${n}/package.json`;if(C(g(e,f))){if(!r.includes(f))throw new Error("refactor-root-tests-manifest-unbound");let s;try{s=JSON.parse(L(e,f).toString("utf8"))}catch{throw new Error("refactor-root-tests-manifest-invalid")}if(!s||typeof s!="object"||Array.isArray(s)||!["module","commonjs"].includes(s.type)||t.endsWith(".ts")&&s.type!=="module")throw new Error("refactor-root-tests-manifest-invalid");return}if(n===".")break;n=N(n)}throw new Error("refactor-root-tests-manifest-missing")}function L(e,t){if(!D(t))throw new Error("refactor-root-tests-path-invalid");const r=g(e,t),n=z(r);if(F(r)!==r||!n.isFile()||n.isSymbolicLink()||n.size<1||n.size>8*1024*1024)throw new Error("refactor-root-tests-source-unverified");const f=H(r);if(f.length<1||f.length>8*1024*1024||f.includes(0))throw new Error("refactor-root-tests-source-unverified");return new TextDecoder("utf-8",{fatal:!0}).decode(f),f}function q(e,t){if(!R.test(t))throw new Error("refactor-root-baseline-invalid");return g(ot(e),`characterization-baseline-${t}.json`)}function Y(e,t){const r=z(q(e,t));if(!r.isFile()||r.isSymbolicLink()||r.uid!==process.getuid?.()||(r.mode&63)!==0||r.size<100||r.size>64*1024)throw new Error("refactor-root-baseline-invalid");const n=H(q(e,t));if(n.length>64*1024)throw new Error("refactor-root-baseline-invalid");let f;try{f=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(n))}catch{throw new Error("refactor-root-baseline-invalid")}if(!f||typeof f!="object"||Array.isArray(f))throw new Error("refactor-root-baseline-invalid");const s=f,i=["schemaVersion","kind","admissionSha256","sourceHead","testFiles","dependencies","causalPath","candidateSha256","outputSha256","causalOutputSha256","baselineSha256"],d=a=>Array.isArray(a)&&a.every(o=>o&&typeof o=="object"&&!Array.isArray(o)&&Object.keys(o).sort().join("\0")==="path\0sha256"&&typeof o.path=="string"&&typeof o.sha256=="string"&&D(o.path)&&R.test(o.sha256)),h=s.schemaVersion===2;if(Object.keys(s).sort().join("\0")!==(h?[...i,"runner","toolchainSha256"]:i).sort().join("\0")||s.schemaVersion!==1&&s.schemaVersion!==2||h&&(!["vitest","cpp"].includes(String(s.runner))||!R.test(String(s.toolchainSha256)))||s.kind!=="root-refactor-characterization-baseline"||!R.test(String(s.admissionSha256))||typeof s.sourceHead!="string"||!/^[a-f0-9]{40}(?:[a-f0-9]{24})?$/.test(s.sourceHead)||!d(s.testFiles)||!d(s.dependencies)||s.testFiles.length<1||s.testFiles.length>st||s.dependencies.length>nt||typeof s.causalPath!="string"||!D(s.causalPath)||!R.test(String(s.candidateSha256))||!R.test(String(s.outputSha256))||!R.test(String(s.causalOutputSha256))||s.baselineSha256!==t)throw new Error("refactor-root-baseline-invalid");const v=s.testFiles,l=s.dependencies;if(new Set([...v,...l].map(a=>a.path)).size!==v.length+l.length||v.map(a=>a.path).join("\0")!==V(v.map(a=>a.path)).join("\0")||l.map(a=>a.path).join("\0")!==V(l.map(a=>a.path)).join("\0"))throw new Error("refactor-root-baseline-invalid");const{baselineSha256:u,...c}=s;if(b(JSON.stringify(c))!==t||!n.equals(Buffer.from(`${JSON.stringify(s)}
|
|
2
|
+
`)))throw new Error("refactor-root-baseline-invalid");return s}function $t(e,t){const r=b(JSON.stringify(t)),n=q(e,r),f={...t,baselineSha256:r},s=Buffer.from(`${JSON.stringify(f)}
|
|
3
|
+
`);if(C(n))Y(e,r);else{const i=et(n,B.O_WRONLY|B.O_CREAT|B.O_EXCL|(B.O_NOFOLLOW??0),384);try{A(i,s),tt(i)}finally{K(i)}const d=et(ot(e),B.O_RDONLY|(B.O_DIRECTORY??0));try{tt(d)}finally{K(d)}}return Y(e,r),r}function it(e){return[...e.files.map(t=>t.path),...e.schemaVersion!==1?e.newFiles.map(t=>t.path):[]]}function at(e,t,r,n=[]){const f=new Map;let s=0;for(const d of[...it(t),...r]){if(n.includes(d)){try{z(g(e,d))}catch(v){if(v.code==="ENOENT")continue;throw v}throw new Error("refactor-root-tests-source-stale")}const h=L(e,d);if(s+=h.length,s>xt)throw new Error("refactor-root-tests-snapshot-too-large");f.set(d,h)}const i=b(JSON.stringify([...[...f].map(([d,h])=>[d,b(h)]),...n.map(d=>[d,null])]));return{files:f,candidateSha256:i}}function ct(){try{const e=F("/usr/bin/g++"),t=z(e);if(!e.startsWith("/usr/")||!/^[A-Za-z0-9_./+-]+$/.test(e)||!t.isFile()||t.uid!==0||(t.mode&18)!==0||t.size<1||t.size>32*1024*1024)throw new Error("invalid compiler");const r=Q(e,["-dumpfullversion","-dumpversion"],{env:{PATH:"/usr/bin:/bin"},encoding:"utf8",timeout:1e4,maxBuffer:4096}),n=r.stdout?.trim();if(r.status!==0||!/^(?:11|12|13|14|15)\.[0-9]+\.[0-9]+$/.test(n))throw new Error("unsupported compiler");return{executable:e,sha256:b(JSON.stringify([e,n,b(H(e))]))}}catch{throw new Error("refactor-root-tests-toolchain-unverified")}}function Tt(e,t,r){let n="";for(const $ of t){let x=N($),T="";for(;;){const W=x==="."?"package.json":`${x}/package.json`;if(C(g(e,W))){T=W;break}if(x===".")break;x=N(x)}if(!T||n&&T!==n)throw new Error("refactor-root-tests-toolchain-unverified");n=T}if(!r.includes(n)||!r.includes("package-lock.json"))throw new Error("refactor-root-tests-toolchain-unbound");const f=L(e,n),s=L(e,"package-lock.json");let i,d;try{i=JSON.parse(f.toString("utf8")),d=JSON.parse(s.toString("utf8"))}catch{throw new Error("refactor-root-tests-toolchain-unverified")}const h=i.devDependencies?.vitest??i.dependencies?.vitest,v=d.packages,l=n==="package.json"?"":N(n),u=v?.[l],c=u?.devDependencies?.vitest??u?.dependencies?.vitest,a=v?.["node_modules/vitest"]?.version,o=v?.["node_modules/vite"]?.version;if(typeof h!="string"||h.length>80||!/^[\^~]?[0-9]+\.[0-9]+\.[0-9]+$/.test(h)||h!==c||typeof a!="string"||!/^[0-9]+\.[0-9]+\.[0-9]+$/.test(a)||!a.startsWith("3.2.")||typeof o!="string"||!/^[0-9]+\.[0-9]+\.[0-9]+$/.test(o)||!zt(o))throw new Error("refactor-root-tests-toolchain-unverified");const m=F(g(e,"node_modules")),y=z(m);if(yt(m)!=="node_modules"||!y.isDirectory()||y.isSymbolicLink()||y.uid!==process.getuid?.())throw new Error("refactor-root-tests-toolchain-unverified");const _=g(m,"vitest","package.json"),w=g(m,"vitest","vitest.mjs"),S=g(m,"vite","package.json"),E=z(_),k=z(w),j=z(S);if(!E.isFile()||E.isSymbolicLink()||!k.isFile()||k.isSymbolicLink()||!j.isFile()||j.isSymbolicLink()||F(_)!==_||F(w)!==w||F(S)!==S||E.size>64*1024||k.size>1024*1024||j.size>64*1024)throw new Error("refactor-root-tests-toolchain-unverified");const M=H(_),I=H(w),P=H(S);let J,O;try{J=JSON.parse(M.toString("utf8")),O=JSON.parse(P.toString("utf8"))}catch{throw new Error("refactor-root-tests-toolchain-unverified")}if(J.name!=="vitest"||J.version!==a||O.name!=="vite"||O.version!==o)throw new Error("refactor-root-tests-toolchain-unverified");return{nodeModules:m,sha256:b(JSON.stringify([b(f),b(s),b(M),b(I),b(P)]))}}function zt(e){const t=e.match(/^(\d+)\.(\d+)\.(\d+)$/);return!!t&&Number(t[1])<=7&&(Number(t[1])>6||Number(t[1])===6&&Number(t[2])>=1)}function ft(e,t,r,n,f,s,i){if(r==="python"){const l=N(t[0]),u=V([...e.keys()].filter(c=>(l==="."||c.startsWith(`${l}/`))&&/(?:^|\/)test_[A-Za-z0-9_]+\.py$/.test(c)));if(JSON.stringify(u)!==JSON.stringify(t))throw new Error("refactor-root-tests-path-invalid")}const d=F(r==="cpp"?"/usr/bin/dash":r==="python"?"/usr/bin/python3":process.execPath),h=process.features.typescript;if(r==="node-typescript"&&!Nt(process.versions.node,h))throw new Error("refactor-root-tests-toolchain-unavailable");if(process.platform!=="linux"||!C("/usr/bin/bwrap")||!z("/usr/bin/bwrap").isFile()||!(d.startsWith("/usr/")||d.startsWith("/home/linuxbrew/.linuxbrew/")))throw new Error("refactor-root-tests-sandbox-unavailable");const v=mt(g(vt(),"p222-refactor-characterization-"));try{const l=g(v,"work");Z(l,{mode:448});for(const[w,S]of e){const E=g(l,w);Z(N(E),{recursive:!0,mode:448}),A(E,S,{mode:384,flag:"wx"})}if(r==="vitest"){if(!f)throw new Error("refactor-root-tests-toolchain-unavailable");Z(g(l,"node_modules"),{mode:448}),A(g(l,"p222-vitest.config.mjs"),`export default ${JSON.stringify({test:{include:t,environment:"node",silent:!0,passWithNoTests:!1,watch:!1,maxWorkers:1,fileParallelism:!1,pool:"forks",coverage:{enabled:!1}}})};
|
|
4
|
+
`,{mode:384,flag:"wx"})}if(r==="cpp"){if(!s||!i||!e.has(i))throw new Error("refactor-root-tests-toolchain-unavailable");const w=s.executable,S=V([...e.keys()].filter(k=>k.endsWith(".cpp")&&k!==i&&!t.includes(k))).map(k=>`'/work/${k}'`);n&&A(g(l,"p222-cpp-causal.cpp"),`#include <cstdio>
|
|
5
|
+
#include <cstdlib>
|
|
6
|
+
extern "C" void __cyg_profile_func_enter(void*,void*) { std::fputs(${JSON.stringify(n+`
|
|
7
|
+
`)},stderr); std::_Exit(86); }
|
|
8
|
+
extern "C" void __cyg_profile_func_exit(void*,void*) {}
|
|
9
|
+
`,{mode:384,flag:"wx"});const E=["set -eu","ulimit -c 0",`'${w}' -std=c++17 -O0 -UNDEBUG -I/work ${n?"-finstrument-functions -finstrument-functions-exclude-file-list=/usr/include ":""}-c '/work/${i}' -o /tmp/p222-cpp-causal.o`,...t.flatMap((k,j)=>[`'${w}' -std=c++17 -O0 -UNDEBUG -I/work '/work/${k}' ${S.join(" ")} /tmp/p222-cpp-causal.o ${n?"/work/p222-cpp-causal.cpp ":""}-o /tmp/p222-cpp-test-${j}`,`/tmp/p222-cpp-test-${j}`,`printf 'P222_CPP_TEST_PASSED_${j}\\n'`])].join(`
|
|
10
|
+
`)+`
|
|
11
|
+
`;A(g(l,"p222-cpp-runner.sh"),E,{mode:384,flag:"wx"})}const u=g(v,"etc");Z(u,{mode:448}),A(g(u,"passwd"),`nobody:x:65534:65534:nobody:/tmp:/bin/sh
|
|
12
|
+
`,{mode:384}),A(g(u,"group"),`nogroup:x:65534:
|
|
13
|
+
`,{mode:384}),A(g(u,"hosts"),`127.0.0.1 localhost
|
|
14
|
+
`,{mode:384}),A(g(u,"nsswitch.conf"),`hosts: files
|
|
15
|
+
`,{mode:384});const c=["--die-with-parent","--new-session","--unshare-all","--clearenv","--setenv","HOME","/tmp","--setenv","TMPDIR","/tmp","--setenv","PATH","/home/linuxbrew/.linuxbrew/bin:/usr/bin:/bin","--setenv","CI","true","--ro-bind","/usr","/usr"];r==="python"&&c.push("--setenv","PYTHONPATH","/work");for(const w of["/lib","/lib64","/bin"])C(w)&&c.push("--ro-bind",w,w);C("/home/linuxbrew/.linuxbrew")&&c.push("--ro-bind","/home/linuxbrew/.linuxbrew","/home/linuxbrew/.linuxbrew"),c.push("--dir","/etc");for(const w of["passwd","group","hosts","nsswitch.conf"])c.push("--ro-bind",g(u,w),`/etc/${w}`);c.push("--dev","/dev","--proc","/proc","--tmpfs","/tmp","--ro-bind",l,"/work"),r==="vitest"&&c.push("--ro-bind",f.nodeModules,"/work/node_modules"),c.push("--chdir","/work","--",d),r==="cpp"?c.push("/work/p222-cpp-runner.sh"):r==="python"?c.push("-B","-S","-m","unittest","discover","-s",N(t[0]),"-p","test_*.py"):r==="vitest"?c.push("/work/node_modules/vitest/vitest.mjs","run","--root","/work","--config","/work/p222-vitest.config.mjs","--configLoader=runner","--reporter=json","--no-cache","--no-file-parallelism","--maxWorkers=1"):(r==="node-typescript"&&c.push("--experimental-strip-types"),c.push("--test","--test-reporter=tap",...t));const a=Q("/usr/bin/bwrap",c,{env:{PATH:"/usr/bin:/bin"},encoding:"buffer",timeout:18e4,maxBuffer:4*1024*1024});if(a.error||a.signal||a.status===null)throw new Error("refactor-root-tests-sandbox-unavailable");const o=Buffer.concat([a.stdout??Buffer.alloc(0),a.stderr??Buffer.alloc(0)]),m=r!=="python"||/^Ran [1-9][0-9]* tests? in /m.test(o.toString("utf8"));let y=!0;if(r==="vitest")try{const w=JSON.parse((a.stdout??Buffer.alloc(0)).toString("utf8"));y=Number.isSafeInteger(w.numPassedTests)&&Number(w.numPassedTests)>0&&w.numTotalTests===w.numPassedTests&&w.numFailedTests===0}catch{y=!1}const _=r!=="cpp"||t.every((w,S)=>o.toString("utf8").split(`
|
|
16
|
+
`).includes(`P222_CPP_TEST_PASSED_${S}`));return{passed:a.status===0&&m&&y&&_,outputSha256:b(o),canaryObserved:n!==void 0&&(r==="cpp"?o.toString("utf8").split(`
|
|
17
|
+
`).includes(n):o.includes(Buffer.from(n)))}}finally{wt(v,{recursive:!0,force:!0})}}function lt(e,t,r,n,f,s,i,d,h="native",v){if(!s)throw new Error("refactor-root-run-authorization-required");if(r.length<1||r.length>st||n.length>nt||!["native","vitest","cpp"].includes(h)||f==="baseline"&&d!==void 0||f==="after"&&(!d||!R.test(d)))throw new Error("refactor-root-tests-arguments-invalid");const l=V(r),u=V(n),c=h==="cpp"?"cpp":h==="vitest"?"vitest":l.every(o=>/(?:^|\/)test_[A-Za-z0-9_]+\.py$/.test(o))&&i.endsWith(".py")?"python":l.every(o=>o.endsWith(".test.ts"))&&i.endsWith(".ts")?"node-typescript":"node";if(new Set([...l,...u]).size!==l.length+u.length||l.some(o=>!D(o)||(c==="cpp"?!o.endsWith(".test.cpp"):c==="python"?!/(?:^|\/)test_[A-Za-z0-9_]+\.py$/.test(o)||N(o)!==N(l[0]):c==="vitest"?!/\.test\.(?:ts|js|mjs)$/.test(o):c==="node-typescript"?!o.endsWith(".test.ts"):!/\.test\.(?:mjs|cjs|js)$/.test(o)))||!D(i)||(c==="cpp"?!i.endsWith(".cpp")||i.endsWith(".test.cpp"):c==="python"?!i.endsWith(".py"):c==="vitest"?!/\.(?:ts|js|mjs)$/.test(i)||/\.test\./.test(i):c==="node-typescript"?!i.endsWith(".ts")||i.endsWith(".test.ts"):!/\.(?:mjs|cjs|js)$/.test(i))||u.some(o=>!D(o)||c==="python"&&/(?:^|\/)test_[A-Za-z0-9_]+\.py$/.test(o)))throw new Error("refactor-root-tests-path-invalid");const a=gt(e);try{const o=v?kt(a,t,v):null,m=o?{...o,sourceHead:o.targetPlan.sourceHead}:St(a,t),y=()=>v?Ot(a,t,v):Et(a,t),{pendingDocumentationPaths:_}=y(),w=new Set(it(m));if(l.some(p=>!w.has(p))||!m.files.some(p=>p.path===i)||l.includes(i)||u.some(p=>w.has(p)))throw new Error("refactor-root-tests-path-invalid");for(const p of[...l,i,...u])jt(a,p,u);for(const p of u)bt(a,p);const S=c==="vitest"?Tt(a,l,u):void 0,E=c==="cpp"?ct():void 0,k=S?.sha256??E?.sha256,j=rt(a,["diff","--name-only","-z","--no-ext-diff","--no-textconv"]).toString("utf8").split("\0").filter(p=>p&&!p.startsWith(".neocortex/")),M=rt(a,["ls-files","--others","--exclude-standard","-z"]).toString("utf8").split("\0").filter(p=>p&&!p.startsWith(".neocortex/")),I=[...j,...M].filter(p=>!l.includes(p));if(f==="baseline"&&I.length>0||f==="after"&&I.length===0)throw new Error("refactor-root-tests-phase-invalid");const P=l.map(p=>({path:p,sha256:b(L(a,p))})),J=u.map(p=>({path:p,sha256:b(L(a,p))})),O=f==="after"?Y(a,d):null;if(O&&(O.admissionSha256!==t||O.sourceHead!==m.sourceHead||O.causalPath!==i||(O.schemaVersion===2?h!==O.runner||O.toolchainSha256!==k:h!=="native")||JSON.stringify(O.testFiles)!==JSON.stringify(P)||JSON.stringify(O.dependencies)!==JSON.stringify(J)))throw new Error("refactor-root-baseline-stale");const $=at(a,m,u,_);if(O&&b($.files.get(i))===m.files.find(p=>p.path===i).sha256)throw new Error("refactor-root-tests-phase-invalid");const x=ft($.files,l,c,void 0,S,E,i);let T=null,W=!1;if(x.passed){const p=`P222_REFACTOR_CAUSAL_${ht(16).toString("hex")}`,G=new Map($.files);c!=="cpp"&&G.set(i,Buffer.concat([Buffer.from(c==="python"?`raise RuntimeError(${JSON.stringify(p)})
|
|
18
|
+
`:`throw new Error(${JSON.stringify(p)});
|
|
19
|
+
`),$.files.get(i)]));const U=ft(G,l,c,p,S,E,i);T=U.outputSha256,W=!U.passed&&U.canaryObserved}const dt=y();if(JSON.stringify(dt.pendingDocumentationPaths)!==JSON.stringify(_))throw new Error("refactor-root-tests-source-stale");const ut=at(a,m,u,_);if(E&&ct().sha256!==E.sha256)throw new Error("refactor-root-tests-toolchain-stale");if($.candidateSha256!==ut.candidateSha256)throw new Error("refactor-root-tests-source-stale");let X=d??null;return f==="baseline"&&x.passed&&W&&T&&(X=$t(a,{...c==="vitest"||c==="cpp"?{schemaVersion:2,runner:c,toolchainSha256:k}:{schemaVersion:1},kind:"root-refactor-characterization-baseline",admissionSha256:t,sourceHead:m.sourceHead,testFiles:P,dependencies:J,causalPath:i,candidateSha256:$.candidateSha256,outputSha256:x.outputSha256,causalOutputSha256:T})),Object.freeze({schemaVersion:1,kind:"root-refactor-characterization-observation",phase:f,admissionSha256:t,baselineSha256:X,candidateSha256:$.candidateSha256,outputSha256:x.outputSha256,causalOutputSha256:T,testFileCount:l.length,dependencyCount:u.length,testsPassedObserved:x.passed,causalFailureObserved:W,qaAccepted:!1,gitCommitAuthorized:!1,publicSafe:!0})}catch(o){throw o instanceof Error&&o.message.startsWith("refactor-root-")?o:new Error("refactor-root-tests-unverified")}}function Ht(e){let t="",r="",n,f="",s=!1,i="",d="native",h="plain";const v=[],l=[];try{if(e[0]!=="characterize")throw new Error("refactor-root-tests-arguments-invalid");for(let a=1;a<e.length;a++){const o=e[a],m=()=>{const y=e[++a];if(!y||y.startsWith("--"))throw new Error("refactor-root-tests-arguments-invalid");return y};if(o==="--project-root"&&!t)t=m();else if(o==="--admission-sha"&&!r)r=m();else if(o==="--baseline-sha"&&!n)n=m();else if(o==="--phase"&&!f){const y=m();if(y!=="baseline"&&y!=="after")throw new Error("refactor-root-tests-arguments-invalid");f=y}else if(o==="--test-path")v.push(m());else if(o==="--dependency")l.push(m());else if(o==="--causal-path"&&!i)i=m();else if(o==="--runner"&&d==="native"){const y=m();if(y!=="vitest"&&y!=="cpp")throw new Error("refactor-root-tests-arguments-invalid");d=y}else if(o==="--authorize-run"&&!s)s=!0;else if(o==="--format"&&h==="plain")h=m();else throw new Error("refactor-root-tests-arguments-invalid")}if(!t||!r||!f||!i||!["plain","json"].includes(h))throw new Error("refactor-root-tests-arguments-invalid");const u=lt(t,r,v,l,f,s,i,n,d),c=u.testsPassedObserved&&u.causalFailureObserved;return process.stdout.write(`${JSON.stringify({ok:c,observation:u})}
|
|
20
|
+
`),c?0:1}catch(u){const c=u instanceof Error&&/^refactor-root-[a-z-]+$/.test(u.message)?u.message:"refactor-root-tests-unverified";return process.stdout.write(`${JSON.stringify({ok:!1,reasonCode:c})}
|
|
21
|
+
`),1}}function Dt(e,t,r,n,f,s,i,d,h,v="native"){return lt(e,t,n,f,s,i,d,h,v,r)}export{Y as readRootRefactorBaseline,Ht as refactorCharacterizationCliHandler,lt as runRootRefactorCharacterization,Dt as runRootRefactorTargetCharacterization,Nt as supportsNativeTypeStrippingRuntime,_t as supportsNativeTypeStrippingVersion};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type RootControlRequestInput = Readonly<{
|
|
2
|
+
serverUrl: string;
|
|
3
|
+
token: string;
|
|
4
|
+
projectId: string;
|
|
5
|
+
platformTarget: string;
|
|
6
|
+
} & ({
|
|
7
|
+
storyId: string;
|
|
8
|
+
schemaVersion?: never;
|
|
9
|
+
scopeId?: never;
|
|
10
|
+
} | {
|
|
11
|
+
schemaVersion: 2;
|
|
12
|
+
scopeId: string;
|
|
13
|
+
storyId?: never;
|
|
14
|
+
})>;
|
|
15
|
+
export declare function requestRootControl(family: 'refactor' | 'qa', input: RootControlRequestInput, fetchFn?: typeof fetch): Promise<Record<string, unknown>>;
|
|
16
|
+
export declare function requestRefactorControl(input: Parameters<typeof requestRootControl>[1], fetchFn?: typeof fetch): Promise<Record<string, unknown>>;
|
|
17
|
+
export declare function refactorControlCliHandler(args: readonly string[], family?: 'refactor' | 'qa'): Promise<number>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{lstatSync as v,readFileSync as R,realpathSync as _}from"node:fs";import{join as y,resolve as E}from"node:path";import{signNxInvokeRequest as k}from"../../../shared/dist/nx-invoke-signature.js";import{COMMAND_REGISTRY_VERSION as C,COMMAND_REGISTRY_CHECKSUM as N}from"../generated/command-registry.generated.js";import{CLIENT_VERSION as b}from"../version.js";import{loadSecureConfig as q}from"../config/secure-config.js";import{neocortexProfileDirectory as A}from"../config/profile-directory.js";import{EncryptedCache as T}from"../cache/encrypted-cache.js";import{LicenseClient as $}from"../license/license-client.js";import{detectPlatform as L}from"../adapters/platform-detector.js";const S=new Set(["input-invalid","auth-required","tier-required","read-only","signature-required","client-unsupported","registry-mismatch","executor-unavailable"]),j=new Set(["arguments-invalid","authorization-required","host-unsupported","project-unbound","auth-required","response-invalid","request-refused","outcome-unknown"].map(o=>`refactor-root-control-${o}`));async function V(o){const r=o.body?.getReader();if(!r)throw new Error("refactor-root-control-response-invalid");let s=!1;try{const t=[];let n=0;for(;;){const c=await r.read();if(c.done){s=!0;break}if(n+=c.value.byteLength,n>16384)throw new Error("refactor-root-control-response-invalid");t.push(Buffer.from(c.value))}return JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(Buffer.concat(t,n)))}catch{throw new Error("refactor-root-control-response-invalid")}finally{s||await r.cancel().catch(()=>{}),r.releaseLock()}}async function O(o,r,s=fetch){if(o!=="refactor"&&o!=="qa"||"schemaVersion"in r&&(o!=="refactor"||r.schemaVersion!==2||typeof r.scopeId!="string"||!/^rfs_[a-f0-9]{64}$/.test(r.scopeId)||"storyId"in r)||!("schemaVersion"in r)&&("scopeId"in r||typeof r.storyId!="string"||!/^P[0-9]{1,12}(?:\.[0-9]{1,12}){1,3}$/.test(r.storyId)))throw new Error("refactor-root-control-arguments-invalid");const t=`/api/v1/invoke/${o}/control`,n=k({method:"POST",target:t,body:Buffer.from(JSON.stringify({projectId:r.projectId,..."schemaVersion"in r?{schemaVersion:2,scopeId:r.scopeId}:{storyId:r.storyId},platformTarget:r.platformTarget,registryVersion:C,registryChecksum:N})),bearerToken:r.token,clientVersion:b}),c=await s(`${r.serverUrl.replace(/\/+$/,"")}${t}`,{method:"POST",redirect:"error",signal:AbortSignal.timeout(2e5),headers:{...n.headers,Authorization:`Bearer ${r.token}`},body:n.body}),e=await V(c);if(!c.ok)throw new Error(typeof e?.error_code=="string"&&e.error_code.startsWith(`${o}-control-`)&&S.has(e.error_code.slice(`${o}-control-`.length))?e.error_code:"refactor-root-control-request-refused");const d=["schemaVersion","kind","status","completedStages","authority","qaAccepted","gitAuthority","billingAuthority","publicSafe"];if(!e||typeof e!="object"||Array.isArray(e)||Object.keys(e).some(a=>!d.includes(a))||e.schemaVersion!==1||e.kind!==`root-${o}-control`||typeof e.status!="string"||!["advanced","waiting","blocked","candidate-ready",...o==="qa"?["debt"]:[]].includes(e.status)||e.authority!==(o==="qa"?"LOCAL_ROOT_QA_CANDIDATE_ONLY":"LOCAL_ROOT_CANDIDATE_ONLY")||e.qaAccepted!==!1||e.gitAuthority!=="NONE"||e.billingAuthority!=="NONE"||e.publicSafe!==!0||e.completedStages!==void 0&&(typeof e.completedStages!="number"||!Number.isInteger(e.completedStages)||e.completedStages<0||e.completedStages>(o==="qa"?3:7)))throw new Error("refactor-root-control-response-invalid");return e}async function Y(o,r=fetch){return O("refactor",o,r)}async function G(o,r="refactor"){try{let s="",t="",n="",c=0,e=!1,d="json";const a=[...o];if(a.shift()!=="control")throw new Error("refactor-root-control-arguments-invalid");for(let i=0;i<a.length;i++){const l=a[i];if(l==="--authorize-root-control")e=!0;else if(l==="--project-root")s=a[++i]??"";else if(l==="--story")c++,t=a[++i]??"";else if(l==="--scope-id")c++,n=a[++i]??"";else if(l==="--format")d=a[++i]??"";else throw new Error("refactor-root-control-arguments-invalid")}if(!e||!s||c!==1||d!=="json"||(n?r!=="refactor"||t||!/^rfs_[a-f0-9]{64}$/.test(n):!/^P[0-9]{1,12}(?:\.[0-9]{1,12}){1,3}$/.test(t)))throw new Error("refactor-root-control-authorization-required");const g=L({cwd:E(s),env:process.env}).targetId;if(g!=="codex")throw new Error("refactor-root-control-host-unsupported");const f=y(E(s),".neocortex","state.json"),h=v(f);if(!h.isFile()||h.isSymbolicLink()||_(f)!==f||h.size>16*1024*1024)throw new Error("refactor-root-control-project-unbound");const p=JSON.parse(R(f,"utf8")).config?.project_id;if(typeof p!="string"||!/^[A-Za-z0-9][A-Za-z0-9_-]{15,127}$/.test(p))throw new Error("refactor-root-control-project-unbound");const u=q({strictReadOnly:!0});if(!u?.licenseKey)throw new Error("refactor-root-control-auth-required");const m=process.env.NEOCORTEX_SERVER_URL??u.serverUrl;if(!m)throw new Error("refactor-root-control-auth-required");const w=await new $({serverUrl:m,licenseKey:u.licenseKey,cacheProvider:new T({cacheDir:y(A(),"cache"),passphrase:u.licenseKey})}).getToken();if(!w)throw new Error("refactor-root-control-auth-required");const I=await O(r,{serverUrl:m,token:w,projectId:p,platformTarget:g,...n?{schemaVersion:2,scopeId:n}:{storyId:t}});return process.stdout.write(`${JSON.stringify({ok:!0,control:I})}
|
|
2
|
+
`),0}catch(s){const t=s instanceof Error?s.message.replace(/^qa-/,"refactor-"):"",n=j.has(t)||t.startsWith("refactor-control-")&&S.has(t.slice(17))?t:"refactor-root-control-outcome-unknown";return process.stdout.write(`${JSON.stringify({ok:!1,reasonCode:r==="qa"?n.replace(/^refactor-/,"qa-"):n})}
|
|
3
|
+
`),1}}export{G as refactorControlCliHandler,Y as requestRefactorControl,O as requestRootControl};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Preserve line numbers while excluding C++ comments and quoted/raw string data. */
|
|
2
|
+
export declare function cppRefactorExecutableLines(text: string): string[];
|
|
3
|
+
/** Syntactic anchor only; independent root review checks the failure body and behavior. */
|
|
4
|
+
export declare function isCppRefactorAssertionSite(line: string): boolean;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
function u(t){let n="",e=0,s="code",r="",c=!1,o="";for(;e<t.length;){const i=t[e];if(i===`
|
|
2
|
+
`){n+=`
|
|
3
|
+
`,e++,s==="line"&&(s="code"),s==="quote"&&(c=!1);continue}if(s==="line"){e++;continue}if(s==="block"){t.startsWith("*/",e)?(s="code",e+=2):e++;continue}if(s==="quote"){c?c=!1:i==="\\"?c=!0:i===r&&(s="code"),e++;continue}if(s==="raw"){t.startsWith(o,e)?(s="code",e+=o.length):e++;continue}if(t.startsWith("//",e)){s="line",e+=2,n+=" ";continue}if(t.startsWith("/*",e)){s="block",e+=2,n+=" ";continue}const f=/^(?:u8|u|U|L)?R"([^\s()\\]{0,16})\(/.exec(t.slice(e,e+24));if(f){o=`)${f[1]}"`,s="raw",e+=f[0].length,n+=" ";continue}if(i==='"'||i==="'"){r=i,s="quote",c=!1,e++,n+=" ";continue}if(/[A-Za-z_0-9]/.test(i)){const a=e++,l=/[0-9]/.test(i);for(;e<t.length&&(l?/[A-Za-z_0-9.']/.test(t[e]):/[A-Za-z_0-9]/.test(t[e]));)e++;n+=t.slice(a,e);continue}n+=i,e++}return n.split(/\r?\n/)}function h(t){return!/^\s*#/.test(t)&&(/\bassert\s*\(/.test(t)||/\bthrow\s+\S/.test(t)||/^\s*(?:else\s+)?if\s*\(/.test(t))}export{u as cppRefactorExecutableLines,h as isCppRefactorAssertionSite};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type RefactorRootTargetV2 } from './refactor-root.js';
|
|
1
2
|
export interface RefactorSemanticReviewV1 {
|
|
2
3
|
readonly schemaVersion: 1;
|
|
3
4
|
readonly kind: 'root-refactor-semantic-review';
|
|
@@ -35,3 +36,15 @@ export declare function acceptRootRefactorSemanticReview(projectRoot: string, ad
|
|
|
35
36
|
export declare function readRootRefactorSemanticReview(projectRoot: string, admissionSha256: string, baselineSha256: string): RefactorSemanticAcceptanceV1;
|
|
36
37
|
/** The report travels only over stdin and is never echoed on public CLI output. */
|
|
37
38
|
export declare function refactorReviewCliHandler(args: readonly string[]): Promise<number>;
|
|
39
|
+
export interface RefactorTargetSemanticReviewV2 extends Omit<RefactorSemanticReviewV1, 'schemaVersion' | 'kind' | 'storyId'> {
|
|
40
|
+
readonly schemaVersion: 2;
|
|
41
|
+
readonly kind: 'root-refactor-target-semantic-review';
|
|
42
|
+
readonly scopeId: string;
|
|
43
|
+
}
|
|
44
|
+
export interface RefactorTargetSemanticAcceptanceV2 extends Omit<RefactorSemanticAcceptanceV1, 'schemaVersion' | 'kind' | 'storyId'> {
|
|
45
|
+
readonly schemaVersion: 2;
|
|
46
|
+
readonly kind: 'root-refactor-target-semantic-acceptance';
|
|
47
|
+
readonly scopeId: string;
|
|
48
|
+
}
|
|
49
|
+
export declare function acceptRootRefactorTargetSemanticReview(projectRoot: string, admissionSha256: string, baselineSha256: string, targetInput: RefactorRootTargetV2, report: unknown, authorizeRootReview: boolean): RefactorTargetSemanticAcceptanceV2;
|
|
50
|
+
export declare function readRootRefactorTargetSemanticReview(projectRoot: string, admissionSha256: string, baselineSha256: string, targetInput: RefactorRootTargetV2): RefactorTargetSemanticAcceptanceV2;
|