@coderifts/agent-guard 12.0.0 → 13.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/cas-adapters/fs-default-wire.d.ts +40 -10
- package/dist/cjs/cas-adapters/fs-default-wire.d.ts.map +1 -1
- package/dist/cjs/cas-adapters/fs-default-wire.js +46 -18
- package/dist/cjs/cas-adapters/fs-default-wire.js.map +1 -1
- package/dist/cjs/cas-adapters/fs.d.ts +49 -0
- package/dist/cjs/cas-adapters/fs.d.ts.map +1 -1
- package/dist/cjs/cas-adapters/fs.js +167 -13
- package/dist/cjs/cas-adapters/fs.js.map +1 -1
- package/dist/cjs/cas-attestation.d.ts +16 -1
- package/dist/cjs/cas-attestation.d.ts.map +1 -1
- package/dist/cjs/cas-attestation.js +18 -0
- package/dist/cjs/cas-attestation.js.map +1 -1
- package/dist/cjs/conditional-write.d.ts +55 -0
- package/dist/cjs/conditional-write.d.ts.map +1 -1
- package/dist/cjs/conditional-write.js +6 -0
- package/dist/cjs/conditional-write.js.map +1 -1
- package/dist/cjs/index.d.ts +5 -3
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +10 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/tool-registry.d.ts.map +1 -1
- package/dist/cjs/tool-registry.js +15 -2
- package/dist/cjs/tool-registry.js.map +1 -1
- package/dist/esm/cas-adapters/fs-default-wire.d.ts +40 -10
- package/dist/esm/cas-adapters/fs-default-wire.d.ts.map +1 -1
- package/dist/esm/cas-adapters/fs-default-wire.js +45 -19
- package/dist/esm/cas-adapters/fs-default-wire.js.map +1 -1
- package/dist/esm/cas-adapters/fs.d.ts +49 -0
- package/dist/esm/cas-adapters/fs.d.ts.map +1 -1
- package/dist/esm/cas-adapters/fs.js +162 -12
- package/dist/esm/cas-adapters/fs.js.map +1 -1
- package/dist/esm/cas-attestation.d.ts +16 -1
- package/dist/esm/cas-attestation.d.ts.map +1 -1
- package/dist/esm/cas-attestation.js +18 -0
- package/dist/esm/cas-attestation.js.map +1 -1
- package/dist/esm/conditional-write.d.ts +55 -0
- package/dist/esm/conditional-write.d.ts.map +1 -1
- package/dist/esm/conditional-write.js +6 -0
- package/dist/esm/conditional-write.js.map +1 -1
- package/dist/esm/index.d.ts +5 -3
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/tool-registry.d.ts.map +1 -1
- package/dist/esm/tool-registry.js +16 -3
- package/dist/esm/tool-registry.js.map +1 -1
- package/package.json +1 -1
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
'use strict';
|
|
14
14
|
import { isExecuteIfUnchangedOutcome } from '../cas-attestation.js';
|
|
15
|
-
import { createFsVersionToken, writeFileIfUnchanged } from './fs.js';
|
|
15
|
+
import { assertSafeCasPath, createFsVersionToken, fsObjectIdentity, writeFileIfUnchanged } from './fs.js';
|
|
16
16
|
/** Unambiguous fs target: a non-empty `path` string on tool arguments (Write convention). */
|
|
17
17
|
export function inferFsPathFromArgs(args) {
|
|
18
18
|
if (!args || typeof args !== 'object')
|
|
@@ -47,31 +47,29 @@ export function inferFullFileWriteContent(args) {
|
|
|
47
47
|
* Otherwise run the host write unchanged. If the host already returned an
|
|
48
48
|
* ExecuteIfUnchangedOutcome, pass it through (do not wrap again).
|
|
49
49
|
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
50
|
+
* THE TOKEN MUST COME FROM T1. This function used to call createFsVersionToken HERE, inside
|
|
51
|
+
* executeFactory — after preflight (T1) and after the T2 recheck — and then condition the write on
|
|
52
|
+
* that self-fetched value. Measured on 12.0.0: with a writer landing between T2 and that read, the
|
|
53
|
+
* CAS adopted the interfering state as its legitimate starting point and still reported
|
|
54
|
+
* status:'committed' with enforced:true. It was a real check of a vacuous window — it asked whether
|
|
55
|
+
* the state had changed since a read a microsecond earlier, which is a question whose answer is
|
|
56
|
+
* always no and which says nothing about the state the authorization actually examined.
|
|
57
|
+
*
|
|
58
|
+
* Now the expected token is supplied by the caller from the T1 measurement. When it is ABSENT we do
|
|
59
|
+
* NOT fall back to self-fetching, because that is precisely the vacuous claim: the write runs
|
|
60
|
+
* unwrapped and the guarantee is NON_ATOMIC, which is the honest thing to report and which
|
|
61
|
+
* requireConditionalWrite will refuse. A weaker guarantee is reportable; a false one is not.
|
|
59
62
|
*/
|
|
60
|
-
export async function wrapWriteWithFsCas(args, write) {
|
|
63
|
+
export async function wrapWriteWithFsCas(args, write, opts) {
|
|
61
64
|
const filePath = inferFsPathFromArgs(args);
|
|
62
65
|
const content = inferFullFileWriteContent(args);
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
try {
|
|
66
|
-
expected = await createFsVersionToken(filePath);
|
|
67
|
-
}
|
|
68
|
-
catch {
|
|
69
|
-
return write();
|
|
70
|
-
}
|
|
66
|
+
const expected = opts && typeof opts.expected_token === 'string' ? opts.expected_token : null;
|
|
67
|
+
if (filePath && content != null && expected !== null) {
|
|
71
68
|
return writeFileIfUnchanged({
|
|
72
69
|
path: filePath,
|
|
73
70
|
expected_token: expected,
|
|
74
71
|
content,
|
|
72
|
+
...(opts && 'expected_identity' in opts ? { expected_identity: opts.expected_identity ?? null } : {}),
|
|
75
73
|
});
|
|
76
74
|
}
|
|
77
75
|
const raw = await write();
|
|
@@ -79,4 +77,32 @@ export async function wrapWriteWithFsCas(args, write) {
|
|
|
79
77
|
return raw;
|
|
80
78
|
return raw;
|
|
81
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* The T1 measurement itself — call this in the RUNNER, before preflight, and pass the result to
|
|
82
|
+
* wrapWriteWithFsCas. Returns null when this call is not an inferable full-file FS write, or when
|
|
83
|
+
* the path is unsafe / unreadable (a token we could not measure is not a token we may claim).
|
|
84
|
+
*/
|
|
85
|
+
export async function measureFsAuthorization(args) {
|
|
86
|
+
const filePath = inferFsPathFromArgs(args);
|
|
87
|
+
const content = inferFullFileWriteContent(args);
|
|
88
|
+
if (!filePath || content == null)
|
|
89
|
+
return null;
|
|
90
|
+
try {
|
|
91
|
+
const target = await assertSafeCasPath(filePath);
|
|
92
|
+
// Identity FIRST, then the token: both must describe the same observation, and taking identity
|
|
93
|
+
// first means a swap between them makes the token the newer of the two, which the pre-rename
|
|
94
|
+
// re-check then catches rather than silently accepting.
|
|
95
|
+
const expected_identity = await fsObjectIdentity(target);
|
|
96
|
+
const expected_token = await createFsVersionToken(target);
|
|
97
|
+
return { expected_token, expected_identity };
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/** Convenience: the token half only. */
|
|
104
|
+
export async function measureFsAuthorizationToken(args) {
|
|
105
|
+
const m = await measureFsAuthorization(args);
|
|
106
|
+
return m ? m.expected_token : null;
|
|
107
|
+
}
|
|
82
108
|
//# sourceMappingURL=fs-default-wire.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs-default-wire.js","sourceRoot":"","sources":["../../../src/cas-adapters/fs-default-wire.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,YAAY,CAAC;AAEb,OAAO,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"fs-default-wire.js","sourceRoot":"","sources":["../../../src/cas-adapters/fs-default-wire.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,6 +21,46 @@ export declare const FS_VERSION_TOKEN_PREFIX = "fs:v1:";
|
|
|
21
21
|
export declare const FS_ABSENT_TOKEN: VersionToken;
|
|
22
22
|
/** Extract content-hash segment from an fs:v1 token (null if absent/malformed). */
|
|
23
23
|
export declare function fsTokenContentHash(token: VersionToken | null | undefined): string | null;
|
|
24
|
+
/**
|
|
25
|
+
* Refuse a path this adapter must not treat as a CAS target.
|
|
26
|
+
*
|
|
27
|
+
* MEASURED ABSENT before this existed (2026-08-27): `..` was silently resolved and the write landed
|
|
28
|
+
* outside the intended directory, and a symlinked target was followed by stat/readFile while the
|
|
29
|
+
* rename replaced the LINK — so the check and the write referred to DIFFERENT objects. That object
|
|
30
|
+
* mismatch is the other half of the TOCTOU: a path interpreted twice can have a symlink swapped in
|
|
31
|
+
* between the two interpretations.
|
|
32
|
+
*
|
|
33
|
+
* Three refusals, each for a different escape:
|
|
34
|
+
* - a literal `..` segment in the caller's own path (traversal, judged BEFORE resolution),
|
|
35
|
+
* - a symlinked final component (lstat — the object we would check is not the one we would write).
|
|
36
|
+
*
|
|
37
|
+
* The parent directory is CANONICALISED rather than rejected. Requiring realpath(dir) === dir was
|
|
38
|
+
* written first and measured wrong within the hour: on macOS /var is itself a symlink, so every
|
|
39
|
+
* path under a normal temp directory was refused. A symlinked ancestor is not the danger — an
|
|
40
|
+
* ancestor that CHANGES between the check and the write is, and that is closed by the inode/device
|
|
41
|
+
* identity re-check in writeFileIfUnchanged, not by refusing ordinary filesystems. Resolving the
|
|
42
|
+
* parent once and building the target from it means both the check and the write name one object.
|
|
43
|
+
*/
|
|
44
|
+
export declare class UnsafeCasPathError extends Error {
|
|
45
|
+
readonly reason: 'path_traversal' | 'symlink_target';
|
|
46
|
+
readonly casPath: string;
|
|
47
|
+
constructor(reason: 'path_traversal' | 'symlink_target', casPath: string);
|
|
48
|
+
}
|
|
49
|
+
export declare function assertSafeCasPath(filePath: string): Promise<string>;
|
|
50
|
+
/** Filesystem identity of the object a token was measured on. Evidence, not a comparison key. */
|
|
51
|
+
export type FsObjectIdentity = {
|
|
52
|
+
dev: number;
|
|
53
|
+
ino: number;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Identity of the object CURRENTLY at a path, read through a FILE DESCRIPTOR.
|
|
57
|
+
*
|
|
58
|
+
* Opening once and fstat-ing the handle is what makes this an identity rather than another path
|
|
59
|
+
* interpretation: the fd names the object, so a symlink swapped in afterwards cannot redirect it.
|
|
60
|
+
* null when the path does not exist.
|
|
61
|
+
*/
|
|
62
|
+
export declare function fsObjectIdentity(filePath: string): Promise<FsObjectIdentity | null>;
|
|
63
|
+
export declare function identitiesEqual(a: FsObjectIdentity | null | undefined, b: FsObjectIdentity | null | undefined): boolean;
|
|
24
64
|
/**
|
|
25
65
|
* Build a VersionToken from path: mtime (ms) + sha256 of file bytes.
|
|
26
66
|
* Throws on I/O errors other than callers may catch. ENOENT → returns FS_ABSENT_TOKEN
|
|
@@ -36,6 +76,13 @@ export type WriteFileIfUnchangedArgs = {
|
|
|
36
76
|
path: string;
|
|
37
77
|
/** Token measured before the host decided to write (from createFsVersionToken). */
|
|
38
78
|
expected_token: VersionToken;
|
|
79
|
+
/**
|
|
80
|
+
* Identity (dev+ino) of the object the AUTHORIZATION examined, from fsObjectIdentity at T1.
|
|
81
|
+
* Optional, and when omitted no identity claim is made. Supplying it is strictly stronger than
|
|
82
|
+
* the token alone: an inode swapped in carrying identical bytes and mtime produces an IDENTICAL
|
|
83
|
+
* token, so content equality cannot see it. null means "absent at T1" (create-if-absent).
|
|
84
|
+
*/
|
|
85
|
+
expected_identity?: FsObjectIdentity | null;
|
|
39
86
|
/** Full new file contents (utf8 string or Buffer). */
|
|
40
87
|
content: string | Buffer;
|
|
41
88
|
};
|
|
@@ -59,6 +106,8 @@ export declare function writeFileIfUnchanged(args: WriteFileIfUnchangedArgs): Pr
|
|
|
59
106
|
path: string;
|
|
60
107
|
bytes: number;
|
|
61
108
|
written_content_hash: string;
|
|
109
|
+
checked_identity: FsObjectIdentity | null;
|
|
110
|
+
committed_identity: FsObjectIdentity | null;
|
|
62
111
|
}>>;
|
|
63
112
|
/**
|
|
64
113
|
* Opt-in PriorContentResolver that reads a file path from tool arguments.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../../src/cas-adapters/fs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,OAAO,EAGL,WAAW,EACX,KAAK,yBAAyB,EAC9B,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE5D,mFAAmF;AACnF,eAAO,MAAM,uBAAuB,WAAW,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,YAA6B,CAAC;AAM5D,mFAAmF;AACnF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAQxF;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../../src/cas-adapters/fs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,OAAO,EAGL,WAAW,EACX,KAAK,yBAAyB,EAC9B,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE5D,mFAAmF;AACnF,eAAO,MAAM,uBAAuB,WAAW,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,YAA6B,CAAC;AAM5D,mFAAmF;AACnF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAQxF;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CAAC;IACrD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBACb,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,EAAE,OAAO,EAAE,MAAM;CAMzE;AAED,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmCzE;AAED,iGAAiG;AACjG,MAAM,MAAM,gBAAgB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5D;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAazF;AAED,wBAAgB,eAAe,CAC7B,CAAC,EAAE,gBAAgB,GAAG,IAAI,GAAG,SAAS,EACtC,CAAC,EAAE,gBAAgB,GAAG,IAAI,GAAG,SAAS,GACrC,OAAO,CAGT;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA2BlF;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAOnF;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,mFAAmF;IACnF,cAAc,EAAE,YAAY,CAAC;IAC7B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC5C,sDAAsD;IACtD,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,yBAAyB,CAAC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC1C,kBAAkB,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAC7C,CAAC,CAAC,CAgGF;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,CAAC,EAAE;IACrD;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACrE,GAAG,oBAAoB,CAoBvB;AAED,0FAA0F;AAC1F,OAAO,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -38,15 +38,117 @@ export function fsTokenContentHash(token) {
|
|
|
38
38
|
const hash = rest.slice(colon + 1);
|
|
39
39
|
return /^[a-f0-9]{64}$/.test(hash) ? hash : null;
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Refuse a path this adapter must not treat as a CAS target.
|
|
43
|
+
*
|
|
44
|
+
* MEASURED ABSENT before this existed (2026-08-27): `..` was silently resolved and the write landed
|
|
45
|
+
* outside the intended directory, and a symlinked target was followed by stat/readFile while the
|
|
46
|
+
* rename replaced the LINK — so the check and the write referred to DIFFERENT objects. That object
|
|
47
|
+
* mismatch is the other half of the TOCTOU: a path interpreted twice can have a symlink swapped in
|
|
48
|
+
* between the two interpretations.
|
|
49
|
+
*
|
|
50
|
+
* Three refusals, each for a different escape:
|
|
51
|
+
* - a literal `..` segment in the caller's own path (traversal, judged BEFORE resolution),
|
|
52
|
+
* - a symlinked final component (lstat — the object we would check is not the one we would write).
|
|
53
|
+
*
|
|
54
|
+
* The parent directory is CANONICALISED rather than rejected. Requiring realpath(dir) === dir was
|
|
55
|
+
* written first and measured wrong within the hour: on macOS /var is itself a symlink, so every
|
|
56
|
+
* path under a normal temp directory was refused. A symlinked ancestor is not the danger — an
|
|
57
|
+
* ancestor that CHANGES between the check and the write is, and that is closed by the inode/device
|
|
58
|
+
* identity re-check in writeFileIfUnchanged, not by refusing ordinary filesystems. Resolving the
|
|
59
|
+
* parent once and building the target from it means both the check and the write name one object.
|
|
60
|
+
*/
|
|
61
|
+
export class UnsafeCasPathError extends Error {
|
|
62
|
+
reason;
|
|
63
|
+
casPath;
|
|
64
|
+
constructor(reason, casPath) {
|
|
65
|
+
super(`unsafe CAS path (${reason}): ${casPath}`);
|
|
66
|
+
this.name = 'UnsafeCasPathError';
|
|
67
|
+
this.reason = reason;
|
|
68
|
+
this.casPath = casPath;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export async function assertSafeCasPath(filePath) {
|
|
72
|
+
// 1. Traversal is judged on what the CALLER wrote, not on the resolved form — resolution is
|
|
73
|
+
// exactly what makes `sub/../escaped` look innocent.
|
|
74
|
+
const segments = filePath.split(/[\\/]+/);
|
|
75
|
+
if (segments.includes('..'))
|
|
76
|
+
throw new UnsafeCasPathError('path_traversal', filePath);
|
|
77
|
+
const resolved = path.resolve(filePath);
|
|
78
|
+
// 2. Canonicalise the PARENT once, then rebuild the target from it, so every later use names the
|
|
79
|
+
// same directory object. realpath on the parent only — never on the target itself, because
|
|
80
|
+
// that would follow exactly the final-component symlink step 3 exists to refuse.
|
|
81
|
+
const dir = path.dirname(resolved);
|
|
82
|
+
let canonicalDir = dir;
|
|
83
|
+
try {
|
|
84
|
+
canonicalDir = await fsp.realpath(dir);
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
const code = err && typeof err === 'object' && 'code' in err ? String(err.code) : '';
|
|
88
|
+
if (code !== 'ENOENT')
|
|
89
|
+
throw err;
|
|
90
|
+
// Parent does not exist yet — a create under mkdir -p. Keep the resolved form.
|
|
91
|
+
}
|
|
92
|
+
const target = path.join(canonicalDir, path.basename(resolved));
|
|
93
|
+
// 3. The final component must not be a symlink. lstat does NOT follow; stat would, which is the
|
|
94
|
+
// whole bug: stat/readFile measured the TARGET while rename replaced the LINK, so the check
|
|
95
|
+
// and the write referred to different objects. ENOENT is fine — create-if-absent is legitimate.
|
|
96
|
+
try {
|
|
97
|
+
const lst = await fsp.lstat(target);
|
|
98
|
+
if (lst.isSymbolicLink())
|
|
99
|
+
throw new UnsafeCasPathError('symlink_target', filePath);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
if (err instanceof UnsafeCasPathError)
|
|
103
|
+
throw err;
|
|
104
|
+
const code = err && typeof err === 'object' && 'code' in err ? String(err.code) : '';
|
|
105
|
+
if (code !== 'ENOENT')
|
|
106
|
+
throw err;
|
|
107
|
+
}
|
|
108
|
+
return target;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Identity of the object CURRENTLY at a path, read through a FILE DESCRIPTOR.
|
|
112
|
+
*
|
|
113
|
+
* Opening once and fstat-ing the handle is what makes this an identity rather than another path
|
|
114
|
+
* interpretation: the fd names the object, so a symlink swapped in afterwards cannot redirect it.
|
|
115
|
+
* null when the path does not exist.
|
|
116
|
+
*/
|
|
117
|
+
export async function fsObjectIdentity(filePath) {
|
|
118
|
+
let fh;
|
|
119
|
+
try {
|
|
120
|
+
fh = await fsp.open(filePath, 'r');
|
|
121
|
+
const st = await fh.stat();
|
|
122
|
+
return { dev: st.dev, ino: st.ino };
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
const code = err && typeof err === 'object' && 'code' in err ? String(err.code) : '';
|
|
126
|
+
if (code === 'ENOENT')
|
|
127
|
+
return null;
|
|
128
|
+
throw err;
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
if (fh)
|
|
132
|
+
await fh.close().catch(() => { });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
export function identitiesEqual(a, b) {
|
|
136
|
+
if (!a || !b)
|
|
137
|
+
return false;
|
|
138
|
+
return a.dev === b.dev && a.ino === b.ino;
|
|
139
|
+
}
|
|
41
140
|
/**
|
|
42
141
|
* Build a VersionToken from path: mtime (ms) + sha256 of file bytes.
|
|
43
142
|
* Throws on I/O errors other than callers may catch. ENOENT → returns FS_ABSENT_TOKEN
|
|
44
143
|
* so hosts can CAS create vs create-raced.
|
|
45
144
|
*/
|
|
46
145
|
export async function createFsVersionToken(filePath) {
|
|
47
|
-
|
|
146
|
+
// ONE open, then stat AND read from the same handle. Previously this was stat(path) followed by
|
|
147
|
+
// readFile(path) — two interpretations of the same string, so a swap between them produced a
|
|
148
|
+
// token describing neither object exactly. The fd names the object for both reads.
|
|
149
|
+
let fh;
|
|
48
150
|
try {
|
|
49
|
-
|
|
151
|
+
fh = await fsp.open(filePath, 'r');
|
|
50
152
|
}
|
|
51
153
|
catch (err) {
|
|
52
154
|
const code = err && typeof err === 'object' && 'code' in err
|
|
@@ -56,14 +158,20 @@ export async function createFsVersionToken(filePath) {
|
|
|
56
158
|
return FS_ABSENT_TOKEN;
|
|
57
159
|
throw err;
|
|
58
160
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
161
|
+
try {
|
|
162
|
+
const st = await fh.stat();
|
|
163
|
+
if (!st.isFile()) {
|
|
164
|
+
// Directories / specials are not content CAS targets for this adapter.
|
|
165
|
+
throw new Error(`createFsVersionToken: not a regular file: ${filePath}`);
|
|
166
|
+
}
|
|
167
|
+
const buf = await fh.readFile();
|
|
168
|
+
const hash = sha256hex(buf);
|
|
169
|
+
const mtimeMs = Math.trunc(st.mtimeMs);
|
|
170
|
+
return `${FS_VERSION_TOKEN_PREFIX}${mtimeMs}:${hash}`;
|
|
171
|
+
}
|
|
172
|
+
finally {
|
|
173
|
+
await fh.close().catch(() => { });
|
|
62
174
|
}
|
|
63
|
-
const buf = await fsp.readFile(filePath);
|
|
64
|
-
const hash = sha256hex(buf);
|
|
65
|
-
const mtimeMs = Math.trunc(st.mtimeMs);
|
|
66
|
-
return `${FS_VERSION_TOKEN_PREFIX}${mtimeMs}:${hash}`;
|
|
67
175
|
}
|
|
68
176
|
/**
|
|
69
177
|
* Read file content + version token for VersionedContent (host reporting / preflight prior).
|
|
@@ -94,9 +202,29 @@ export async function readVersionedFile(filePath) {
|
|
|
94
202
|
* Wired through executeIfUnchanged — not a parallel path.
|
|
95
203
|
*/
|
|
96
204
|
export async function writeFileIfUnchanged(args) {
|
|
97
|
-
|
|
205
|
+
// Refuse traversal / symlink / mounted-over-parent BEFORE any token is measured. A CAS over an
|
|
206
|
+
// object the caller did not name is not a weaker guarantee, it is a wrong one.
|
|
207
|
+
const target = await assertSafeCasPath(args.path);
|
|
98
208
|
const body = typeof args.content === 'string' ? Buffer.from(args.content, 'utf8') : args.content;
|
|
99
209
|
const writtenHash = sha256hex(body);
|
|
210
|
+
// Identity of the object the CHECK is about, captured through an fd (null when creating).
|
|
211
|
+
const checkedIdentity = await fsObjectIdentity(target);
|
|
212
|
+
// T1 identity claim: if the caller measured one at authorization time, the object must still be
|
|
213
|
+
// that object BEFORE we do anything. Captured-here identity cannot see a swap that predates this
|
|
214
|
+
// call, which is exactly the case the token also cannot see.
|
|
215
|
+
const hasT1Identity = Object.prototype.hasOwnProperty.call(args, 'expected_identity');
|
|
216
|
+
if (hasT1Identity) {
|
|
217
|
+
const t1 = args.expected_identity ?? null;
|
|
218
|
+
const held = t1 === null ? checkedIdentity === null : identitiesEqual(t1, checkedIdentity);
|
|
219
|
+
if (!held) {
|
|
220
|
+
return {
|
|
221
|
+
status: 'refused',
|
|
222
|
+
reason: 'stale_version_token',
|
|
223
|
+
expected_token: args.expected_token,
|
|
224
|
+
current_token: await createFsVersionToken(target).catch(() => null),
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
}
|
|
100
228
|
return executeIfUnchanged({
|
|
101
229
|
expected_token: args.expected_token,
|
|
102
230
|
current_token: () => createFsVersionToken(target),
|
|
@@ -119,7 +247,22 @@ export async function writeFileIfUnchanged(args) {
|
|
|
119
247
|
const tmp = path.join(dir, `.coderifts-cas-${path.basename(target)}-${process.pid}-${randomBytes(6).toString('hex')}.tmp`);
|
|
120
248
|
try {
|
|
121
249
|
await fsp.writeFile(tmp, body);
|
|
122
|
-
// Close pre-rename window
|
|
250
|
+
// Close pre-rename window on BOTH facts. Content equality alone cannot see an object swap:
|
|
251
|
+
// a symlink or a replaced inode with identical bytes passes a token check and is still a
|
|
252
|
+
// different object. Identity is checked first because it is the stronger statement.
|
|
253
|
+
const stillIdentity = await fsObjectIdentity(target);
|
|
254
|
+
const identityHeld = checkedIdentity === null
|
|
255
|
+
? stillIdentity === null // create-if-absent: nothing may have appeared
|
|
256
|
+
: identitiesEqual(checkedIdentity, stillIdentity);
|
|
257
|
+
if (!identityHeld) {
|
|
258
|
+
try {
|
|
259
|
+
await fsp.unlink(tmp);
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
/* ignore */
|
|
263
|
+
}
|
|
264
|
+
throw new StaleVersionTokenAbort(await createFsVersionToken(target).catch(() => null));
|
|
265
|
+
}
|
|
123
266
|
const still = await createFsVersionToken(target);
|
|
124
267
|
if (!tokensEqual(args.expected_token, still)) {
|
|
125
268
|
try {
|
|
@@ -145,7 +288,14 @@ export async function writeFileIfUnchanged(args) {
|
|
|
145
288
|
}
|
|
146
289
|
throw err;
|
|
147
290
|
}
|
|
148
|
-
|
|
291
|
+
// Evidence: which OBJECT was checked, not merely which path string.
|
|
292
|
+
return {
|
|
293
|
+
path: target,
|
|
294
|
+
bytes: body.length,
|
|
295
|
+
written_content_hash: writtenHash,
|
|
296
|
+
checked_identity: checkedIdentity,
|
|
297
|
+
committed_identity: await fsObjectIdentity(target),
|
|
298
|
+
};
|
|
149
299
|
},
|
|
150
300
|
});
|
|
151
301
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs.js","sourceRoot":"","sources":["../../../src/cas-adapters/fs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,YAAY,CAAC;AAEb,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,QAAQ,IAAI,GAAG,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,WAAW,GAIZ,MAAM,yBAAyB,CAAC;AAGjC,mFAAmF;AACnF,MAAM,CAAC,MAAM,uBAAuB,GAAG,QAAQ,CAAC;AAEhD;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAiB,cAAc,CAAC;AAE5D,SAAS,SAAS,CAAC,GAAW;IAC5B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACxD,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,kBAAkB,CAAC,KAAsC;IACvE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,uBAAuB,CAAC;QAAE,OAAO,IAAI,CAAC;IACzF,IAAI,KAAK,KAAK,eAAe;QAAE,OAAO,IAAI,CAAC;IAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IACnC,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACnD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,QAAgB;IACzD,IAAI,
|
|
1
|
+
{"version":3,"file":"fs.js","sourceRoot":"","sources":["../../../src/cas-adapters/fs.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import type { ExecutorKeyRegistry } from '@coderifts/sdk';
|
|
15
15
|
import type { GuardExecutionProof, ExecutionResultHash } from './execution-proof.js';
|
|
16
|
-
import type { ExecuteIfUnchangedOutcome, VersionToken } from './conditional-write.js';
|
|
16
|
+
import type { ExecuteIfUnchangedOutcome, IndeterminateReason, VersionToken } from './conditional-write.js';
|
|
17
17
|
/** Machine-readable schema id — mirrors EXECUTION_PROOF_SPEC style. */
|
|
18
18
|
export declare const CAS_ATTESTATION_SPEC: "cas-attestation.v1";
|
|
19
19
|
/**
|
|
@@ -51,6 +51,16 @@ export type CasAttestationCas = {
|
|
|
51
51
|
reason: 'stale_during_commit';
|
|
52
52
|
expected_token: VersionToken;
|
|
53
53
|
post_commit_token: VersionToken | null;
|
|
54
|
+
} | {
|
|
55
|
+
status: 'indeterminate';
|
|
56
|
+
/**
|
|
57
|
+
* 'unknown' is a THIRD value, never a default to false. Collapsing it to false would say the
|
|
58
|
+
* write did not run, which is a claim we do not have; collapsing it to true would say it did.
|
|
59
|
+
*/
|
|
60
|
+
write_ran: 'unknown';
|
|
61
|
+
reason: IndeterminateReason;
|
|
62
|
+
expected_token: VersionToken;
|
|
63
|
+
observed_token: VersionToken | null;
|
|
54
64
|
};
|
|
55
65
|
/**
|
|
56
66
|
* Frozen cas-attestation.v1 record.
|
|
@@ -79,6 +89,11 @@ export type CasAttestation = {
|
|
|
79
89
|
stale_during_commit: boolean;
|
|
80
90
|
/** outcome.status === 'refused'. */
|
|
81
91
|
refused: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* outcome.status === 'indeterminate'. Downstream MUST block on this: it is not a pass, and it
|
|
94
|
+
* is not a failure either. Reconciliation is required before anything may proceed.
|
|
95
|
+
*/
|
|
96
|
+
indeterminate: boolean;
|
|
82
97
|
};
|
|
83
98
|
/**
|
|
84
99
|
* Observation-side CAS evidence class (S2-F2a R3). Never a verdict/preimage field.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cas-attestation.d.ts","sourceRoot":"","sources":["../../src/cas-attestation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAErF,OAAO,KAAK,EAAE,yBAAyB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"cas-attestation.d.ts","sourceRoot":"","sources":["../../src/cas-attestation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAErF,OAAO,KAAK,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3G,uEAAuE;AACvE,eAAO,MAAM,oBAAoB,EAAG,oBAA6B,CAAC;AAElE;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,uEAAuE;IACvE,iCAAiC,EAAE,IAAI,CAAC;IACxC,mGAAmG;IACnG,mDAAmD,EAAE,IAAI,CAAC;IAC1D,qGAAqG;IACrG,sCAAsC,EAAE,IAAI,CAAC;IAC7C,4FAA4F;IAC5F,qDAAqD,EAAE,IAAI,CAAC;IAC5D,yFAAyF;IACzF,iCAAiC,EAAE,IAAI,CAAC;IACxC,yFAAyF;IACzF,oCAAoC,EAAE,IAAI,CAAC;CAC5C,CAAC;AAWF,kFAAkF;AAClF,MAAM,MAAM,iBAAiB,GACzB;IACE,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,IAAI,CAAC;IAChB,aAAa,EAAE,YAAY,CAAC;CAC7B,GACD;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,KAAK,CAAC;IACjB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,cAAc,EAAE,YAAY,CAAC;IAC7B,aAAa,EAAE,YAAY,GAAG,IAAI,CAAC;CACpC,GACD;IACE,MAAM,EAAE,0BAA0B,CAAC;IACnC,SAAS,EAAE,IAAI,CAAC;IAChB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,cAAc,EAAE,YAAY,CAAC;IAC7B,iBAAiB,EAAE,YAAY,GAAG,IAAI,CAAC;CACxC,GACD;IACE,MAAM,EAAE,eAAe,CAAC;IACxB;;;OAGG;IACH,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,cAAc,EAAE,YAAY,CAAC;IAC7B,cAAc,EAAE,YAAY,GAAG,IAAI,CAAC;CACrC,CAAC;AAEN;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,gBAAgB,EAAE,OAAO,oBAAoB,CAAC;IAC9C,UAAU,EAAE;QACV,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,qBAAqB,EAAE,mBAAmB,CAAC;QAC3C,gBAAgB,EAAE,OAAO,CAAC;KAC3B,CAAC;IACF,GAAG,EAAE,iBAAiB,CAAC;IACvB,OAAO,EAAE;QACP;;;WAGG;QACH,wBAAwB,EAAE,OAAO,CAAC;QAClC,iEAAiE;QACjE,SAAS,EAAE,OAAO,CAAC;QACnB,qDAAqD;QACrD,mBAAmB,EAAE,OAAO,CAAC;QAC7B,oCAAoC;QACpC,OAAO,EAAE,OAAO,CAAC;QACjB;;;WAGG;QACH,aAAa,EAAE,OAAO,CAAC;KACxB,CAAC;IACF;;;;;OAKG;IACH,YAAY,EAAE,WAAW,CAAC;IAC1B,MAAM,EAAE,oBAAoB,CAAC;CAC9B,CAAC;AAEF,uEAAuE;AACvE,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,GAAG,cAAc,GAAG,QAAQ,CAAC;AAE/E,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,+EAA+E;IAC/E,QAAQ,EAAE,mBAAmB,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,YAAY,CAAC,EAAE;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GAAG,IAAI,CAAC;IACT,0FAA0F;IAC1F,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B,CAAC;AAEF,6FAA6F;AAC7F,MAAM,MAAM,WAAW,GAAG,0BAA0B,GAAG,0BAA0B,CAAC;AAClF,eAAO,MAAM,uBAAuB,EAAG,yBAAkC,CAAC;AAE1E,MAAM,MAAM,uBAAuB,GAAG;IACpC,YAAY,EAAE,WAAW,CAAC;IAC1B,sBAAsB,CAAC,EAAE,OAAO,uBAAuB,CAAC;CACzD,CAAC;AAaF;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,WAAW,GAAG,SAAS,EACjC,IAAI,GAAE,uBAA4B,GACjC,uBAAuB,CAWzB;AAkBD,qFAAqF;AACrF,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAY/E;AAiBD;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,IAAI,GAAE,uBAA4B,GACjC,WAAW,CAsDb;AAED,2DAA2D;AAC3D,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,mBAAmB,CAQ1E;AAED,iFAAiF;AACjF,wBAAgB,2BAA2B,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,yBAAyB,CAAC,OAAO,CAAC,CAuB/F;AA0CD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,mBAAmB,EAC1B,OAAO,EAAE,yBAAyB,CAAC,OAAO,CAAC,EAC3C,IAAI,GAAE,uBAA4B,GACjC,cAAc,CAoDhB"}
|
|
@@ -186,6 +186,13 @@ export function isExecuteIfUnchangedOutcome(x) {
|
|
|
186
186
|
const s = x;
|
|
187
187
|
return s.reason === 'stale_during_commit' && typeof s.expected_token === 'string';
|
|
188
188
|
}
|
|
189
|
+
if (o.status === 'indeterminate') {
|
|
190
|
+
const i = x;
|
|
191
|
+
return (i.reason === 'response_lost'
|
|
192
|
+
|| i.reason === 'ambiguous_provider_reply'
|
|
193
|
+
|| i.reason === 'observation_failed')
|
|
194
|
+
&& typeof i.expected_token === 'string';
|
|
195
|
+
}
|
|
189
196
|
return false;
|
|
190
197
|
}
|
|
191
198
|
function freezeExecutionResultHash(h) {
|
|
@@ -208,6 +215,15 @@ function projectCas(outcome) {
|
|
|
208
215
|
current_token: outcome.current_token == null ? null : outcome.current_token,
|
|
209
216
|
});
|
|
210
217
|
}
|
|
218
|
+
if (outcome.status === 'indeterminate') {
|
|
219
|
+
return Object.freeze({
|
|
220
|
+
status: 'indeterminate',
|
|
221
|
+
write_ran: 'unknown',
|
|
222
|
+
reason: outcome.reason,
|
|
223
|
+
expected_token: outcome.expected_token,
|
|
224
|
+
observed_token: outcome.observed_token == null ? null : outcome.observed_token,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
211
227
|
// committed_stale_detected
|
|
212
228
|
return Object.freeze({
|
|
213
229
|
status: 'committed_stale_detected',
|
|
@@ -237,6 +253,7 @@ export function buildCasAttestation(proof, outcome, opts = {}) {
|
|
|
237
253
|
const write_ran = cas.write_ran === true;
|
|
238
254
|
const stale_during_commit = cas.status === 'committed_stale_detected';
|
|
239
255
|
const refused = cas.status === 'refused';
|
|
256
|
+
const indeterminate = cas.status === 'indeterminate';
|
|
240
257
|
const cas_evidence = evaluateCasEvidence(outcome, opts);
|
|
241
258
|
let authorized_and_committed = receipt_verified && cas.status === 'committed';
|
|
242
259
|
// ENFORCING_STRICT: the existing derived name now requires executor_attested + kernel
|
|
@@ -261,6 +278,7 @@ export function buildCasAttestation(proof, outcome, opts = {}) {
|
|
|
261
278
|
write_ran,
|
|
262
279
|
stale_during_commit,
|
|
263
280
|
refused,
|
|
281
|
+
indeterminate,
|
|
264
282
|
}),
|
|
265
283
|
cas_evidence,
|
|
266
284
|
limits: LIMITS,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cas-attestation.js","sourceRoot":"","sources":["../../src/cas-attestation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAG5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAG5D,uEAAuE;AACvE,MAAM,CAAC,MAAM,oBAAoB,GAAG,oBAA6B,CAAC;AAqBlE,MAAM,MAAM,GAAyB,MAAM,CAAC,MAAM,CAAC;IACjD,iCAAiC,EAAE,IAAI;IACvC,mDAAmD,EAAE,IAAI;IACzD,sCAAsC,EAAE,IAAI;IAC5C,qDAAqD,EAAE,IAAI;IAC3D,iCAAiC,EAAE,IAAI;IACvC,oCAAoC,EAAE,IAAI;CAC3C,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"cas-attestation.js","sourceRoot":"","sources":["../../src/cas-attestation.ts"],"names":[],"mappings":"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"}
|