@ornexus/neocortex 4.60.61 → 4.60.62
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 -0
- package/dist/sbom.cdx.json +150 -47
- package/install.ps1 +1 -1
- package/install.sh +1 -1
- package/package.json +9 -4
- package/packages/client/dist/cli.js +52 -2
- package/packages/client/dist/commands/invoke.d.ts +1 -0
- package/packages/client/dist/commands/invoke.js +80 -73
- package/packages/client/dist/commands/legacy-epic-terminal.d.ts +9 -0
- package/packages/client/dist/commands/legacy-epic-terminal.js +1 -0
- package/packages/client/dist/commands/legacy-story-pr.d.ts +2 -1
- package/packages/client/dist/commands/legacy-story-pr.js +1 -1
- package/packages/client/dist/commands/mutation-qa-checkpoint.d.ts +39 -0
- package/packages/client/dist/commands/mutation-qa-checkpoint.js +5 -0
- package/packages/client/dist/commands/mutation-qa-gate.d.ts +35 -0
- package/packages/client/dist/commands/mutation-qa-gate.js +1 -0
- package/packages/client/dist/commands/mutation-qa-git.d.ts +2 -0
- package/packages/client/dist/commands/mutation-qa-git.js +1 -0
- package/packages/client/dist/commands/mutation-qa-policy.d.ts +15 -0
- package/packages/client/dist/commands/mutation-qa-policy.js +1 -0
- package/packages/client/dist/commands/mutation-qa-run.d.ts +14 -0
- package/packages/client/dist/commands/mutation-qa-run.js +3 -0
- package/packages/client/dist/commands/mutation-qa-verdict.d.ts +21 -0
- package/packages/client/dist/commands/mutation-qa-verdict.js +1 -0
- package/packages/client/dist/commands/mutation-qa.d.ts +22 -0
- package/packages/client/dist/commands/mutation-qa.js +1 -0
- package/packages/client/dist/commands/property-qa.d.ts +1 -0
- package/packages/client/dist/commands/property-qa.js +1 -0
- package/packages/client/dist/commands/qa-scan-capture.d.ts +52 -0
- package/packages/client/dist/commands/qa-scan-capture.js +11 -0
- package/packages/client/dist/commands/qa-scan-discovery.d.ts +36 -0
- package/packages/client/dist/commands/qa-scan-discovery.js +3 -0
- package/packages/client/dist/commands/qa-scan-review.d.ts +119 -0
- package/packages/client/dist/commands/qa-scan-review.js +5 -0
- package/packages/client/dist/commands/refactor-characterization.d.ts +47 -0
- package/packages/client/dist/commands/refactor-characterization.js +12 -0
- package/packages/client/dist/commands/refactor-commit.d.ts +45 -0
- package/packages/client/dist/commands/refactor-commit.js +13 -0
- package/packages/client/dist/commands/refactor-review.d.ts +37 -0
- package/packages/client/dist/commands/refactor-review.js +5 -0
- package/packages/client/dist/commands/refactor-root.d.ts +85 -0
- package/packages/client/dist/commands/refactor-root.js +7 -0
- package/packages/client/dist/generated/command-registry.generated.d.ts +9 -9
- package/packages/client/dist/generated/command-registry.generated.js +1 -1
- package/packages/client/dist/generated/public-projections.generated.d.ts +20 -20
- package/packages/client/dist/generated/public-projections.generated.js +1 -1
- package/packages/client/dist/git/legacy-story-pr.d.ts +137 -6
- package/packages/client/dist/git/legacy-story-pr.js +51 -43
- package/packages/client/dist/license/license-client.js +1 -1
- package/packages/client/dist/private-execution/delivery.d.ts +49 -4
- package/packages/client/dist/private-execution/delivery.js +4 -2
- package/packages/client/dist/private-execution/isolated-admission.d.ts +7 -0
- package/packages/client/dist/private-execution/isolated-admission.js +10 -10
- package/packages/client/dist/private-execution/private-report-store.d.ts +17 -0
- package/packages/client/dist/private-execution/private-report-store.js +1 -0
- package/packages/client/dist/private-execution/property-test-candidate.d.ts +14 -0
- package/packages/client/dist/private-execution/property-test-candidate.js +1 -0
- package/packages/client/dist/private-execution/property-test-choices.d.ts +15 -0
- package/packages/client/dist/private-execution/property-test-choices.js +3 -0
- package/packages/client/dist/private-execution/property-test-plan.d.ts +65 -0
- package/packages/client/dist/private-execution/property-test-plan.js +7 -0
- package/packages/client/dist/private-execution/property-test-review.d.ts +58 -0
- package/packages/client/dist/private-execution/property-test-review.js +4 -0
- package/packages/client/dist/private-execution/property-test-runtime.d.ts +18 -0
- package/packages/client/dist/private-execution/property-test-runtime.js +9 -0
- package/packages/client/dist/private-execution/property-test-source.d.ts +8 -0
- package/packages/client/dist/private-execution/property-test-source.js +1 -0
- package/packages/client/dist/state/project-state-snapshot.js +1 -1
- package/packages/shared/dist/generated/command-registry.generated.js +9 -9
- package/packages/shared/dist/generated/invocation-schema.generated.js +2 -2
- package/packages/shared/dist/generated/public-projections.generated.js +18 -18
- package/packages/shared/dist/invocation/index.d.ts +1 -1
- package/packages/shared/dist/invocation/index.js +13 -0
- package/packages/shared/dist/merge-readiness/c12-registry-projection.js +111 -0
- package/packages/shared/dist/merge-readiness/c12-remote-observation.js +60 -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,119 @@
|
|
|
1
|
+
declare const KINDS: readonly ["visual", "responsive", "responsive-tablet", "responsive-desktop", "accessibility", "interaction", "console-network", "performance"];
|
|
2
|
+
type Kind = (typeof KINDS)[number];
|
|
3
|
+
/** An IHDR-sized prefix is not a screenshot. Check the bounded PNG stream,
|
|
4
|
+
* chunk checksums and decompressed scanlines before an approved QA verdict. */
|
|
5
|
+
export declare function validateRootQaScanPng(bytes: Buffer, kind: 'visual' | 'responsive' | 'responsive-tablet' | 'responsive-desktop'): boolean;
|
|
6
|
+
/** The capture adapter may write only beneath the same private directory that
|
|
7
|
+
* the independent root reviewer reopens and hashes. */
|
|
8
|
+
export declare function rootQaScanEvidenceDirectory(projectRoot: string): string;
|
|
9
|
+
export interface RootQaScanPlanV1 {
|
|
10
|
+
readonly schemaVersion: 1;
|
|
11
|
+
readonly evidenceContractVersion: 2;
|
|
12
|
+
readonly kind: 'root-qa-scan-plan';
|
|
13
|
+
readonly sourceHead: string;
|
|
14
|
+
readonly surface: string;
|
|
15
|
+
readonly targetSha256: string;
|
|
16
|
+
readonly planSha256: string;
|
|
17
|
+
readonly requiredKinds: readonly Kind[];
|
|
18
|
+
readonly qaAccepted: false;
|
|
19
|
+
readonly localOnly: true;
|
|
20
|
+
}
|
|
21
|
+
export interface RootQaScanObservationV1 {
|
|
22
|
+
readonly kind: Kind;
|
|
23
|
+
readonly artifactId: string;
|
|
24
|
+
readonly captureMethod: string;
|
|
25
|
+
readonly sha256: string;
|
|
26
|
+
readonly capturedAt: string;
|
|
27
|
+
readonly rationale: string;
|
|
28
|
+
}
|
|
29
|
+
export interface RootQaScanReportV1 {
|
|
30
|
+
readonly schemaVersion: 1;
|
|
31
|
+
readonly evidenceContractVersion: 2;
|
|
32
|
+
readonly kind: 'root-qa-scan-report';
|
|
33
|
+
readonly sourceHead: string;
|
|
34
|
+
readonly planSha256: string;
|
|
35
|
+
readonly surface: string;
|
|
36
|
+
readonly targetSha256: string;
|
|
37
|
+
readonly verdict: 'approved' | 'issues-found';
|
|
38
|
+
readonly observations: readonly RootQaScanObservationV1[];
|
|
39
|
+
readonly issues: readonly {
|
|
40
|
+
readonly severity: 'critical' | 'high' | 'medium' | 'low';
|
|
41
|
+
readonly evidenceArtifactId: string;
|
|
42
|
+
readonly summary: string;
|
|
43
|
+
}[];
|
|
44
|
+
}
|
|
45
|
+
export interface RootQaScanReviewReceiptV1 {
|
|
46
|
+
readonly schemaVersion: 1;
|
|
47
|
+
readonly evidenceContractVersion: 2;
|
|
48
|
+
readonly kind: 'root-qa-scan-review';
|
|
49
|
+
readonly sourceHead: string;
|
|
50
|
+
readonly planSha256: string;
|
|
51
|
+
readonly evidenceSha256: string;
|
|
52
|
+
readonly reviewSha256: string;
|
|
53
|
+
readonly evidenceCount: 8;
|
|
54
|
+
readonly issueCount: number;
|
|
55
|
+
readonly verdict: 'approved' | 'issues-found';
|
|
56
|
+
readonly qaAccepted: boolean;
|
|
57
|
+
readonly checkpointAccepted: false;
|
|
58
|
+
readonly workflowContinuationAuthorized: false;
|
|
59
|
+
readonly localOnly: true;
|
|
60
|
+
readonly publicSafe: true;
|
|
61
|
+
}
|
|
62
|
+
export interface RootQaScanAggregateV1 {
|
|
63
|
+
readonly schemaVersion: 1;
|
|
64
|
+
readonly evidenceContractVersion: 2;
|
|
65
|
+
readonly kind: 'root-qa-scan-aggregate';
|
|
66
|
+
readonly sourceHead: string;
|
|
67
|
+
readonly aggregateSha256: string;
|
|
68
|
+
readonly surfaceCount: number;
|
|
69
|
+
readonly evidenceCount: number;
|
|
70
|
+
readonly issueCount: number;
|
|
71
|
+
readonly verdict: 'approved' | 'issues-found';
|
|
72
|
+
readonly qaAccepted: boolean;
|
|
73
|
+
readonly checkpointAccepted: false;
|
|
74
|
+
readonly workflowContinuationAuthorized: false;
|
|
75
|
+
readonly localOnly: true;
|
|
76
|
+
readonly publicSafe: true;
|
|
77
|
+
}
|
|
78
|
+
/** A root-owned terminal synthesis of the three Q-phase evidence boundaries.
|
|
79
|
+
* It does not assert that a private Q01–Q03 agent ran or grant workflow effects. */
|
|
80
|
+
export interface RootQaScanPhaseCheckpointV1 {
|
|
81
|
+
readonly schemaVersion: 1;
|
|
82
|
+
readonly evidenceContractVersion: 2;
|
|
83
|
+
readonly kind: 'root-qa-scan-phase-checkpoint';
|
|
84
|
+
readonly sourceHead: string;
|
|
85
|
+
readonly aggregateSha256: string;
|
|
86
|
+
readonly surfaceCount: number;
|
|
87
|
+
readonly q01DiscoveryEvidenceValidated: true;
|
|
88
|
+
readonly q02InteractionEvidenceValidated: true;
|
|
89
|
+
readonly q03RootTriageValidated: true;
|
|
90
|
+
readonly qaAccepted: boolean;
|
|
91
|
+
readonly rootPhaseCheckpointAccepted: true;
|
|
92
|
+
readonly workflowContinuationAuthorized: false;
|
|
93
|
+
readonly localOnly: true;
|
|
94
|
+
readonly publicSafe: true;
|
|
95
|
+
}
|
|
96
|
+
/** Creates only an owner-private evidence directory; no project or QA state is changed. */
|
|
97
|
+
export declare function planRootQaScan(projectRoot: string, surface: string, targetUrl: string): RootQaScanPlanV1;
|
|
98
|
+
/** The root must independently inspect every physical artifact before signing this report. */
|
|
99
|
+
export declare function validateRootQaScanReview(projectRoot: string, surface: string, targetUrl: string, input: unknown): {
|
|
100
|
+
readonly plan: RootQaScanPlanV1;
|
|
101
|
+
readonly report: RootQaScanReportV1;
|
|
102
|
+
readonly evidenceSha256: string;
|
|
103
|
+
readonly reviewSha256: string;
|
|
104
|
+
};
|
|
105
|
+
/** Immutable local record: a tested report is not inferred from a server selection. */
|
|
106
|
+
export declare function acceptRootQaScanReview(projectRoot: string, surface: string, targetUrl: string, input: unknown): RootQaScanReviewReceiptV1;
|
|
107
|
+
/** Rechecks the private report and every artifact against the current physical source. */
|
|
108
|
+
export declare function readRootQaScanReview(projectRoot: string, surface: string, targetUrl: string): RootQaScanReviewReceiptV1;
|
|
109
|
+
/** Reopens every independent root verdict and its eight physical artifacts.
|
|
110
|
+
* This is a multi-surface observation, never Q01–Q03 state or release authority. */
|
|
111
|
+
export declare function aggregateRootQaScanReviews(projectRoot: string, input: unknown): RootQaScanAggregateV1;
|
|
112
|
+
/** Revalidates every private review and artifact, then saves an immutable root
|
|
113
|
+
* synthesis. This is local QA state only, never a server graph advancement. */
|
|
114
|
+
export declare function acceptRootQaScanPhaseCheckpoint(projectRoot: string, input: unknown): RootQaScanPhaseCheckpointV1;
|
|
115
|
+
/** A checkpoint is valid only while the current source and all underlying
|
|
116
|
+
* root reviews and artifacts still match its immutable aggregate. */
|
|
117
|
+
export declare function readRootQaScanPhaseCheckpoint(projectRoot: string, input: unknown): RootQaScanPhaseCheckpointV1;
|
|
118
|
+
export declare function qaScanReviewCliHandler(args: readonly string[]): Promise<number>;
|
|
119
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{createHash as he,randomUUID as Y}from"node:crypto";import{closeSync as x,constants as X,existsSync as D,fstatSync as Z,fsyncSync as J,linkSync as ee,lstatSync as k,mkdirSync as re,openSync as z,readFileSync as j,realpathSync as B,unlinkSync as te,writeFileSync as ne}from"node:fs";import{isAbsolute as ve,join as b,resolve as E}from"node:path";import{inflateSync as pe}from"node:zlib";import{mutationQaGit as T}from"./mutation-qa-git.js";const F=/^[a-f0-9]{64}$/,we=/^[a-z][a-z0-9-]{0,63}$/,ge=/^[a-z][a-z0-9-]{0,63}\.(?:png|json)$/,oe=8*1024*1024,Q=128*1024,V=2,se=Buffer.from([137,80,78,71,13,10,26,10]),ye=Uint32Array.from({length:256},(r,t)=>{let e=t;for(let n=0;n<8;n++)e=(e&1)!==0?3988292384^e>>>1:e>>>1;return e>>>0}),M=["visual","responsive","responsive-tablet","responsive-desktop","accessibility","interaction","console-network","performance"],Se=Object.freeze({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"}),me=Object.freeze({visual:"PNG 8-bit non-interlaced CRC+IDAT verified; width=1440, 600<=height<=4096, pixels<=8000000",responsive:"PNG 8-bit non-interlaced CRC+IDAT verified; width=375, 600<=height<=4096","responsive-tablet":"PNG 8-bit non-interlaced CRC+IDAT verified; width=768, 600<=height<=4096","responsive-desktop":"PNG 8-bit non-interlaced CRC+IDAT verified; width=1024, 600<=height<=4096",accessibility:"JSON: schemaVersion=1 engine=axe-core violationCount=0 incompleteCount=0 passCount>0",interaction:"JSON: schemaVersion=2 syntheticTarget=true networkAttemptsAfterAction=0 checks=[{id:functional-safe-slug,passed:true}] (1..32 distinct)","console-network":"JSON: schemaVersion=1 initialCapture=true consoleErrors=0 pageErrors=0 failedRequests=0 requestsObserved>0",performance:"JSON: schemaVersion=1 metric=load 0<=observedMs<=budgetMs<=30000"});function _(r,t=1e6){return Number.isSafeInteger(r)&&r>=0&&r<=t}function qe(r,t,e){let n=4294967295;for(let o=t;o<e;o++)n=ye[(n^r[o])&255]^n>>>8;return(n^4294967295)>>>0}function Ee(r,t){if(r.length<57||!r.subarray(0,8).equals(se))return!1;let e=8,n=0,o=0,s=0,c=0,d=!1,a=!1,g=!1,f=!1,l=0;const p=[];for(;e<r.length;){if(++l>1024||r.length-e<12)return!1;const w=r.readUInt32BE(e),S=e+8+w,$=S+4;if(w>oe||$>r.length)return!1;const A=r.toString("ascii",e+4,e+8);if(!/^[A-Za-z]{4}$/.test(A)||qe(r,e+4,S)!==r.readUInt32BE(S))return!1;if(A==="IHDR"){if(d||e!==8||w!==13||(d=!0,n=r.readUInt32BE(e+8),o=r.readUInt32BE(e+12),c=r[e+17],s=c===0?1:c===2?3:c===4?2:c===6?4:0,!s||r[e+16]!==8||r[e+18]!==0||r[e+19]!==0||r[e+20]!==0||n<1||o<1||n>4096||o>4096||n*o>8e6))return!1}else if(A==="IDAT"){if(!d||f||w===0)return!1;p.push(r.subarray(e+8,S))}else if(A==="PLTE"){if(!d||g||p.length>0||c!==2&&c!==6||w===0||w>768||w%3!==0)return!1;g=!0}else if(A==="IEND"){if(!d||p.length===0||w!==0||$!==r.length)return!1;a=!0;break}else{if(!d||A[0]===A[0]?.toUpperCase())return!1;p.length&&(f=!0)}e=$}const y={visual:1440,responsive:375,"responsive-tablet":768,"responsive-desktop":1024}[t];if(!a||n!==y||o<600)return!1;const i=n*s,v=o*(i+1);try{const w=pe(Buffer.concat(p),{maxOutputLength:v+1});if(w.length!==v)return!1;for(let S=0;S<o;S++)if(w[S*(i+1)]>4)return!1;return!0}catch{return!1}}function Ae(r,t){if(r==="visual"||r==="responsive"||r==="responsive-tablet"||r==="responsive-desktop")return Ee(t,r);let e;try{e=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(t))}catch{return!1}if(r==="accessibility")return m(e,["schemaVersion","engine","violationCount","incompleteCount","passCount"])&&e.schemaVersion===1&&e.engine==="axe-core"&&e.violationCount===0&&e.incompleteCount===0&&_(e.passCount)&&e.passCount>0;if(r==="interaction"){if(!m(e,["schemaVersion","syntheticTarget","networkAttemptsAfterAction","checks"])||e.schemaVersion!==2||e.syntheticTarget!==!0||e.networkAttemptsAfterAction!==0||!Array.isArray(e.checks)||e.checks.length<1||e.checks.length>32)return!1;const n=new Set;return e.checks.every(o=>!m(o,["id","passed"])||typeof o.id!="string"||!/^functional-[a-z][a-z0-9-]{0,50}$/.test(o.id)||n.has(o.id)||o.passed!==!0?!1:(n.add(o.id),!0))}return r==="console-network"?m(e,["schemaVersion","initialCapture","consoleErrors","pageErrors","failedRequests","requestsObserved"])&&e.schemaVersion===1&&e.initialCapture===!0&&e.consoleErrors===0&&e.pageErrors===0&&e.failedRequests===0&&_(e.requestsObserved)&&e.requestsObserved>0:m(e,["schemaVersion","metric","observedMs","budgetMs"])&&e.schemaVersion===1&&e.metric==="load"&&_(e.observedMs,3e4)&&_(e.budgetMs,3e4)&&e.budgetMs>0&&e.observedMs<=e.budgetMs}function C(r){return he("sha256").update(r).digest("hex")}function m(r,t){return r!==null&&typeof r=="object"&&!Array.isArray(r)&&Object.keys(r).sort().join("\0")===[...t].sort().join("\0")}function I(r,t){const e=T(r,["rev-parse","--git-common-dir"]).toString("utf8").trim(),n=ve(e)?E(e):E(r,e);if(B(n)!==n||k(n).isSymbolicLink()||k(n).uid!==process.getuid?.())throw new Error("qa-scan-review-unverified");const o=b(n,"neocortex-qa-scan");t&&re(o,{recursive:!0,mode:448});const s=k(o);if(!s.isDirectory()||s.isSymbolicLink()||s.uid!==process.getuid?.()||(s.mode&63)!==0)throw new Error("qa-scan-review-unverified");return o}function H(r,t){const e=b(I(r,t),"evidence");t&&re(e,{recursive:!0,mode:448});const n=k(e);if(!n.isDirectory()||n.isSymbolicLink()||n.uid!==process.getuid?.()||(n.mode&63)!==0)throw new Error("qa-scan-review-unverified");return e}function ze(r){return H(E(r),!1)}function L(r){if(B(r)!==r||!k(r).isDirectory()||T(r,["rev-parse","--show-toplevel"]).toString("utf8").trim()!==r)throw new Error("qa-scan-review-unverified");if(T(r,["status","--porcelain=v1","-z","--untracked-files=all"]).toString("utf8").split("\0").filter(Boolean).some(n=>!/^.{2} \.neocortex\//.test(n)))throw new Error("qa-scan-review-source-dirty");const e=T(r,["rev-parse","--verify","HEAD"]).toString("utf8").trim();if(!/^[a-f0-9]{40}(?:[a-f0-9]{24})?$/.test(e))throw new Error("qa-scan-review-unverified");return e}function ke(r){let t;try{t=new URL(r)}catch{throw new Error("qa-scan-review-target-invalid")}if(t.protocol!=="http:"||!["127.0.0.1","localhost","[::1]"].includes(t.hostname)||!t.port||t.username||t.password||t.search||t.hash)throw new Error("qa-scan-review-target-invalid");return C(`qa-scan-loopback-target-v1\0${t.href}`)}function P(r,t,e){try{if(!we.test(t))throw new Error("qa-scan-review-surface-invalid");const n=E(r),o=L(n),s=ke(e);H(n,!0);const c={schemaVersion:1,evidenceContractVersion:V,kind:"root-qa-scan-plan",sourceHead:o,surface:t,targetSha256:s,requiredKinds:M,qaAccepted:!1,localOnly:!0};return Object.freeze({...c,planSha256:C(`root-qa-scan-plan-v2\0${JSON.stringify(c)}`)})}catch(n){throw n instanceof Error&&n.message.startsWith("qa-scan-review-")?n:new Error("qa-scan-review-unverified")}}function ie(r,t){const e=new Set,n=[];for(const o of t.observations){if(!m(o,["kind","artifactId","captureMethod","sha256","capturedAt","rationale"])||!M.includes(o.kind)||!ge.test(o.artifactId)||e.has(o.artifactId)||o.captureMethod!==Se[o.kind]||!F.test(o.sha256)||typeof o.rationale!="string"||o.rationale.length<30||o.rationale.length>500||/[\x00-\x1f\x7f]/.test(o.rationale))throw new Error("qa-scan-review-unverified");const s=typeof o.capturedAt=="string"?Date.parse(o.capturedAt):NaN;if(!Number.isFinite(s)||new Date(s).toISOString()!==o.capturedAt||s>Date.now()+5*6e4||Date.now()-s>60*6e4)throw new Error("qa-scan-review-unverified");e.add(o.artifactId);const c=b(H(r,!1),o.artifactId),d=k(c);if(!d.isFile()||d.isSymbolicLink()||d.uid!==process.getuid?.()||(d.mode&63)!==0||d.size<8||d.size>oe||B(c)!==c)throw new Error("qa-scan-review-unverified");const a=z(c,X.O_RDONLY|(X.O_NOFOLLOW??0));let g;try{const f=Z(a);if(!f.isFile()||f.dev!==d.dev||f.ino!==d.ino||f.uid!==d.uid||f.size!==d.size)throw new Error("qa-scan-review-unverified");g=j(a);const l=Z(a),p=k(c);if(l.dev!==f.dev||l.ino!==f.ino||l.size!==f.size||l.mtimeMs!==f.mtimeMs||l.ctimeMs!==f.ctimeMs||p.dev!==f.dev||p.ino!==f.ino)throw new Error("qa-scan-review-unverified")}finally{x(a)}if(C(g)!==o.sha256)throw new Error("qa-scan-review-unverified");if(o.artifactId.endsWith(".png")){if(o.captureMethod!=="browser-screenshot"||!g.subarray(0,8).equals(se))throw new Error("qa-scan-review-unverified")}else{if(o.captureMethod==="browser-screenshot")throw new Error("qa-scan-review-unverified");try{const f=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(g));if(!f||typeof f!="object"||Array.isArray(f))throw new Error}catch{throw new Error("qa-scan-review-unverified")}}if(t.verdict==="approved"&&!Ae(o.kind,g))throw new Error("qa-scan-review-unverified");n.push(`${o.kind}:${o.artifactId}:${o.sha256}`)}return C(`root-qa-scan-evidence-v2\0${n.sort().join("\0")}`)}function G(r,t,e,n){try{const o=P(r,t,e);if(!m(n,["schemaVersion","evidenceContractVersion","kind","sourceHead","planSha256","surface","targetSha256","verdict","observations","issues"])||n.schemaVersion!==1||n.evidenceContractVersion!==V||n.kind!=="root-qa-scan-report"||n.sourceHead!==o.sourceHead||n.planSha256!==o.planSha256||n.surface!==o.surface||n.targetSha256!==o.targetSha256||n.verdict!=="approved"&&n.verdict!=="issues-found"||!Array.isArray(n.observations)||n.observations.length!==M.length||!Array.isArray(n.issues)||n.issues.length>128||Buffer.byteLength(JSON.stringify(n))>Q)throw new Error("qa-scan-review-unverified");const s=n;if(s.observations.map(a=>a.kind).sort().join("\0")!==[...M].sort().join("\0"))throw new Error("qa-scan-review-unverified");const c=ie(E(r),s),d=new Set(s.observations.map(a=>a.artifactId));for(const a of s.issues)if(!m(a,["severity","evidenceArtifactId","summary"])||!["critical","high","medium","low"].includes(a.severity)||!d.has(a.evidenceArtifactId)||typeof a.summary!="string"||a.summary.length<20||a.summary.length>500||/[\x00-\x1f\x7f]/.test(a.summary))throw new Error("qa-scan-review-unverified");if(s.verdict==="approved"!=(s.issues.length===0))throw new Error("qa-scan-review-unverified");if(L(E(r))!==o.sourceHead||ie(E(r),s)!==c)throw new Error("qa-scan-review-unverified");return Object.freeze({plan:o,report:s,evidenceSha256:c,reviewSha256:C(`root-qa-scan-review-v2\0${JSON.stringify(s)}`)})}catch{throw new Error("qa-scan-review-unverified")}}function ae(r){return Object.freeze({schemaVersion:1,evidenceContractVersion:V,kind:"root-qa-scan-review",sourceHead:r.plan.sourceHead,planSha256:r.plan.planSha256,evidenceSha256:r.evidenceSha256,reviewSha256:r.reviewSha256,evidenceCount:8,issueCount:r.report.issues.length,verdict:r.report.verdict,qaAccepted:r.report.verdict==="approved",checkpointAccepted:!1,workflowContinuationAuthorized:!1,localOnly:!0,publicSafe:!0})}function Ce(r,t,e,n){try{const o=E(r),s=G(o,t,e,n),c=ae(s),d=I(o,!0),a=b(d,`review-${c.planSha256}.json`),g={report:s.report,receipt:c},f={schemaVersion:1,kind:"root-qa-scan-review-record",...g,checksumSha256:C(`root-qa-scan-review-record-v1\0${JSON.stringify(g)}`)},l=`${JSON.stringify(f)}
|
|
2
|
+
`;if(D(a)){const i=k(a);if(!i.isFile()||i.isSymbolicLink()||i.uid!==process.getuid?.()||(i.mode&63)!==0||j(a,"utf8")!==l)throw new Error("qa-scan-review-unverified");return c}const p=b(d,`review-${Y()}.tmp`),y=z(p,"wx",384);try{ne(y,l),J(y)}finally{x(y)}try{if(G(o,t,e,n).reviewSha256!==c.reviewSha256)throw new Error("qa-scan-review-unverified");ee(p,a);const i=z(d,"r");try{J(i)}finally{x(i)}}finally{D(p)&&te(p)}return c}catch{throw new Error("qa-scan-review-unverified")}}function ce(r,t,e){try{const n=E(r),o=P(n,t,e),s=b(I(n,!1),`review-${o.planSha256}.json`),c=k(s);if(!c.isFile()||c.isSymbolicLink()||c.uid!==process.getuid?.()||(c.mode&63)!==0||c.size<1||c.size>Q+4096)throw new Error("qa-scan-review-unverified");const d=j(s,"utf8"),a=JSON.parse(d);if(!m(a,["schemaVersion","kind","report","receipt","checksumSha256"])||a.schemaVersion!==1||a.kind!=="root-qa-scan-review-record"||typeof a.checksumSha256!="string"||!F.test(a.checksumSha256)||d!==`${JSON.stringify(a)}
|
|
3
|
+
`)throw new Error("qa-scan-review-unverified");const g={report:a.report,receipt:a.receipt};if(a.checksumSha256!==C(`root-qa-scan-review-record-v1\0${JSON.stringify(g)}`))throw new Error("qa-scan-review-unverified");const f=G(n,t,e,a.report),l=ae(f);if(!m(a.receipt,Object.keys(l))||JSON.stringify(a.receipt)!==JSON.stringify(l))throw new Error("qa-scan-review-unverified");return l}catch{throw new Error("qa-scan-review-unverified")}}function U(r,t){try{if(!m(t,["schemaVersion","targets"])||t.schemaVersion!==1||!Array.isArray(t.targets)||t.targets.length<2||t.targets.length>16)throw new Error("qa-scan-review-aggregate-unverified");const e=E(r),n=L(e),o=new Set,s=new Set;let c;const d=t.targets.map(i=>{if(!m(i,["surface","targetUrl"])||typeof i.surface!="string"||typeof i.targetUrl!="string"||o.has(i.surface))throw new Error("qa-scan-review-aggregate-unverified");const v=P(e,i.surface,i.targetUrl),w=new URL(i.targetUrl).origin;if(v.sourceHead!==n||s.has(v.targetSha256)||c!==void 0&&c!==w)throw new Error("qa-scan-review-aggregate-unverified");return c=w,o.add(i.surface),s.add(v.targetSha256),{surface:i.surface,targetUrl:i.targetUrl,plan:v}}).sort((i,v)=>i.surface<v.surface?-1:i.surface>v.surface?1:0),a=()=>d.map(({surface:i,targetUrl:v,plan:w})=>{const S=ce(e,i,v);if(S.sourceHead!==n||S.planSha256!==w.planSha256)throw new Error("qa-scan-review-aggregate-unverified");return S}),g=a(),f=a();if(L(e)!==n||JSON.stringify(g)!==JSON.stringify(f))throw new Error("qa-scan-review-aggregate-unverified");if(new Set(f.map(i=>i.evidenceSha256)).size!==f.length)throw new Error("qa-scan-review-aggregate-unverified");const l=f.reduce((i,v)=>i+v.issueCount,0),p=f.every(i=>i.qaAccepted&&i.verdict==="approved"),y=C(`root-qa-scan-aggregate-v2\0${n}\0${f.map(i=>[i.planSha256,i.evidenceSha256,i.reviewSha256,i.verdict,i.issueCount].join(":")).join("\0")}`);return Object.freeze({schemaVersion:1,evidenceContractVersion:V,kind:"root-qa-scan-aggregate",sourceHead:n,aggregateSha256:y,surfaceCount:f.length,evidenceCount:f.reduce((i,v)=>i+v.evidenceCount,0),issueCount:l,verdict:p?"approved":"issues-found",qaAccepted:p,checkpointAccepted:!1,workflowContinuationAuthorized:!1,localOnly:!0,publicSafe:!0})}catch{throw new Error("qa-scan-review-aggregate-unverified")}}function K(r){if(r.qaAccepted&&(r.verdict!=="approved"||r.issueCount!==0)||!r.qaAccepted&&(r.verdict!=="issues-found"||r.issueCount<1))throw new Error("qa-scan-review-phase-unverified");return Object.freeze({schemaVersion:1,evidenceContractVersion:V,kind:"root-qa-scan-phase-checkpoint",sourceHead:r.sourceHead,aggregateSha256:r.aggregateSha256,surfaceCount:r.surfaceCount,q01DiscoveryEvidenceValidated:!0,q02InteractionEvidenceValidated:!0,q03RootTriageValidated:!0,qaAccepted:r.qaAccepted,rootPhaseCheckpointAccepted:!0,workflowContinuationAuthorized:!1,localOnly:!0,publicSafe:!0})}function Oe(r,t){try{const e=E(r),n=U(e,t),o=K(n),s=I(e,!0),c=b(s,`phase-${o.aggregateSha256}.json`),d={receipt:o},a={schemaVersion:1,kind:"root-qa-scan-phase-record",...d,checksumSha256:C(`root-qa-scan-phase-record-v1\0${JSON.stringify(d)}`)},g=`${JSON.stringify(a)}
|
|
4
|
+
`;if(D(c)){if(de(e,t).aggregateSha256!==o.aggregateSha256)throw new Error("qa-scan-review-phase-unverified");return o}const f=b(s,`phase-${Y()}.tmp`),l=z(f,"wx",384);try{ne(l,g),J(l)}finally{x(l)}try{const p=K(U(e,t));if(JSON.stringify(p)!==JSON.stringify(o))throw new Error("qa-scan-review-phase-unverified");ee(f,c);const y=z(s,"r");try{J(y)}finally{x(y)}}finally{D(f)&&te(f)}return o}catch{throw new Error("qa-scan-review-phase-unverified")}}function de(r,t){try{const e=E(r),n=K(U(e,t)),o=b(I(e,!1),`phase-${n.aggregateSha256}.json`),s=k(o);if(!s.isFile()||s.isSymbolicLink()||s.uid!==process.getuid?.()||(s.mode&63)!==0||s.size<1||s.size>4096)throw new Error("qa-scan-review-phase-unverified");const c=j(o,"utf8"),d=JSON.parse(c);if(!m(d,["schemaVersion","kind","receipt","checksumSha256"])||d.schemaVersion!==1||d.kind!=="root-qa-scan-phase-record"||d.checksumSha256!==C(`root-qa-scan-phase-record-v1\0${JSON.stringify({receipt:d.receipt})}`)||!m(d.receipt,Object.keys(n))||JSON.stringify(d.receipt)!==JSON.stringify(n)||c!==`${JSON.stringify(d)}
|
|
5
|
+
`)throw new Error("qa-scan-review-phase-unverified");return n}catch{throw new Error("qa-scan-review-phase-unverified")}}async function Ve(r){const t=r[0];let e=process.cwd(),n="",o="",s="plain",c=!1,d=!1,a=!1,g=!1,f=!1,l="",p="",y="";const i=new Set;try{if(t!=="plan"&&t!=="capture"&&t!=="interact"&&t!=="accept"&&t!=="status"&&t!=="aggregate"&&t!=="phase-checkpoint"&&t!=="phase-status"&&t!=="discover"&&t!=="discovery-status"&&t!=="discovered-phase-checkpoint"&&t!=="discovered-phase-status")throw new Error("qa-scan-review-action-invalid");for(let u=1;u<r.length;u++){const h=r[u];if(i.has(h))throw new Error("qa-scan-review-argument-duplicate");i.add(h);const q=()=>r[++u]??"";if(h==="--project-root")e=q();else if(h==="--surface")n=q();else if(h==="--target-url")o=q();else if(h==="--action-id")p=q();else if(h==="--expected-status")y=q();else if(h==="--discovery-sha")l=q();else if(h==="--format"){const O=q();if(O!=="json"&&O!=="plain")throw new Error("qa-scan-review-format-invalid");s=O}else if(h==="--authorize-review")c=!0;else if(h==="--authorize-capture")d=!0;else if(h==="--authorize-interaction")a=!0;else if(h==="--authorize-discovery")g=!0;else if(h==="--authorize-root-checkpoint")f=!0;else throw new Error("qa-scan-review-argument-invalid")}const v=t==="discovered-phase-checkpoint"||t==="discovered-phase-status",w=t==="aggregate"||t==="phase-checkpoint"||t==="phase-status"||v,S=t==="discover"||t==="discovery-status",$=t==="phase-checkpoint"||t==="discovered-phase-checkpoint";if(!e||(w||t==="discovery-status"?i.has("--surface")||i.has("--target-url"):t==="discover"?i.has("--surface")||!o:!n||!o)||c!==(t==="accept")||d!==(t==="capture")||a!==(t==="interact")||g!==(t==="discover")||f!==$||(v||t==="discovery-status"?!F.test(l):i.has("--discovery-sha"))||(t==="interact"?!p||!y:i.has("--action-id")||i.has("--expected-status")))throw new Error("qa-scan-review-authorization-or-target-required");if(w){let u="";for await(const le of process.stdin)if(u+=String(le),Buffer.byteLength(u)>Q)throw new Error("qa-scan-review-too-large");const{parseDocument:h}=await import("yaml"),q=h(u,{strict:!0,uniqueKeys:!0,schema:"core",customTags:[]});if(q.errors.length||q.warnings.length)throw new Error(t==="aggregate"?"qa-scan-review-aggregate-unverified":"qa-scan-review-phase-unverified");const O=JSON.parse(u),N=v?t==="discovered-phase-checkpoint"?(await import("./qa-scan-discovery.js")).acceptRootQaScanDiscoveredPhase(e,l,O):(await import("./qa-scan-discovery.js")).readRootQaScanDiscoveredPhase(e,l,O):t==="aggregate"?U(e,O):t==="phase-checkpoint"?Oe(e,O):de(e,O);return s==="json"?console.log(JSON.stringify(N)):"verdict"in N?console.log(`Root QA scan aggregate ${N.verdict}; surfaces=${N.surfaceCount}, issues=${N.issueCount}, workflow-continuation=unauthorized`):console.log(`Root QA scan bounded local evidence checkpoint; surfaces=${N.surfaceCount}, qa-accepted=${N.qaAccepted}, workflow-continuation=unauthorized`),N.qaAccepted?0:2}if(S){const{discoverRootQaScanLinks:u,readRootQaScanDiscovery:h}=await import("./qa-scan-discovery.js"),q=t==="discover"?await u({projectRoot:e,seedUrl:o,authorizeDiscovery:g}):h(e,l);return console.log(s==="json"?JSON.stringify(q):`Root QA scan link inventory; targets=${q.targetCount}, QA=not-accepted`),0}if(t==="capture"){const{captureRootQaScan:u}=await import("./qa-scan-capture.js"),h=await u({projectRoot:e,surface:n,targetUrl:o,authorizeCapture:d});return console.log(s==="json"?JSON.stringify(h):`Root QA scan captured ${h.evidenceCount} private artifacts; independent review required`),0}if(t==="interact"){const{captureRootQaScanInteraction:u}=await import("./qa-scan-capture.js"),h=await u({projectRoot:e,surface:n,targetUrl:o,actionId:p,expectedStatus:y,authorizeInteraction:a});return console.log(s==="json"?JSON.stringify(h):"Root QA scan synthetic interaction captured; independent review required"),0}if(t==="plan"){const u=P(e,n,o),h=H(E(e),!1);return console.log(s==="json"?JSON.stringify({plan:u,evidenceDirectory:h,approvedEvidenceContract:me}):`Root QA scan plan ${u.planSha256}; evidence directory ${h}; no QA accepted; use --format json for approved evidence contract`),0}if(t==="status"){const u=ce(e,n,o);return console.log(s==="json"?JSON.stringify(u):`Root QA scan ${u.verdict}; evidence=${u.evidenceCount}, issues=${u.issueCount}, qaAccepted=${u.qaAccepted}`),u.qaAccepted?0:2}let A="";for await(const u of process.stdin)if(A+=String(u),Buffer.byteLength(A)>Q)throw new Error("qa-scan-review-too-large");const{parseDocument:fe}=await import("yaml"),W=fe(A,{strict:!0,uniqueKeys:!0,schema:"core",customTags:[]});if(W.errors.length||W.warnings.length)throw new Error("qa-scan-review-unverified");const ue=JSON.parse(A),R=Ce(e,n,o,ue);return console.log(s==="json"?JSON.stringify(R):`Root QA scan ${R.verdict}; evidence=${R.evidenceCount}, issues=${R.issueCount}, qaAccepted=${R.qaAccepted}`),R.qaAccepted?0:2}catch(v){const w=v instanceof Error&&/^qa-scan-review-[a-z-]+$/.test(v.message)?v.message:"qa-scan-review-unverified";return s==="json"?console.log(JSON.stringify({ok:!1,reasonCode:w})):console.error(w),1}}export{Oe as acceptRootQaScanPhaseCheckpoint,Ce as acceptRootQaScanReview,U as aggregateRootQaScanReviews,P as planRootQaScan,Ve as qaScanReviewCliHandler,de as readRootQaScanPhaseCheckpoint,ce as readRootQaScanReview,ze as rootQaScanEvidenceDirectory,Ee as validateRootQaScanPng,G as validateRootQaScanReview};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export type RefactorCharacterizationRunner = 'native' | 'vitest';
|
|
2
|
+
/** Node's native type-stripping switch first exists in 22.6.0. */
|
|
3
|
+
export declare function supportsNativeTypeStrippingVersion(version: string): boolean;
|
|
4
|
+
interface FileDigest {
|
|
5
|
+
readonly path: string;
|
|
6
|
+
readonly sha256: string;
|
|
7
|
+
}
|
|
8
|
+
export interface RefactorCharacterizationBaselineV1 {
|
|
9
|
+
readonly schemaVersion: 1;
|
|
10
|
+
readonly kind: 'root-refactor-characterization-baseline';
|
|
11
|
+
readonly admissionSha256: string;
|
|
12
|
+
readonly sourceHead: string;
|
|
13
|
+
readonly testFiles: readonly FileDigest[];
|
|
14
|
+
readonly dependencies: readonly FileDigest[];
|
|
15
|
+
readonly causalPath: string;
|
|
16
|
+
readonly candidateSha256: string;
|
|
17
|
+
readonly outputSha256: string;
|
|
18
|
+
readonly causalOutputSha256: string;
|
|
19
|
+
readonly baselineSha256: string;
|
|
20
|
+
}
|
|
21
|
+
export interface RefactorCharacterizationBaselineV2 extends Omit<RefactorCharacterizationBaselineV1, 'schemaVersion'> {
|
|
22
|
+
readonly schemaVersion: 2;
|
|
23
|
+
readonly runner: 'vitest';
|
|
24
|
+
readonly toolchainSha256: string;
|
|
25
|
+
}
|
|
26
|
+
export type RefactorCharacterizationBaseline = RefactorCharacterizationBaselineV1 | RefactorCharacterizationBaselineV2;
|
|
27
|
+
export declare function readRootRefactorBaseline(root: string, sha256: string): RefactorCharacterizationBaseline;
|
|
28
|
+
export interface RefactorCharacterizationReceiptV1 {
|
|
29
|
+
readonly schemaVersion: 1;
|
|
30
|
+
readonly kind: 'root-refactor-characterization-observation';
|
|
31
|
+
readonly phase: 'baseline' | 'after';
|
|
32
|
+
readonly admissionSha256: string;
|
|
33
|
+
readonly baselineSha256: string | null;
|
|
34
|
+
readonly candidateSha256: string;
|
|
35
|
+
readonly outputSha256: string;
|
|
36
|
+
readonly causalOutputSha256: string | null;
|
|
37
|
+
readonly testFileCount: number;
|
|
38
|
+
readonly dependencyCount: number;
|
|
39
|
+
readonly testsPassedObserved: boolean;
|
|
40
|
+
readonly causalFailureObserved: boolean;
|
|
41
|
+
readonly qaAccepted: false;
|
|
42
|
+
readonly gitCommitAuthorized: false;
|
|
43
|
+
readonly publicSafe: true;
|
|
44
|
+
}
|
|
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;
|
|
46
|
+
export declare function refactorCharacterizationCliHandler(args: readonly string[]): number;
|
|
47
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import{spawnSync as ne}from"node:child_process";import{createHash as ie,randomBytes as ae}from"node:crypto";import{closeSync as Y,constants as R,existsSync as W,fsyncSync as X,lstatSync as z,mkdirSync as P,mkdtempSync as ce,openSync as U,readFileSync as D,realpathSync as C,rmSync as fe,writeFileSync as $}from"node:fs";import{tmpdir as le}from"node:os";import{basename as de,dirname as E,join as y,resolve as ue}from"node:path";import{mutationQaGit as G}from"./mutation-qa-git.js";import{exactCommittedRefactorFile as he,privateRefactorDirectory as Q,readPrivateRefactorAdmission as pe,verifyRootRefactor as K}from"./refactor-root.js";const j=/^[a-f0-9]{64}$/,me=64*1024*1024,ee=32,te=128;function we(s){const e=s.match(/^(\d+)\.(\d+)\.(\d+)$/);if(!e)return!1;const r=Number(e[1]),c=Number(e[2]);return r>22||r===22&&c>=6}function g(s){return ie("sha256").update(s).digest("hex")}function H(s){return s.length>0&&s.length<=512&&/^[A-Za-z0-9_.-]+(?:\/[A-Za-z0-9_.-]+)*$/.test(s)&&s.split("/").every(e=>e!=="."&&e!==".."&&![".git",".neocortex","node_modules"].includes(e.toLowerCase()))}function M(s){return[...s].sort((e,r)=>Buffer.from(e).compare(Buffer.from(r)))}function ye(s,e,r){if(!e.endsWith(".js")&&!e.endsWith(".ts"))return;let c=E(e);for(;;){const f=c==="."?"package.json":`${c}/package.json`;if(W(y(s,f))){if(!r.includes(f))throw new Error("refactor-root-tests-manifest-unbound");let o;try{o=JSON.parse(V(s,f).toString("utf8"))}catch{throw new Error("refactor-root-tests-manifest-invalid")}if(!o||typeof o!="object"||Array.isArray(o)||!["module","commonjs"].includes(o.type)||e.endsWith(".ts")&&o.type!=="module")throw new Error("refactor-root-tests-manifest-invalid");return}if(c===".")break;c=E(c)}throw new Error("refactor-root-tests-manifest-missing")}function V(s,e){if(!H(e))throw new Error("refactor-root-tests-path-invalid");const r=y(s,e),c=z(r);if(C(r)!==r||!c.isFile()||c.isSymbolicLink()||c.size<1||c.size>8*1024*1024)throw new Error("refactor-root-tests-source-unverified");const f=D(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 Z(s,e){if(!j.test(e))throw new Error("refactor-root-baseline-invalid");return y(Q(s),`characterization-baseline-${e}.json`)}function q(s,e){const r=z(Z(s,e));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 c=D(Z(s,e));if(c.length>64*1024)throw new Error("refactor-root-baseline-invalid");let f;try{f=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(c))}catch{throw new Error("refactor-root-baseline-invalid")}if(!f||typeof f!="object"||Array.isArray(f))throw new Error("refactor-root-baseline-invalid");const o=f,i=["schemaVersion","kind","admissionSha256","sourceHead","testFiles","dependencies","causalPath","candidateSha256","outputSha256","causalOutputSha256","baselineSha256"],l=t=>Array.isArray(t)&&t.every(a=>a&&typeof a=="object"&&!Array.isArray(a)&&Object.keys(a).sort().join("\0")==="path\0sha256"&&typeof a.path=="string"&&typeof a.sha256=="string"&&H(a.path)&&j.test(a.sha256)),p=o.schemaVersion===2;if(Object.keys(o).sort().join("\0")!==(p?[...i,"runner","toolchainSha256"]:i).sort().join("\0")||o.schemaVersion!==1&&o.schemaVersion!==2||p&&(o.runner!=="vitest"||!j.test(String(o.toolchainSha256)))||o.kind!=="root-refactor-characterization-baseline"||!j.test(String(o.admissionSha256))||typeof o.sourceHead!="string"||!/^[a-f0-9]{40}(?:[a-f0-9]{24})?$/.test(o.sourceHead)||!l(o.testFiles)||!l(o.dependencies)||o.testFiles.length<1||o.testFiles.length>ee||o.dependencies.length>te||typeof o.causalPath!="string"||!H(o.causalPath)||!j.test(String(o.candidateSha256))||!j.test(String(o.outputSha256))||!j.test(String(o.causalOutputSha256))||o.baselineSha256!==e)throw new Error("refactor-root-baseline-invalid");const n=o.testFiles,u=o.dependencies;if(new Set([...n,...u].map(t=>t.path)).size!==n.length+u.length||n.map(t=>t.path).join("\0")!==M(n.map(t=>t.path)).join("\0")||u.map(t=>t.path).join("\0")!==M(u.map(t=>t.path)).join("\0"))throw new Error("refactor-root-baseline-invalid");const{baselineSha256:h,...m}=o;if(g(JSON.stringify(m))!==e||!c.equals(Buffer.from(`${JSON.stringify(o)}
|
|
2
|
+
`)))throw new Error("refactor-root-baseline-invalid");return o}function ve(s,e){const r=g(JSON.stringify(e)),c=Z(s,r),f={...e,baselineSha256:r},o=Buffer.from(`${JSON.stringify(f)}
|
|
3
|
+
`);if(W(c))q(s,r);else{const i=U(c,R.O_WRONLY|R.O_CREAT|R.O_EXCL|(R.O_NOFOLLOW??0),384);try{$(i,o),X(i)}finally{Y(i)}const l=U(Q(s),R.O_RDONLY|(R.O_DIRECTORY??0));try{X(l)}finally{Y(l)}}return q(s,r),r}function re(s){return[...s.files.map(e=>e.path),...s.schemaVersion===2?s.newFiles.map(e=>e.path):[]]}function oe(s,e,r){const c=new Map;let f=0;for(const i of[...re(e),...r]){const l=V(s,i);if(f+=l.length,f>me)throw new Error("refactor-root-tests-snapshot-too-large");c.set(i,l)}const o=g(JSON.stringify([...c].map(([i,l])=>[i,g(l)])));return{files:c,candidateSha256:o}}function ge(s,e,r){let c="";for(const d of e){let O=E(d),x="";for(;;){const I=O==="."?"package.json":`${O}/package.json`;if(W(y(s,I))){x=I;break}if(O===".")break;O=E(O)}if(!x||c&&x!==c)throw new Error("refactor-root-tests-toolchain-unverified");c=x}if(!r.includes(c)||!r.includes("package-lock.json"))throw new Error("refactor-root-tests-toolchain-unbound");const f=V(s,c),o=V(s,"package-lock.json");let i,l;try{i=JSON.parse(f.toString("utf8")),l=JSON.parse(o.toString("utf8"))}catch{throw new Error("refactor-root-tests-toolchain-unverified")}const p=i.devDependencies?.vitest??i.dependencies?.vitest,n=l.packages,u=c==="package.json"?"":E(c),h=n?.[u],m=h?.devDependencies?.vitest??h?.dependencies?.vitest,t=n?.["node_modules/vitest"]?.version,a=n?.["node_modules/vite"]?.version;if(typeof p!="string"||p.length>80||!/^[\^~]?[0-9]+\.[0-9]+\.[0-9]+$/.test(p)||p!==m||typeof t!="string"||!/^[0-9]+\.[0-9]+\.[0-9]+$/.test(t)||!t.startsWith("3.2.")||typeof a!="string"||!/^[0-9]+\.[0-9]+\.[0-9]+$/.test(a)||!be(a))throw new Error("refactor-root-tests-toolchain-unverified");const w=C(y(s,"node_modules")),v=z(w);if(de(w)!=="node_modules"||!v.isDirectory()||v.isSymbolicLink()||v.uid!==process.getuid?.())throw new Error("refactor-root-tests-toolchain-unverified");const A=y(w,"vitest","package.json"),N=y(w,"vitest","vitest.mjs"),_=y(w,"vite","package.json"),T=z(A),b=z(N),S=z(_);if(!T.isFile()||T.isSymbolicLink()||!b.isFile()||b.isSymbolicLink()||!S.isFile()||S.isSymbolicLink()||C(A)!==A||C(N)!==N||C(_)!==_||T.size>64*1024||b.size>1024*1024||S.size>64*1024)throw new Error("refactor-root-tests-toolchain-unverified");const k=D(A),B=D(N),F=D(_);let L,J;try{L=JSON.parse(k.toString("utf8")),J=JSON.parse(F.toString("utf8"))}catch{throw new Error("refactor-root-tests-toolchain-unverified")}if(L.name!=="vitest"||L.version!==t||J.name!=="vite"||J.version!==a)throw new Error("refactor-root-tests-toolchain-unverified");return{nodeModules:w,sha256:g(JSON.stringify([g(f),g(o),g(k),g(B),g(F)]))}}function be(s){const e=s.match(/^(\d+)\.(\d+)\.(\d+)$/);return!!e&&Number(e[1])<=7&&(Number(e[1])>6||Number(e[1])===6&&Number(e[2])>=1)}function se(s,e,r,c,f){if(r==="python"){const l=E(e[0]),p=M([...s.keys()].filter(n=>(l==="."||n.startsWith(`${l}/`))&&/(?:^|\/)test_[A-Za-z0-9_]+\.py$/.test(n)));if(JSON.stringify(p)!==JSON.stringify(e))throw new Error("refactor-root-tests-path-invalid")}const o=C(r==="python"?"/usr/bin/python3":process.execPath);if(r==="node-typescript"&&!we(process.versions.node))throw new Error("refactor-root-tests-toolchain-unavailable");if(process.platform!=="linux"||!W("/usr/bin/bwrap")||!z("/usr/bin/bwrap").isFile()||!(o.startsWith("/usr/")||o.startsWith("/home/linuxbrew/.linuxbrew/")))throw new Error("refactor-root-tests-sandbox-unavailable");const i=ce(y(le(),"p222-refactor-characterization-"));try{const l=y(i,"work");P(l,{mode:448});for(const[a,w]of s){const v=y(l,a);P(E(v),{recursive:!0,mode:448}),$(v,w,{mode:384,flag:"wx"})}if(r==="vitest"){if(!f)throw new Error("refactor-root-tests-toolchain-unavailable");P(y(l,"node_modules"),{mode:448}),$(y(l,"p222-vitest.config.mjs"),`export default ${JSON.stringify({test:{include:e,environment:"node",silent:!0,passWithNoTests:!1,watch:!1,maxWorkers:1,fileParallelism:!1,pool:"forks",coverage:{enabled:!1}}})};
|
|
4
|
+
`,{mode:384,flag:"wx"})}const p=y(i,"etc");P(p,{mode:448}),$(y(p,"passwd"),`nobody:x:65534:65534:nobody:/tmp:/bin/sh
|
|
5
|
+
`,{mode:384}),$(y(p,"group"),`nogroup:x:65534:
|
|
6
|
+
`,{mode:384}),$(y(p,"hosts"),`127.0.0.1 localhost
|
|
7
|
+
`,{mode:384}),$(y(p,"nsswitch.conf"),`hosts: files
|
|
8
|
+
`,{mode:384});const n=["--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"&&n.push("--setenv","PYTHONPATH","/work");for(const a of["/lib","/lib64","/bin"])W(a)&&n.push("--ro-bind",a,a);W("/home/linuxbrew/.linuxbrew")&&n.push("--ro-bind","/home/linuxbrew/.linuxbrew","/home/linuxbrew/.linuxbrew"),n.push("--dir","/etc");for(const a of["passwd","group","hosts","nsswitch.conf"])n.push("--ro-bind",y(p,a),`/etc/${a}`);n.push("--dev","/dev","--proc","/proc","--tmpfs","/tmp","--ro-bind",l,"/work"),r==="vitest"&&n.push("--ro-bind",f.nodeModules,"/work/node_modules"),n.push("--chdir","/work","--",o),r==="python"?n.push("-B","-S","-m","unittest","discover","-s",E(e[0]),"-p","test_*.py"):r==="vitest"?n.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"&&n.push("--experimental-strip-types"),n.push("--test","--test-reporter=tap",...e));const u=ne("/usr/bin/bwrap",n,{env:{PATH:"/usr/bin:/bin"},encoding:"buffer",timeout:18e4,maxBuffer:4*1024*1024});if(u.error||u.signal||u.status===null)throw new Error("refactor-root-tests-sandbox-unavailable");const h=Buffer.concat([u.stdout??Buffer.alloc(0),u.stderr??Buffer.alloc(0)]),m=r!=="python"||/^Ran [1-9][0-9]* tests? in /m.test(h.toString("utf8"));let t=!0;if(r==="vitest")try{const a=JSON.parse((u.stdout??Buffer.alloc(0)).toString("utf8"));t=Number.isSafeInteger(a.numPassedTests)&&Number(a.numPassedTests)>0&&a.numTotalTests===a.numPassedTests&&a.numFailedTests===0}catch{t=!1}return{passed:u.status===0&&m&&t,outputSha256:g(h),canaryObserved:c!==void 0&&h.includes(Buffer.from(c))}}finally{fe(i,{recursive:!0,force:!0})}}function Se(s,e,r,c,f,o,i,l,p="native"){if(!o)throw new Error("refactor-root-run-authorization-required");if(r.length<1||r.length>ee||c.length>te||!["native","vitest"].includes(p)||f==="baseline"&&l!==void 0||f==="after"&&(!l||!j.test(l)))throw new Error("refactor-root-tests-arguments-invalid");const n=M(r),u=M(c),h=p==="vitest"?"vitest":n.every(t=>/(?:^|\/)test_[A-Za-z0-9_]+\.py$/.test(t))&&i.endsWith(".py")?"python":n.every(t=>t.endsWith(".test.ts"))&&i.endsWith(".ts")?"node-typescript":"node";if(new Set([...n,...u]).size!==n.length+u.length||n.some(t=>!H(t)||(h==="python"?!/(?:^|\/)test_[A-Za-z0-9_]+\.py$/.test(t)||E(t)!==E(n[0]):h==="vitest"?!/\.test\.(?:ts|js|mjs)$/.test(t):h==="node-typescript"?!t.endsWith(".test.ts"):!/\.test\.(?:mjs|cjs|js)$/.test(t)))||!H(i)||(h==="python"?!i.endsWith(".py"):h==="vitest"?!/\.(?:ts|js|mjs)$/.test(i)||/\.test\./.test(i):h==="node-typescript"?!i.endsWith(".ts")||i.endsWith(".test.ts"):!/\.(?:mjs|cjs|js)$/.test(i))||u.some(t=>!H(t)||h==="python"&&/(?:^|\/)test_[A-Za-z0-9_]+\.py$/.test(t)))throw new Error("refactor-root-tests-path-invalid");const m=ue(s);try{const t=pe(m,e);K(m,e);const a=new Set(re(t));if(n.some(d=>!a.has(d))||!t.files.some(d=>d.path===i)||n.includes(i)||u.some(d=>a.has(d)))throw new Error("refactor-root-tests-path-invalid");for(const d of[...n,i,...u])ye(m,d,u);for(const d of u)he(m,d);const w=h==="vitest"?ge(m,n,u):void 0,v=G(m,["diff","--name-only","-z","--no-ext-diff","--no-textconv"]).toString("utf8").split("\0").filter(d=>d&&!d.startsWith(".neocortex/")),A=G(m,["ls-files","--others","--exclude-standard","-z"]).toString("utf8").split("\0").filter(d=>d&&!d.startsWith(".neocortex/")),N=[...v,...A].filter(d=>!n.includes(d));if(f==="baseline"&&N.length>0||f==="after"&&N.length===0)throw new Error("refactor-root-tests-phase-invalid");const _=n.map(d=>({path:d,sha256:g(V(m,d))})),T=u.map(d=>({path:d,sha256:g(V(m,d))})),b=f==="after"?q(m,l):null;if(b&&(b.admissionSha256!==e||b.sourceHead!==t.sourceHead||b.causalPath!==i||(b.schemaVersion===2?p!=="vitest"||b.toolchainSha256!==w?.sha256:p!=="native")||JSON.stringify(b.testFiles)!==JSON.stringify(_)||JSON.stringify(b.dependencies)!==JSON.stringify(T)))throw new Error("refactor-root-baseline-stale");const S=oe(m,t,u);if(b&&g(S.files.get(i))===t.files.find(d=>d.path===i).sha256)throw new Error("refactor-root-tests-phase-invalid");const k=se(S.files,n,h,void 0,w);let B=null,F=!1;if(k.passed){const d=`P222_REFACTOR_CAUSAL_${ae(16).toString("hex")}`,O=new Map(S.files);O.set(i,Buffer.concat([Buffer.from(h==="python"?`raise RuntimeError(${JSON.stringify(d)})
|
|
9
|
+
`:`throw new Error(${JSON.stringify(d)});
|
|
10
|
+
`),S.files.get(i)]));const x=se(O,n,h,d,w);B=x.outputSha256,F=!x.passed&&x.canaryObserved}K(m,e);const L=oe(m,t,u);if(S.candidateSha256!==L.candidateSha256)throw new Error("refactor-root-tests-source-stale");let J=l??null;return f==="baseline"&&k.passed&&F&&B&&(J=ve(m,{...h==="vitest"?{schemaVersion:2,runner:"vitest",toolchainSha256:w.sha256}:{schemaVersion:1},kind:"root-refactor-characterization-baseline",admissionSha256:e,sourceHead:t.sourceHead,testFiles:_,dependencies:T,causalPath:i,candidateSha256:S.candidateSha256,outputSha256:k.outputSha256,causalOutputSha256:B})),Object.freeze({schemaVersion:1,kind:"root-refactor-characterization-observation",phase:f,admissionSha256:e,baselineSha256:J,candidateSha256:S.candidateSha256,outputSha256:k.outputSha256,causalOutputSha256:B,testFileCount:n.length,dependencyCount:u.length,testsPassedObserved:k.passed,causalFailureObserved:F,qaAccepted:!1,gitCommitAuthorized:!1,publicSafe:!0})}catch(t){throw t instanceof Error&&t.message.startsWith("refactor-root-")?t:new Error("refactor-root-tests-unverified")}}function ze(s){let e="",r="",c,f="",o=!1,i="",l="native",p="plain";const n=[],u=[];try{if(s[0]!=="characterize")throw new Error("refactor-root-tests-arguments-invalid");for(let t=1;t<s.length;t++){const a=s[t],w=()=>{const v=s[++t];if(!v||v.startsWith("--"))throw new Error("refactor-root-tests-arguments-invalid");return v};if(a==="--project-root"&&!e)e=w();else if(a==="--admission-sha"&&!r)r=w();else if(a==="--baseline-sha"&&!c)c=w();else if(a==="--phase"&&!f){const v=w();if(v!=="baseline"&&v!=="after")throw new Error("refactor-root-tests-arguments-invalid");f=v}else if(a==="--test-path")n.push(w());else if(a==="--dependency")u.push(w());else if(a==="--causal-path"&&!i)i=w();else if(a==="--runner"&&l==="native"){if(w()!=="vitest")throw new Error("refactor-root-tests-arguments-invalid");l="vitest"}else if(a==="--authorize-run"&&!o)o=!0;else if(a==="--format"&&p==="plain")p=w();else throw new Error("refactor-root-tests-arguments-invalid")}if(!e||!r||!f||!i||!["plain","json"].includes(p))throw new Error("refactor-root-tests-arguments-invalid");const h=Se(e,r,n,u,f,o,i,c,l),m=h.testsPassedObserved&&h.causalFailureObserved;return process.stdout.write(`${JSON.stringify({ok:m,observation:h})}
|
|
11
|
+
`),m?0:1}catch(h){const m=h instanceof Error&&/^refactor-root-[a-z-]+$/.test(h.message)?h.message:"refactor-root-tests-unverified";return process.stdout.write(`${JSON.stringify({ok:!1,reasonCode:m})}
|
|
12
|
+
`),1}}export{q as readRootRefactorBaseline,ze as refactorCharacterizationCliHandler,Se as runRootRefactorCharacterization,we as supportsNativeTypeStrippingVersion};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export interface RefactorCommitPlanReceiptV1 {
|
|
2
|
+
readonly schemaVersion: 1;
|
|
3
|
+
readonly kind: 'root-refactor-commit-plan';
|
|
4
|
+
readonly storyId: string;
|
|
5
|
+
readonly baseHead: string;
|
|
6
|
+
readonly branchRef: string;
|
|
7
|
+
readonly planSha256: string;
|
|
8
|
+
readonly fileCount: number;
|
|
9
|
+
readonly commitSubject: string;
|
|
10
|
+
readonly commitTrailer: string;
|
|
11
|
+
readonly gitCommitAuthorized: false;
|
|
12
|
+
readonly checkpointAccepted: false;
|
|
13
|
+
readonly publicSafe: true;
|
|
14
|
+
}
|
|
15
|
+
export interface RefactorStagedReceiptV1 {
|
|
16
|
+
readonly schemaVersion: 1;
|
|
17
|
+
readonly kind: 'root-refactor-staged-verification';
|
|
18
|
+
readonly planSha256: string;
|
|
19
|
+
readonly baseHead: string;
|
|
20
|
+
readonly fileCount: number;
|
|
21
|
+
readonly stagedWriteSetSha256: string;
|
|
22
|
+
readonly gitCommitAuthorized: true;
|
|
23
|
+
readonly checkpointAccepted: false;
|
|
24
|
+
readonly publicSafe: true;
|
|
25
|
+
}
|
|
26
|
+
export interface RefactorCommitCheckpointV1 {
|
|
27
|
+
readonly schemaVersion: 1;
|
|
28
|
+
readonly kind: 'root-refactor-commit-checkpoint';
|
|
29
|
+
readonly storyId: string;
|
|
30
|
+
readonly baseHead: string;
|
|
31
|
+
readonly commitSha: string;
|
|
32
|
+
readonly branchRef: string;
|
|
33
|
+
readonly planSha256: string;
|
|
34
|
+
readonly candidateSha256: string;
|
|
35
|
+
readonly reviewSha256: string;
|
|
36
|
+
readonly fileCount: number;
|
|
37
|
+
readonly checkpointAccepted: true;
|
|
38
|
+
readonly graphExecution: 'NOT_RUN';
|
|
39
|
+
readonly publicSafe: true;
|
|
40
|
+
}
|
|
41
|
+
export declare function prepareRootRefactorCommit(projectRoot: string, admissionSha256: string, baselineSha256: string, authorizeRootPlan: boolean): RefactorCommitPlanReceiptV1;
|
|
42
|
+
export declare function verifyRootRefactorStaged(projectRoot: string, planSha256: string): RefactorStagedReceiptV1;
|
|
43
|
+
export declare function sealRootRefactorCommit(projectRoot: string, planSha256: string, authorizeRootSeal: boolean): RefactorCommitCheckpointV1;
|
|
44
|
+
export declare function readRootRefactorCommitCheckpoint(projectRoot: string, planSha256: string): RefactorCommitCheckpointV1;
|
|
45
|
+
export declare function refactorCommitCliHandler(args: readonly string[]): number;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import{createHash as Q}from"node:crypto";import{closeSync as _,constants as E,existsSync as X,fsyncSync as W,lstatSync as V,openSync as P,readFileSync as q,realpathSync as K,writeFileSync as tt}from"node:fs";import{join as $,resolve as H}from"node:path";import{mutationQaGit as y}from"./mutation-qa-git.js";import{privateRefactorDirectory as x,readPrivateRefactorAdmission as F,refactorSidecarDigest as j,verifyRootRefactor as et}from"./refactor-root.js";import{readRootRefactorSemanticReview as rt}from"./refactor-review.js";const S=/^[a-f0-9]{64}$/,T=/^[a-f0-9]{40}(?:[a-f0-9]{24})?$/;function w(o){return Q("sha256").update(o).digest("hex")}function g(o,e){return y(o,e).toString("utf8").trim()}function b(o,e){return y(o,e).toString("utf8").split("\0").filter(Boolean)}function I(o){return[...o].sort((e,r)=>Buffer.from(e).compare(Buffer.from(r)))}function N(o,e){return o!==null&&typeof o=="object"&&!Array.isArray(o)&&Object.keys(o).sort().join("\0")===[...e].sort().join("\0")}function R(o,e){const r=$(o,e),t=V(r);if(!t.isFile()||t.isSymbolicLink()||K(r)!==r||t.size<1||t.size>8*1024*1024)throw new Error("refactor-root-commit-physical-drift");const n=q(r);if(n.length!==t.size)throw new Error("refactor-root-commit-physical-drift");return Object.freeze({sha256:w(n),mode:t.mode&511})}function L(o,e){if(!S.test(e))throw new Error("refactor-root-commit-plan-invalid");return $(x(o),`commit-plan-${e}.json`)}function C(o,e){if(!S.test(e))throw new Error("refactor-root-commit-plan-invalid");return $(x(o),`commit-checkpoint-${e}.json`)}function v(o,e){const r=V(o);if(!r.isFile()||r.isSymbolicLink()||r.uid!==process.getuid?.()||(r.mode&63)!==0||r.size<100||r.size>e)throw new Error("refactor-root-commit-plan-invalid");const t=q(o);if(t.length!==r.size)throw new Error("refactor-root-commit-plan-invalid");return t}function Y(o,e,r){if(X(e)){if(!v(e,128*1024).equals(r))throw new Error("refactor-root-commit-plan-conflict");return}const t=P(e,E.O_WRONLY|E.O_CREAT|E.O_EXCL|(E.O_NOFOLLOW??0),384);try{tt(t,r),W(t)}finally{_(t)}const n=P(x(o),E.O_RDONLY|(E.O_DIRECTORY??0));try{W(n)}finally{_(n)}}function A(o,e){const r=v(L(o,e),131072);let t;try{t=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(r))}catch{throw new Error("refactor-root-commit-plan-invalid")}if(!N(t,["schemaVersion","kind","storyId","baseHead","branchRef","admissionSha256","baselineSha256","candidateSha256","reviewSha256","reviewRecordSha256","sidecarSha256","files","planSha256"])||t.schemaVersion!==1||t.kind!=="private-root-refactor-commit-plan"||typeof t.storyId!="string"||!/^P[0-9]+(?:\.[0-9]+)+$/.test(t.storyId)||typeof t.baseHead!="string"||!T.test(t.baseHead)||typeof t.branchRef!="string"||![`refs/heads/epic/${t.storyId.split(".")[0]}`,`refs/heads/story/${t.storyId.split(".")[0]}/${t.storyId}`].includes(t.branchRef)||![t.admissionSha256,t.baselineSha256,t.candidateSha256,t.reviewSha256,t.reviewRecordSha256,t.sidecarSha256].every(a=>typeof a=="string"&&S.test(a))||!Array.isArray(t.files)||t.files.length<2||t.files.length>256||!t.files.every(a=>N(a,["path","sha256","mode"])&&typeof a.path=="string"&&/^[A-Za-z0-9_.-]+(?:\/[A-Za-z0-9_.-]+)*$/.test(a.path)&&typeof a.sha256=="string"&&S.test(a.sha256)&&Number.isSafeInteger(a.mode)&&Number(a.mode)>=0&&Number(a.mode)<=511)||t.files.map(a=>a.path).join("\0")!==I(t.files.map(a=>a.path)).join("\0")||new Set(t.files.map(a=>a.path)).size!==t.files.length||t.planSha256!==e)throw new Error("refactor-root-commit-plan-invalid");const{planSha256:n,...c}=t;if(w(JSON.stringify(c))!==e||!r.equals(Buffer.from(`${JSON.stringify(t)}
|
|
2
|
+
`)))throw new Error("refactor-root-commit-plan-invalid");const i=F(o,t.admissionSha256),m=new Set([...i.files.map(a=>a.path),...i.schemaVersion===2?i.newFiles.map(a=>a.path):[]]);if(i.storyId!==t.storyId||i.sourceHead!==t.baseHead||i.sidecarSha256!==t.sidecarSha256||t.files.some(a=>!m.has(a.path)))throw new Error("refactor-root-commit-plan-invalid");return t}function B(o,e){return $(x(o),`review-${e.admissionSha256}-${e.candidateSha256}.json`)}function G(o){return`refactor(${o}): characterized change`}function U(o){return`Neocortex-Refactor-Plan: ${o}`}function k(o){return g(o,["symbolic-ref","-q","HEAD"])}function ot(o){return b(o,["status","--porcelain=v1","-z","--untracked-files=all"]).every(e=>e.length>=4&&e[2]===" "&&e.slice(3).startsWith(".neocortex/"))}function it(o,e,r,t){if(!t)throw new Error("refactor-root-commit-authorization-required");try{const n=H(o),c=rt(n,e,r),i=F(n,e),m=et(n,e),a=k(n),s=i.storyId.split(".")[0];if(![`refs/heads/epic/${s}`,`refs/heads/story/${s}/${i.storyId}`].includes(a))throw new Error("refactor-root-commit-branch-invalid");const u=b(n,["diff","--name-only","-z","--no-ext-diff","--no-textconv"]),d=b(n,["ls-files","--others","--exclude-standard","-z"]),l=I([...u,...d].filter(f=>!f.startsWith(".neocortex/"))),h=new Set([...i.files.map(f=>f.path),...i.schemaVersion===2?i.newFiles.map(f=>f.path):[]]);if(l.length!==m.changedFileCount||l.some(f=>!h.has(f)))throw new Error("refactor-root-commit-delta-invalid");const p=l.map(f=>Object.freeze({path:f,...R(n,f)})),z=w(v(B(n,{admissionSha256:e,candidateSha256:c.candidateSha256}),128*1024)),D={schemaVersion:1,kind:"private-root-refactor-commit-plan",storyId:i.storyId,baseHead:i.sourceHead,branchRef:a,admissionSha256:e,baselineSha256:r,candidateSha256:c.candidateSha256,reviewSha256:c.reviewSha256,reviewRecordSha256:z,sidecarSha256:i.sidecarSha256,files:p},O=w(JSON.stringify(D)),M={...D,planSha256:O};if(g(n,["rev-parse","--verify","HEAD"])!==i.sourceHead||j(n)!==i.sidecarSha256||p.some(f=>{const J=R(n,f.path);return J.sha256!==f.sha256||J.mode!==f.mode}))throw new Error("refactor-root-commit-physical-drift");return Y(n,L(n,O),Buffer.from(`${JSON.stringify(M)}
|
|
3
|
+
`)),A(n,O),Object.freeze({schemaVersion:1,kind:"root-refactor-commit-plan",storyId:i.storyId,baseHead:i.sourceHead,branchRef:a,planSha256:O,fileCount:p.length,commitSubject:G(i.storyId),commitTrailer:U(O),gitCommitAuthorized:!1,checkpointAccepted:!1,publicSafe:!0})}catch(n){throw n instanceof Error&&n.message.startsWith("refactor-root-commit-")?n:new Error("refactor-root-commit-unverified")}}function at(o,e){try{const r=H(o),t=A(r,e);if(k(r)!==t.branchRef||g(r,["rev-parse","--verify","HEAD"])!==t.baseHead||j(r)!==t.sidecarSha256||w(v(B(r,t),128*1024))!==t.reviewRecordSha256)throw new Error("refactor-root-commit-physical-drift");const n=I(b(r,["diff","--cached","--name-only","-z","--no-renames"])),c=t.files.map(a=>a.path),i=b(r,["diff","--name-only","-z","--no-renames"]).filter(a=>!a.startsWith(".neocortex/")),m=b(r,["ls-files","--others","--exclude-standard","-z"]).filter(a=>!a.startsWith(".neocortex/"));if(n.join("\0")!==c.join("\0")||i.length||m.length)throw new Error("refactor-root-commit-staged-invalid");for(const a of t.files){const u=y(r,["ls-files","--stage","-z","--",a.path]).toString("utf8").match(/^(100644|100755) [a-f0-9]{40,64} 0\t([^\0]+)\0$/);if(!u||u[2]!==a.path||u[1]!==(a.mode&73?"100755":"100644")||w(y(r,["show",`:${a.path}`]))!==a.sha256||R(r,a.path).sha256!==a.sha256||R(r,a.path).mode!==a.mode)throw new Error("refactor-root-commit-staged-invalid")}if(k(r)!==t.branchRef||g(r,["rev-parse","--verify","HEAD"])!==t.baseHead||j(r)!==t.sidecarSha256)throw new Error("refactor-root-commit-physical-drift");return Object.freeze({schemaVersion:1,kind:"root-refactor-staged-verification",planSha256:e,baseHead:t.baseHead,fileCount:t.files.length,stagedWriteSetSha256:w(JSON.stringify(t.files)),gitCommitAuthorized:!0,checkpointAccepted:!1,publicSafe:!0})}catch(r){throw r instanceof Error&&r.message.startsWith("refactor-root-commit-")?r:new Error("refactor-root-commit-unverified")}}function Z(o,e){const r=g(o,["rev-parse","--verify","HEAD"]),t=g(o,["show","-s","--format=%P",r]),n=y(o,["cat-file","commit",r]),c=n.indexOf(Buffer.from(`
|
|
4
|
+
|
|
5
|
+
`)),i=c<0?Buffer.alloc(0):n.subarray(c+2),m=Buffer.from(`${G(e.storyId)}
|
|
6
|
+
|
|
7
|
+
${U(e.planSha256)}
|
|
8
|
+
`);if(!T.test(r)||t!==e.baseHead||!i.equals(m)||k(o)!==e.branchRef||!ot(o)||j(o)!==e.sidecarSha256||w(v(B(o,e),128*1024))!==e.reviewRecordSha256)throw new Error("refactor-root-commit-physical-drift");if(I(b(o,["diff-tree","--no-commit-id","--name-only","--no-renames","-r","-z",r])).join("\0")!==e.files.map(s=>s.path).join("\0"))throw new Error("refactor-root-commit-physical-drift");for(const s of e.files){const d=y(o,["ls-tree","-z",r,"--",s.path]).toString("utf8").match(/^(100644|100755) blob [a-f0-9]{40,64}\t([^\0]+)\0$/);if(!d||d[2]!==s.path||d[1]!==(s.mode&73?"100755":"100644")||w(y(o,["show",`${r}:${s.path}`]))!==s.sha256||R(o,s.path).sha256!==s.sha256||R(o,s.path).mode!==s.mode)throw new Error("refactor-root-commit-physical-drift")}if(g(o,["rev-parse","--verify","HEAD"])!==r||k(o)!==e.branchRef)throw new Error("refactor-root-commit-physical-drift");return r}function nt(o,e,r){if(!r)throw new Error("refactor-root-commit-authorization-required");try{const t=H(o),n=A(t,e),c=Z(t,n),i=Object.freeze({schemaVersion:1,kind:"root-refactor-commit-checkpoint",storyId:n.storyId,baseHead:n.baseHead,commitSha:c,branchRef:n.branchRef,planSha256:e,candidateSha256:n.candidateSha256,reviewSha256:n.reviewSha256,fileCount:n.files.length,checkpointAccepted:!0,graphExecution:"NOT_RUN",publicSafe:!0});if(Y(t,C(t,e),Buffer.from(`${JSON.stringify(i)}
|
|
9
|
+
`)),!v(C(t,e),8*1024).equals(Buffer.from(`${JSON.stringify(i)}
|
|
10
|
+
`)))throw new Error("refactor-root-commit-checkpoint-invalid");return i}catch(t){throw t instanceof Error&&t.message.startsWith("refactor-root-commit-")?t:new Error("refactor-root-commit-unverified")}}function ct(o,e){try{const r=H(o),t=A(r,e),n=Z(r,t),c=v(C(r,e),8*1024),i=JSON.parse(c.toString("utf8"));if(!N(i,["schemaVersion","kind","storyId","baseHead","commitSha","branchRef","planSha256","candidateSha256","reviewSha256","fileCount","checkpointAccepted","graphExecution","publicSafe"])||i.schemaVersion!==1||i.kind!=="root-refactor-commit-checkpoint"||i.commitSha!==n||i.planSha256!==e||i.storyId!==t.storyId||i.baseHead!==t.baseHead||i.branchRef!==t.branchRef||i.candidateSha256!==t.candidateSha256||i.reviewSha256!==t.reviewSha256||i.fileCount!==t.files.length||i.checkpointAccepted!==!0||i.graphExecution!=="NOT_RUN"||i.publicSafe!==!0||!c.equals(Buffer.from(`${JSON.stringify(i)}
|
|
11
|
+
`)))throw new Error("refactor-root-commit-checkpoint-invalid");return i}catch{throw new Error("refactor-root-commit-checkpoint-invalid")}}function ut(o){const e=o[0];let r="",t="",n="",c="",i=!1,m=!1,a=!1,s="plain";const u=new Set;try{if(!["commit-plan","commit-staged","commit-seal","commit-status"].includes(e??""))throw new Error("refactor-root-commit-arguments-invalid");for(let l=1;l<o.length;l++){const h=o[l];if(u.has(h))throw new Error("refactor-root-commit-arguments-invalid");u.add(h);const p=()=>{const z=o[++l];if(!z||z.startsWith("--"))throw new Error("refactor-root-commit-arguments-invalid");return z};if(h==="--project-root")r=p();else if(h==="--admission-sha")t=p();else if(h==="--baseline-sha")n=p();else if(h==="--plan-sha")c=p();else if(h==="--authorize-run")i=!0;else if(h==="--authorize-root-commit-plan")m=!0;else if(h==="--authorize-root-seal")a=!0;else if(h==="--format")s=p();else throw new Error("refactor-root-commit-arguments-invalid")}if(!r||!["plain","json"].includes(s)||e==="commit-plan"&&(!S.test(t)||!S.test(n)||c||!i||!m||a)||e!=="commit-plan"&&(!S.test(c)||t||n||i||m||a!==(e==="commit-seal")))throw new Error("refactor-root-commit-arguments-invalid");const d=e==="commit-plan"?it(r,t,n,m):e==="commit-staged"?at(r,c):e==="commit-seal"?nt(r,c,a):ct(r,c);return process.stdout.write(`${JSON.stringify({ok:!0,result:d})}
|
|
12
|
+
`),0}catch(d){const l=d instanceof Error&&/^refactor-root-[a-z-]+$/.test(d.message)?d.message:"refactor-root-commit-unverified";return process.stdout.write(`${JSON.stringify({ok:!1,reasonCode:l})}
|
|
13
|
+
`),1}}export{it as prepareRootRefactorCommit,ct as readRootRefactorCommitCheckpoint,ut as refactorCommitCliHandler,nt as sealRootRefactorCommit,at as verifyRootRefactorStaged};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface RefactorSemanticReviewV1 {
|
|
2
|
+
readonly schemaVersion: 1;
|
|
3
|
+
readonly kind: 'root-refactor-semantic-review';
|
|
4
|
+
readonly storyId: string;
|
|
5
|
+
readonly sourceHead: string;
|
|
6
|
+
readonly admissionSha256: string;
|
|
7
|
+
readonly baselineSha256: string;
|
|
8
|
+
readonly candidateSha256: string;
|
|
9
|
+
readonly verdict: 'approved';
|
|
10
|
+
readonly behaviorRationale: string;
|
|
11
|
+
readonly assertions: readonly Readonly<{
|
|
12
|
+
testPath: string;
|
|
13
|
+
assertionLine: number;
|
|
14
|
+
rationale: string;
|
|
15
|
+
}>[];
|
|
16
|
+
}
|
|
17
|
+
export interface RefactorSemanticAcceptanceV1 {
|
|
18
|
+
readonly schemaVersion: 1;
|
|
19
|
+
readonly kind: 'root-refactor-semantic-acceptance';
|
|
20
|
+
readonly storyId: string;
|
|
21
|
+
readonly sourceHead: string;
|
|
22
|
+
readonly admissionSha256: string;
|
|
23
|
+
readonly baselineSha256: string;
|
|
24
|
+
readonly candidateSha256: string;
|
|
25
|
+
readonly reviewSha256: string;
|
|
26
|
+
readonly testFileCount: number;
|
|
27
|
+
readonly assertionCount: number;
|
|
28
|
+
readonly changedFileCount: number;
|
|
29
|
+
readonly executionVerified: true;
|
|
30
|
+
readonly qaAccepted: true;
|
|
31
|
+
readonly gitCommitAuthorized: false;
|
|
32
|
+
readonly publicSafe: true;
|
|
33
|
+
}
|
|
34
|
+
export declare function acceptRootRefactorSemanticReview(projectRoot: string, admissionSha256: string, baselineSha256: string, report: unknown): RefactorSemanticAcceptanceV1;
|
|
35
|
+
export declare function readRootRefactorSemanticReview(projectRoot: string, admissionSha256: string, baselineSha256: string): RefactorSemanticAcceptanceV1;
|
|
36
|
+
/** The report travels only over stdin and is never echoed on public CLI output. */
|
|
37
|
+
export declare function refactorReviewCliHandler(args: readonly string[]): Promise<number>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{createHash as H,randomUUID as C}from"node:crypto";import{closeSync as k,existsSync as R,fsyncSync as O,linkSync as j,lstatSync as x,openSync as N,readFileSync as F,realpathSync as L,unlinkSync as I,writeFileSync as V}from"node:fs";import{join as p,resolve as B}from"node:path";import{readRootRefactorBaseline as D,runRootRefactorCharacterization as T}from"./refactor-characterization.js";import{privateRefactorDirectory as z,readPrivateRefactorAdmission as W,verifyRootRefactor as q}from"./refactor-root.js";const l=/^[a-f0-9]{64}$/,S=128*1024;function v(t){return H("sha256").update(t).digest("hex")}function y(t,e){return t!==null&&typeof t=="object"&&!Array.isArray(t)&&Object.keys(t).sort().join("\0")===[...e].sort().join("\0")}function J(t,e){return typeof t=="string"&&t.length>=30&&t.length<=e&&!/[\x00-\x1f\x7f]/.test(t)}function g(t,e,n){if(!l.test(e)||!l.test(n))throw new Error("refactor-root-review-unverified");const o=B(t),i=W(o,e),s=D(o,n),r=q(o,e),c=T(o,e,s.testFiles.map(f=>f.path),s.dependencies.map(f=>f.path),"after",!0,s.causalPath,n,s.schemaVersion===2?"vitest":"native");if(s.admissionSha256!==e||s.sourceHead!==i.sourceHead||c.baselineSha256!==n||!c.testsPassedObserved||!c.causalFailureObserved||r.changedFileCount<2)throw new Error("refactor-root-review-unverified");return Object.freeze({root:o,storyId:i.storyId,sourceHead:i.sourceHead,admissionSha256:e,baselineSha256:n,candidateSha256:c.candidateSha256,testFiles:s.testFiles,changedFileCount:r.changedFileCount})}function P(t,e){if(!y(e,["schemaVersion","kind","storyId","sourceHead","admissionSha256","baselineSha256","candidateSha256","verdict","behaviorRationale","assertions"])||e.schemaVersion!==1||e.kind!=="root-refactor-semantic-review"||e.storyId!==t.storyId||e.sourceHead!==t.sourceHead||e.admissionSha256!==t.admissionSha256||e.baselineSha256!==t.baselineSha256||e.candidateSha256!==t.candidateSha256||e.verdict!=="approved"||!J(e.behaviorRationale,1e3)||!Array.isArray(e.assertions)||e.assertions.length<t.testFiles.length||e.assertions.length>64||Buffer.byteLength(JSON.stringify(e))>S)throw new Error("refactor-root-review-unverified");const n=new Map(t.testFiles.map(r=>[r.path,r.sha256])),o=new Map;for(const[r,c]of n){const f=p(t.root,r),a=x(f);if(!a.isFile()||a.isSymbolicLink()||L(f)!==f||a.size<1||a.size>8*1024*1024)throw new Error("refactor-root-review-unverified");const d=F(f);if(v(d)!==c)throw new Error("refactor-root-review-unverified");o.set(r,new TextDecoder("utf-8",{fatal:!0}).decode(d).split(/\r?\n/))}const i=new Set,s=new Set;for(const r of e.assertions){if(!y(r,["testPath","assertionLine","rationale"])||typeof r.testPath!="string"||!n.has(r.testPath)||!Number.isSafeInteger(r.assertionLine)||Number(r.assertionLine)<1||Number(r.assertionLine)>(o.get(r.testPath)?.length??0)||!J(r.rationale,500))throw new Error("refactor-root-review-unverified");const c=`${r.testPath}:${r.assertionLine}`;if(i.has(c))throw new Error("refactor-root-review-unverified");i.add(c),s.add(r.testPath);const f=o.get(r.testPath)[Number(r.assertionLine)-1],a=r.testPath.endsWith(".py")?(f.split("#")[0]??"").trimStart():f.split("//")[0]??"";if(!(r.testPath.endsWith(".py")?/^self\.assert[A-Z][A-Za-z0-9_]*\s*\(/.test(a)||/^assert\s+\S/.test(a):/\b(?:assert|expect|throw)\b/.test(a)))throw new Error("refactor-root-review-unverified")}if(s.size!==n.size)throw new Error("refactor-root-review-unverified");return e}function $(t,e){return Object.freeze({schemaVersion:1,kind:"root-refactor-semantic-acceptance",storyId:t.storyId,sourceHead:t.sourceHead,admissionSha256:t.admissionSha256,baselineSha256:t.baselineSha256,candidateSha256:t.candidateSha256,reviewSha256:v(`root-refactor-semantic-review-v1\0${JSON.stringify(e)}`),testFileCount:t.testFiles.length,assertionCount:e.assertions.length,changedFileCount:t.changedFileCount,executionVerified:!0,qaAccepted:!0,gitCommitAuthorized:!1,publicSafe:!0})}function A(t,e,n){return p(z(t),`review-${e}-${n}.json`)}function E(t){const e=x(t);if(!e.isFile()||e.isSymbolicLink()||e.uid!==process.getuid?.()||(e.mode&63)!==0||e.size<100||e.size>S+4096)throw new Error("refactor-root-review-unverified");const n=F(t),o=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(n));if(!y(o,["schemaVersion","kind","report","receipt","checksumSha256"])||o.schemaVersion!==1||o.kind!=="root-refactor-semantic-record"||typeof o.checksumSha256!="string"||!l.test(o.checksumSha256)||!n.equals(Buffer.from(`${JSON.stringify(o)}
|
|
2
|
+
`))||o.checksumSha256!==v(`root-refactor-semantic-record-v1\0${JSON.stringify({report:o.report,receipt:o.receipt})}`))throw new Error("refactor-root-review-unverified");return o}function M(t,e,n,o){try{const i=g(t,e,n),s=P(i,o),r=$(i,s),c=A(i.root,e,i.candidateSha256),f={report:s,receipt:r},a={schemaVersion:1,kind:"root-refactor-semantic-record",...f,checksumSha256:v(`root-refactor-semantic-record-v1\0${JSON.stringify(f)}`)},d=Buffer.from(`${JSON.stringify(a)}
|
|
3
|
+
`);if(R(c)){const m=E(c);if(JSON.stringify(m.report)!==JSON.stringify(s)||JSON.stringify(m.receipt)!==JSON.stringify(r))throw new Error("refactor-root-review-conflict");return r}const h=z(i.root),u=p(h,`review-${C()}.tmp`),w=N(u,"wx",384);try{V(w,d),O(w)}finally{k(w)}try{if(g(i.root,e,n).candidateSha256!==r.candidateSha256)throw new Error("refactor-root-review-unverified");j(u,c);const b=N(h,"r");try{O(b)}finally{k(b)}}finally{R(u)&&I(u)}return E(c),r}catch(i){throw i instanceof Error&&i.message==="refactor-root-review-conflict"?i:new Error("refactor-root-review-unverified")}}function _(t,e,n){try{const o=g(t,e,n),i=E(A(o.root,e,o.candidateSha256));if(!y(i,["schemaVersion","kind","report","receipt","checksumSha256"]))throw new Error("refactor-root-review-unverified");const s=P(o,i.report),r=$(o,s);if(JSON.stringify(i.receipt)!==JSON.stringify(r))throw new Error("refactor-root-review-unverified");return r}catch{throw new Error("refactor-root-review-unverified")}}async function G(t){const e=t[0];let n="",o="",i="",s=!1,r=!1,c="plain";const f=new Set;try{if(e!=="review-accept"&&e!=="review-status")throw new Error("refactor-root-review-arguments-invalid");for(let d=1;d<t.length;d++){const h=t[d];if(f.has(h))throw new Error("refactor-root-review-arguments-invalid");f.add(h);const u=()=>{const w=t[++d];if(!w||w.startsWith("--"))throw new Error("refactor-root-review-arguments-invalid");return w};if(h==="--project-root")n=u();else if(h==="--admission-sha")o=u();else if(h==="--baseline-sha")i=u();else if(h==="--authorize-run")s=!0;else if(h==="--authorize-root-review")r=!0;else if(h==="--format")c=u();else throw new Error("refactor-root-review-arguments-invalid")}if(!n||!l.test(o)||!l.test(i)||!["plain","json"].includes(c)||!s||r!==(e==="review-accept"))throw new Error("refactor-root-review-arguments-invalid");let a;if(e==="review-accept"){let d="";for await(const w of process.stdin)if(d+=String(w),Buffer.byteLength(d)>S)throw new Error("refactor-root-review-unverified");const{parseDocument:h}=await import("yaml"),u=h(d,{strict:!0,uniqueKeys:!0,schema:"core",customTags:[]});if(u.errors.length||u.warnings.length)throw new Error("refactor-root-review-unverified");a=M(n,o,i,JSON.parse(d))}else a=_(n,o,i);return process.stdout.write(`${JSON.stringify({ok:!0,acceptance:a})}
|
|
4
|
+
`),0}catch(a){const d=a instanceof Error&&/^refactor-root-[a-z-]+$/.test(a.message)?a.message:"refactor-root-review-unverified";return process.stdout.write(`${JSON.stringify({ok:!1,reasonCode:d})}
|
|
5
|
+
`),1}}export{M as acceptRootRefactorSemanticReview,_ as readRootRefactorSemanticReview,G as refactorReviewCliHandler};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export interface RefactorRootPlanV1 {
|
|
2
|
+
readonly schemaVersion: 1;
|
|
3
|
+
readonly kind: 'root-refactor-story-scope';
|
|
4
|
+
readonly storyId: string;
|
|
5
|
+
readonly sourceHead: string;
|
|
6
|
+
readonly storySha256: string;
|
|
7
|
+
readonly planSha256: string;
|
|
8
|
+
readonly candidateWriteSetRequired: true;
|
|
9
|
+
readonly characterizationRequired: true;
|
|
10
|
+
readonly executionAuthorized: false;
|
|
11
|
+
readonly gitAuthority: 'ROOT_ONLY';
|
|
12
|
+
readonly graphExecution: 'NOT_RUN';
|
|
13
|
+
readonly publicSafe: true;
|
|
14
|
+
}
|
|
15
|
+
export declare function privateRefactorDirectory(root: string): string;
|
|
16
|
+
export declare function exactCommittedRefactorFile(root: string, path: string): Readonly<{
|
|
17
|
+
sha256: string;
|
|
18
|
+
mode: number;
|
|
19
|
+
}>;
|
|
20
|
+
/** Preserve the pre-existing visible Neocortex sidecar state byte-for-byte. */
|
|
21
|
+
export declare function refactorSidecarDigest(root: string): string;
|
|
22
|
+
export interface PrivateRefactorAdmissionV1 {
|
|
23
|
+
readonly schemaVersion: 1;
|
|
24
|
+
readonly kind: 'private-root-refactor-admission';
|
|
25
|
+
readonly storyId: string;
|
|
26
|
+
readonly sourceHead: string;
|
|
27
|
+
readonly storySha256: string;
|
|
28
|
+
readonly planSha256: string;
|
|
29
|
+
readonly indexSha256: string;
|
|
30
|
+
readonly sidecarSha256: string;
|
|
31
|
+
readonly files: readonly Readonly<{
|
|
32
|
+
path: string;
|
|
33
|
+
sha256: string;
|
|
34
|
+
mode: number;
|
|
35
|
+
}>[];
|
|
36
|
+
readonly admissionSha256: string;
|
|
37
|
+
}
|
|
38
|
+
export interface PrivateRefactorAdmissionV2 extends Omit<PrivateRefactorAdmissionV1, 'schemaVersion'> {
|
|
39
|
+
readonly schemaVersion: 2;
|
|
40
|
+
readonly newFiles: readonly Readonly<{
|
|
41
|
+
path: string;
|
|
42
|
+
}>[];
|
|
43
|
+
}
|
|
44
|
+
export type PrivateRefactorAdmission = PrivateRefactorAdmissionV1 | PrivateRefactorAdmissionV2;
|
|
45
|
+
export interface RefactorRootAdmissionReceiptV1 {
|
|
46
|
+
readonly schemaVersion: 1;
|
|
47
|
+
readonly kind: 'root-refactor-write-set-admission';
|
|
48
|
+
readonly storyId: string;
|
|
49
|
+
readonly sourceHead: string;
|
|
50
|
+
readonly planSha256: string;
|
|
51
|
+
readonly writeSetSha256: string;
|
|
52
|
+
readonly admissionSha256: string;
|
|
53
|
+
readonly fileCount: number;
|
|
54
|
+
readonly rootEditPrepared: true;
|
|
55
|
+
readonly privateChildAuthorized: false;
|
|
56
|
+
readonly gitCommitAuthorized: false;
|
|
57
|
+
readonly publicSafe: true;
|
|
58
|
+
}
|
|
59
|
+
export interface RefactorRootAdmissionReceiptV2 extends Omit<RefactorRootAdmissionReceiptV1, 'schemaVersion'> {
|
|
60
|
+
readonly schemaVersion: 2;
|
|
61
|
+
readonly newFileCount: number;
|
|
62
|
+
}
|
|
63
|
+
export declare function readPrivateRefactorAdmission(root: string, sha256: string): PrivateRefactorAdmission;
|
|
64
|
+
export declare function admitRootRefactor(projectRoot: string, storyId: string, planSha256: string, paths: readonly string[], authorizeRootEdit: boolean, newPaths?: readonly string[]): RefactorRootAdmissionReceiptV1 | RefactorRootAdmissionReceiptV2;
|
|
65
|
+
export interface RefactorRootContainmentReceiptV1 {
|
|
66
|
+
readonly schemaVersion: 1;
|
|
67
|
+
readonly kind: 'root-refactor-delta-containment';
|
|
68
|
+
readonly storyId: string;
|
|
69
|
+
readonly sourceHead: string;
|
|
70
|
+
readonly planSha256: string;
|
|
71
|
+
readonly admissionSha256: string;
|
|
72
|
+
readonly writeSetSha256: string;
|
|
73
|
+
readonly changedFileCount: number;
|
|
74
|
+
readonly rootEditContained: true;
|
|
75
|
+
readonly qaAccepted: false;
|
|
76
|
+
readonly gitCommitAuthorized: false;
|
|
77
|
+
readonly publicSafe: true;
|
|
78
|
+
}
|
|
79
|
+
export interface RefactorRootContainmentReceiptV2 extends Omit<RefactorRootContainmentReceiptV1, 'schemaVersion'> {
|
|
80
|
+
readonly schemaVersion: 2;
|
|
81
|
+
readonly newFileCount: number;
|
|
82
|
+
}
|
|
83
|
+
export declare function verifyRootRefactor(projectRoot: string, admissionSha256: string): RefactorRootContainmentReceiptV1 | RefactorRootContainmentReceiptV2;
|
|
84
|
+
export declare function planRootRefactor(projectRoot: string, storyId: string): RefactorRootPlanV1;
|
|
85
|
+
export declare function refactorRootCliHandler(args: readonly string[]): number;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{createHash as rr}from"node:crypto";import{closeSync as J,constants as $,existsSync as er,fsyncSync as q,lstatSync as p,mkdirSync as tr,openSync as I,readFileSync as k,realpathSync as x,writeFileSync as or}from"node:fs";import{dirname as Y,isAbsolute as X,join as z,resolve as H}from"node:path";import{mutationQaGit as g}from"./mutation-qa-git.js";const G=/^P[0-9]{1,12}(?:\.[0-9]{1,12}){1,3}$/,F=/^[a-f0-9]{64}$/,j=8*1024*1024,_=256;function m(i){return rr("sha256").update(i).digest("hex")}function M(i){const o=g(i,["rev-parse","--git-common-dir"]).toString("utf8").trim(),r=X(o)?H(o):H(i,o);if(x(r)!==r||p(r).isSymbolicLink()||p(r).uid!==process.getuid?.())throw new Error("refactor-root-store-unverified");const e=z(r,"neocortex-refactor");tr(e,{recursive:!0,mode:448});const s=p(e);if(!s.isDirectory()||s.isSymbolicLink()||s.uid!==process.getuid?.()||(s.mode&63)!==0)throw new Error("refactor-root-store-unverified");return e}function R(i){return!i||i.length>512||X(i)||i.includes("\\")||/[\u0000-\u001f\u007f:*?\[\]]/.test(i)||i.normalize("NFC")!==i?!1:!i.split("/").some(r=>!r||r==="."||r===".."||[".git",".neocortex","node_modules"].includes(r.toLowerCase()))}function ir(i,o){if(!R(o))throw new Error("refactor-root-write-set-invalid");const r=z(i,o),e=p(r);if(x(r)!==r||!e.isFile()||e.isSymbolicLink()||e.size===0||e.size>j)throw new Error("refactor-root-write-set-invalid");const s=k(r);if(s.length===0||s.length>j)throw new Error("refactor-root-write-set-invalid");if(new TextDecoder("utf-8",{fatal:!0}).decode(s),s.includes(0))throw new Error("refactor-root-write-set-invalid");const n=g(i,["show",`HEAD:${o}`]);if(!s.equals(n))throw new Error("refactor-root-source-dirty");return Object.freeze({sha256:m(s),mode:e.mode&511})}function U(i,o){try{return g(i,["check-ignore","--no-index","-q","--",o]),!0}catch(r){if(r.status===1)return!1;throw r}}function T(i,o){if(!R(o))throw new Error("refactor-root-write-set-invalid");const r=z(i,o),e=Y(r),s=p(e);if(!s.isDirectory()||s.isSymbolicLink()||x(e)!==e||g(i,["ls-files","--stage","-z","--",o]).length>0||U(i,o))throw new Error("refactor-root-write-set-invalid");try{throw p(r),new Error("refactor-root-write-set-invalid")}catch(n){if(n.code!=="ENOENT")throw n}}function L(i){return m(g(i,["ls-files","--stage","-z"]))}function D(i,o){const r=g(i,o);return new TextDecoder("utf-8",{fatal:!0}).decode(r).split("\0").filter(Boolean)}function W(i){if(D(i,["ls-files","-v","-z"]).some(r=>!r.startsWith("H ")))throw new Error("refactor-root-index-unverified")}function C(i){const o=[];let r=0;for(const e of D(i,["status","--porcelain=v1","-z","--untracked-files=all"])){if(e.length<4||e[2]!==" ")throw new Error("refactor-root-sidecar-unverified");const s=e.slice(3);if(!s.startsWith(".neocortex/"))continue;if(s.includes("\\")||/[\u0000-\u001f\u007f]/.test(s)||s.split("/").some(l=>!l||l==="."||l===".."))throw new Error("refactor-root-sidecar-unverified");const n=z(i,s),t=p(n);if(x(n)!==n||!t.isFile()||t.isSymbolicLink()||t.size>64*1024*1024)throw new Error("refactor-root-sidecar-unverified");if(r+=t.size,r>128*1024*1024)throw new Error("refactor-root-sidecar-unverified");const c=k(n);if(c.length>64*1024*1024)throw new Error("refactor-root-sidecar-unverified");o.push({status:e.slice(0,2),path:s,sha256:m(c),mode:t.mode&511})}return o.sort((e,s)=>Buffer.from(e.path).compare(Buffer.from(s.path))),m(JSON.stringify(o))}function P(i){return[...i].sort((o,r)=>Buffer.from(o).compare(Buffer.from(r)))}function Q(i){const o=i.files.map(r=>r.path);return m(JSON.stringify(i.schemaVersion===1?o:{files:o,newFiles:i.newFiles.map(r=>r.path)}))}function K(i,o){if(!F.test(o))throw new Error("refactor-root-admission-invalid");return z(M(i),`admission-${o}.json`)}function B(i,o){const r=K(i,o),e=p(r);if(!e.isFile()||e.isSymbolicLink()||e.uid!==process.getuid?.()||(e.mode&63)!==0||e.size<100||e.size>512*1024)throw new Error("refactor-root-admission-invalid");const s=k(r);if(s.length>512*1024)throw new Error("refactor-root-admission-invalid");let n;try{n=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(s))}catch{throw new Error("refactor-root-admission-invalid")}if(!n||typeof n!="object"||Array.isArray(n))throw new Error("refactor-root-admission-invalid");const t=n,c=t.schemaVersion===2,l=["schemaVersion","kind","storyId","sourceHead","storySha256","planSha256","indexSha256","sidecarSha256","files","admissionSha256"];if(c&&l.push("newFiles"),Object.keys(t).sort().join("\0")!==l.sort().join("\0")||![1,2].includes(t.schemaVersion)||t.kind!=="private-root-refactor-admission"||typeof t.storyId!="string"||!G.test(t.storyId)||typeof t.sourceHead!="string"||!/^[a-f0-9]{40}(?:[a-f0-9]{24})?$/.test(t.sourceHead)||typeof t.storySha256!="string"||!F.test(t.storySha256)||typeof t.planSha256!="string"||!F.test(t.planSha256)||typeof t.indexSha256!="string"||!F.test(t.indexSha256)||typeof t.sidecarSha256!="string"||!F.test(t.sidecarSha256)||t.admissionSha256!==o||!Array.isArray(t.files)||t.files.length>_||(c?!Array.isArray(t.newFiles)||t.newFiles.length<1||t.files.length+t.newFiles.length>_:t.files.length<1))throw new Error("refactor-root-admission-invalid");if(m(`root-refactor-story-scope-v1\0${t.sourceHead}\0${t.storyId}\0${t.storySha256}`)!==t.planSha256)throw new Error("refactor-root-admission-invalid");const S=t.files;if(S.some(a=>!a||typeof a!="object"||Array.isArray(a)||Object.keys(a).sort().join("\0")!==["mode","path","sha256"].join("\0")||typeof a.path!="string"||!R(a.path)||typeof a.sha256!="string"||!F.test(a.sha256)||!Number.isSafeInteger(a.mode)||a.mode<0||a.mode>511))throw new Error("refactor-root-admission-invalid");const d=S.map(a=>a.path);if(new Set(d).size!==d.length||d.join("\0")!==P(d).join("\0"))throw new Error("refactor-root-admission-invalid");if(c){const a=t.newFiles;if(a.some(E=>!E||typeof E!="object"||Array.isArray(E)||Object.keys(E).join("\0")!=="path"||typeof E.path!="string"||!R(E.path)))throw new Error("refactor-root-admission-invalid");const y=a.map(E=>E.path);if(new Set([...d,...y]).size!==d.length+y.length||y.join("\0")!==P(y).join("\0")||[...d,...y].includes(`docs/stories/${t.storyId}.story.md`))throw new Error("refactor-root-admission-invalid")}const{admissionSha256:h,...w}=t;if(m(JSON.stringify(w))!==o||!s.equals(Buffer.from(`${JSON.stringify(t)}
|
|
2
|
+
`)))throw new Error("refactor-root-admission-invalid");return t}function sr(i,o,r,e,s,n=[]){if(!s)throw new Error("refactor-root-authorization-required");if(!F.test(r)||e.length+n.length<1||e.length+n.length>_)throw new Error("refactor-root-write-set-invalid");const t=H(i);try{const c=V(t,o);if(c.planSha256!==r)throw new Error("refactor-root-plan-stale");W(t);const l=L(t),S=C(t),d=P(e),h=P(n);if(new Set([...d,...h]).size!==d.length+h.length||[...d,...h].includes(`docs/stories/${o}.story.md`))throw new Error("refactor-root-write-set-invalid");const w=d.map(u=>Object.freeze({path:u,...ir(t,u)})),a=h.map(u=>(T(t,u),Object.freeze({path:u})));if(L(t)!==l||C(t)!==S||V(t,o).planSha256!==r)throw new Error("refactor-root-source-dirty");for(const u of a)T(t,u.path);const y={kind:"private-root-refactor-admission",storyId:o,sourceHead:c.sourceHead,storySha256:c.storySha256,planSha256:r,indexSha256:l,sidecarSha256:S,files:w},E=a.length>0?{schemaVersion:2,...y,newFiles:a}:{schemaVersion:1,...y},A=m(JSON.stringify(E)),N={...E,admissionSha256:A},f=K(t,A),b=Buffer.from(`${JSON.stringify(N)}
|
|
3
|
+
`);if(er(f))B(t,A);else{const u=I(f,$.O_WRONLY|$.O_CREAT|$.O_EXCL|($.O_NOFOLLOW??0),384);try{or(u,b),q(u)}finally{J(u)}const O=I(M(t),$.O_RDONLY|($.O_DIRECTORY??0));try{q(O)}finally{J(O)}}if(B(t,A),L(t)!==l||C(t)!==S||V(t,o).planSha256!==r)throw new Error("refactor-root-source-dirty");for(const u of a)T(t,u.path);const v={kind:"root-refactor-write-set-admission",storyId:o,sourceHead:c.sourceHead,planSha256:r,writeSetSha256:Q(N),admissionSha256:A,fileCount:w.length,rootEditPrepared:!0,privateChildAuthorized:!1,gitCommitAuthorized:!1,publicSafe:!0};return N.schemaVersion===2?Object.freeze({schemaVersion:2,...v,newFileCount:a.length}):Object.freeze({schemaVersion:1,...v})}catch(c){throw c instanceof Error&&c.message.startsWith("refactor-root-")?c:new Error("refactor-root-write-set-invalid")}}function Z(i,o){if(!R(o)||U(i,o)||g(i,["ls-files","--stage","-z","--",o]).length>0)throw new Error("refactor-root-delta-outside-admission");const r=z(i,o),e=Y(r);if(!p(e).isDirectory()||x(e)!==e)throw new Error("refactor-root-delta-outside-admission");const s=p(r);if(x(r)!==r||!s.isFile()||s.isSymbolicLink()||s.size===0||s.size>j||(s.mode&75)!==0)throw new Error("refactor-root-delta-outside-admission");const n=k(r);if(n.length===0||n.length>j||n.includes(0))throw new Error("refactor-root-delta-outside-admission");return new TextDecoder("utf-8",{fatal:!0}).decode(n),m(n)}function nr(i,o){const r=H(i);try{const e=B(r,o),s=g(r,["rev-parse","--verify","HEAD"]).toString("utf8").trim();if(s!==e.sourceHead||L(r)!==e.indexSha256||C(r)!==e.sidecarSha256)throw new Error("refactor-root-baseline-stale");W(r);const n=z(r,"docs","stories",`${e.storyId}.story.md`),t=p(n);if(!t.isFile()||t.isSymbolicLink()||x(n)!==n||m(k(n))!==e.storySha256||m(g(r,["show",`HEAD:docs/stories/${e.storyId}.story.md`]))!==e.storySha256)throw new Error("refactor-root-baseline-stale");const c=D(r,["diff","--name-only","-z","--no-ext-diff","--no-textconv"]).filter(f=>!f.startsWith(".neocortex/")),l=D(r,["ls-files","--others","--exclude-standard","-z"]).filter(f=>!f.startsWith(".neocortex/")),S=new Set(e.files.map(f=>f.path)),d=e.schemaVersion===2?e.newFiles.map(f=>f.path):[],h=new Set(d);if(c.length+l.length===0||l.length!==h.size||c.some(f=>!S.has(f))||l.some(f=>!h.has(f)))throw new Error("refactor-root-delta-outside-admission");let w=0;const a=[];for(const f of e.files){const b=z(r,f.path);if(m(g(r,["show",`HEAD:${f.path}`]))!==f.sha256)throw new Error("refactor-root-admission-invalid");const v=p(b);if(x(b)!==b||!v.isFile()||v.isSymbolicLink()||v.size===0||v.size>j||(v.mode&511)!==f.mode)throw new Error("refactor-root-delta-outside-admission");const u=k(b);if(u.length===0||u.length>j)throw new Error("refactor-root-delta-outside-admission");if(new TextDecoder("utf-8",{fatal:!0}).decode(u),u.includes(0))throw new Error("refactor-root-delta-outside-admission");const O=m(u);a.push(O),O!==f.sha256&&w++}const y=d.map(f=>Z(r,f));w+=y.length;const E=D(r,["diff","--name-only","-z","--no-ext-diff","--no-textconv"]).filter(f=>!f.startsWith(".neocortex/")),A=D(r,["ls-files","--others","--exclude-standard","-z"]).filter(f=>!f.startsWith(".neocortex/"));if(W(r),w===0||w!==c.length+l.length||E.join("\0")!==c.join("\0")||A.join("\0")!==l.join("\0")||e.files.some((f,b)=>{const v=z(r,f.path),u=p(v);if(x(v)!==v||!u.isFile()||u.isSymbolicLink()||u.size>j||(u.mode&511)!==f.mode)return!0;const O=k(v);return O.length>j||m(O)!==a[b]})||d.some((f,b)=>Z(r,f)!==y[b])||L(r)!==e.indexSha256||C(r)!==e.sidecarSha256||g(r,["rev-parse","--verify","HEAD"]).toString("utf8").trim()!==s)throw new Error("refactor-root-baseline-stale");const N={kind:"root-refactor-delta-containment",storyId:e.storyId,sourceHead:e.sourceHead,planSha256:e.planSha256,admissionSha256:o,writeSetSha256:Q(e),changedFileCount:w,rootEditContained:!0,qaAccepted:!1,gitCommitAuthorized:!1,publicSafe:!0};return e.schemaVersion===2?Object.freeze({schemaVersion:2,...N,newFileCount:d.length}):Object.freeze({schemaVersion:1,...N})}catch(e){throw e instanceof Error&&e.message.startsWith("refactor-root-")?e:new Error("refactor-root-delta-unverified")}}function V(i,o){if(!G.test(o))throw new Error("refactor-root-story-invalid");const r=H(i);try{if(x(r)!==r||!p(r).isDirectory())throw new Error("refactor-root-source-unverified");if(g(r,["rev-parse","--show-toplevel"]).toString("utf8").trim()!==r)throw new Error("refactor-root-source-unverified");if(g(r,["status","--porcelain=v1","-z","--untracked-files=all"]).toString("utf8").split("\0").filter(Boolean).some(a=>!/^.{2} \.neocortex\//.test(a)))throw new Error("refactor-root-source-dirty");const n=g(r,["rev-parse","--verify","HEAD"]).toString("utf8").trim();if(!/^[a-f0-9]{40}(?:[a-f0-9]{24})?$/.test(n))throw new Error("refactor-root-source-unverified");const t=`docs/stories/${o}.story.md`,c=z(r,t),l=p(c);if(x(c)!==c||!l.isFile()||l.isSymbolicLink()||l.size===0||l.size>1024*1024)throw new Error("refactor-root-story-unverified");const S=k(c),d=g(r,["show",`HEAD:${t}`]);if(!S.equals(d))throw new Error("refactor-root-story-unverified");const h=m(S),w=m(`root-refactor-story-scope-v1\0${n}\0${o}\0${h}`);return Object.freeze({schemaVersion:1,kind:"root-refactor-story-scope",storyId:o,sourceHead:n,storySha256:h,planSha256:w,candidateWriteSetRequired:!0,characterizationRequired:!0,executionAuthorized:!1,gitAuthority:"ROOT_ONLY",graphExecution:"NOT_RUN",publicSafe:!0})}catch(e){throw e instanceof Error&&e.message.startsWith("refactor-root-")?e:new Error("refactor-root-source-unverified")}}function lr(i){let o="",r="",e="",s="",n="",t=!1;const c=[],l=[];let S="plain";try{const d=[...i];o=d.shift()??"";for(let h=0;h<d.length;h++){const w=d[h],a=()=>{const y=d[++h];if(!y||y.startsWith("--"))throw new Error("refactor-root-arguments-invalid");return y};if(w==="--project-root")r=a();else if(w==="--story")e=a();else if(w==="--plan-sha")s=a();else if(w==="--admission-sha")n=a();else if(w==="--path")c.push(a());else if(w==="--new-path")l.push(a());else if(w==="--authorize-root-edit")t=!0;else if(w==="--format")S=a();else throw new Error("refactor-root-arguments-invalid")}if(!r||!["plain","json"].includes(S))throw new Error("refactor-root-arguments-invalid");if(o==="plan"&&e&&!s&&!n&&c.length===0&&l.length===0&&!t){const h=V(r,e);process.stdout.write(`${JSON.stringify({ok:!0,plan:h})}
|
|
4
|
+
`)}else if(o==="admit"&&e&&s&&!n&&c.length+l.length>0){const h=sr(r,e,s,c,t,l);process.stdout.write(`${JSON.stringify({ok:!0,admission:h})}
|
|
5
|
+
`)}else if(o==="verify"&&!e&&!s&&n&&c.length===0&&l.length===0&&!t){const h=nr(r,n);process.stdout.write(`${JSON.stringify({ok:!0,containment:h})}
|
|
6
|
+
`)}else throw new Error("refactor-root-arguments-invalid");return 0}catch(d){const h=d instanceof Error&&/^refactor-root-[a-z-]+$/.test(d.message)?d.message:"refactor-root-source-unverified";return process.stdout.write(`${JSON.stringify({ok:!1,reasonCode:h})}
|
|
7
|
+
`),1}}export{sr as admitRootRefactor,ir as exactCommittedRefactorFile,V as planRootRefactor,M as privateRefactorDirectory,B as readPrivateRefactorAdmission,lr as refactorRootCliHandler,C as refactorSidecarDigest,nr as verifyRootRefactor};
|
|
@@ -2,35 +2,35 @@
|
|
|
2
2
|
export { PUBLIC_PROJECTION_BUNDLE, PUBLIC_PROJECTION_GENERATION_ID, PUBLIC_PROJECTION_BUNDLE_HASH } from './public-projections.generated.js';
|
|
3
3
|
export declare const COMMAND_REGISTRY_SCHEMA_VERSION: 1;
|
|
4
4
|
export declare const COMMAND_REGISTRY_VERSION: "1.0.0";
|
|
5
|
-
export declare const COMMAND_REGISTRY_CHECKSUM: "
|
|
5
|
+
export declare const COMMAND_REGISTRY_CHECKSUM: "184a2d616e0734fd3173d60889d74bae031280513831ec1f0a3a8c36959d2994";
|
|
6
6
|
export declare const COMMAND_REGISTRY_PROJECTION_MANIFEST: {
|
|
7
7
|
readonly schemaVersion: 1;
|
|
8
8
|
readonly registryVersion: "1.0.0";
|
|
9
|
-
readonly registryChecksum: "
|
|
9
|
+
readonly registryChecksum: "184a2d616e0734fd3173d60889d74bae031280513831ec1f0a3a8c36959d2994";
|
|
10
10
|
readonly projections: readonly [{
|
|
11
11
|
readonly kind: "admin";
|
|
12
12
|
readonly entryCount: 62;
|
|
13
|
-
readonly sha256: "
|
|
13
|
+
readonly sha256: "03492ffc9a4b868286c5dd9b62d04d16f61871dcf8a073f6d6fba6878fd765ea";
|
|
14
14
|
}, {
|
|
15
15
|
readonly kind: "client";
|
|
16
16
|
readonly entryCount: 62;
|
|
17
|
-
readonly sha256: "
|
|
17
|
+
readonly sha256: "03492ffc9a4b868286c5dd9b62d04d16f61871dcf8a073f6d6fba6878fd765ea";
|
|
18
18
|
}, {
|
|
19
19
|
readonly kind: "docs";
|
|
20
20
|
readonly entryCount: 62;
|
|
21
|
-
readonly sha256: "
|
|
21
|
+
readonly sha256: "03492ffc9a4b868286c5dd9b62d04d16f61871dcf8a073f6d6fba6878fd765ea";
|
|
22
22
|
}, {
|
|
23
23
|
readonly kind: "metrics";
|
|
24
24
|
readonly entryCount: 62;
|
|
25
|
-
readonly sha256: "
|
|
25
|
+
readonly sha256: "03492ffc9a4b868286c5dd9b62d04d16f61871dcf8a073f6d6fba6878fd765ea";
|
|
26
26
|
}, {
|
|
27
27
|
readonly kind: "server";
|
|
28
28
|
readonly entryCount: 67;
|
|
29
|
-
readonly sha256: "
|
|
29
|
+
readonly sha256: "d2071a42b5707e72be9886433c5ce19123d55a8641e30092f5a9354182fc51df";
|
|
30
30
|
}, {
|
|
31
31
|
readonly kind: "shared";
|
|
32
32
|
readonly entryCount: 67;
|
|
33
|
-
readonly sha256: "
|
|
33
|
+
readonly sha256: "91620a92df8c33a339cf6cab26befba92cbac608cd2fdaf3801ceacd5e15e703";
|
|
34
34
|
}];
|
|
35
35
|
};
|
|
36
36
|
export declare const GENERATED_CLIENT_COMMANDS: readonly [{
|
|
@@ -841,7 +841,7 @@ export declare const GENERATED_CLIENT_COMMANDS: readonly [{
|
|
|
841
841
|
readonly minimumTier: "pro";
|
|
842
842
|
readonly mutationClass: "stateful";
|
|
843
843
|
readonly privilege: "authenticated";
|
|
844
|
-
readonly quotaClass: "
|
|
844
|
+
readonly quotaClass: "workflow";
|
|
845
845
|
readonly replayClass: "signed-request";
|
|
846
846
|
readonly strictReadOnly: "deny";
|
|
847
847
|
};
|