coderifts 6.0.0 → 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -2
- package/dist/cli.js +186 -28
- package/package.json +2 -2
- package/scripts/assert-guard-major.js +21 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 6.0.
|
|
3
|
+
## 6.0.1
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
### Changed
|
|
6
|
+
- **Guard floor raised to 13, declared range `^13.0.0`.** ADOPTER-FACING: the guard is a direct
|
|
7
|
+
dependency with no `peerDependencies` and no bundled copy, so this range *is* what a fresh install
|
|
8
|
+
resolves. `coderifts@5.0.1` declared `^12.0.0`, which resolves to 12.0.0 — the version in which
|
|
9
|
+
`wrapWriteWithFsCas` measured its expected CAS token INSIDE `executeFactory`, after preflight and
|
|
10
|
+
after the T2 recheck, and conditioned the write on that self-fetched value. Measured on 12.0.0: a
|
|
11
|
+
writer landing in that window had its state adopted as the legitimate starting point and the CAS
|
|
12
|
+
still returned `committed` with `enforced: true`, clobbering it. 13.0.0 threads the
|
|
13
|
+
authorization-time token, and adds three filesystem defences that were measured absent rather than
|
|
14
|
+
assumed — `..` refused before resolution, a symlinked final component refused (`stat`/`readFile`
|
|
15
|
+
measured the link's TARGET while `rename` replaced the LINK, so check and write named different
|
|
16
|
+
objects), the token read through a single file descriptor, and `dev`+`ino` recorded in the write
|
|
17
|
+
evidence.
|
|
18
|
+
|
|
19
|
+
**Cost measured as zero**, the same way the 11-, 12- and 13-raises were: the CLI imports only
|
|
20
|
+
`deployGate`, `asVerifiedDeployReceiptView`, `DEPLOY_RECEIPT_VIEW_SPEC` and `matchGlob`, whose
|
|
21
|
+
implementing modules are byte-identical 12.0.0 → 13.0.0, and all four return identical values
|
|
22
|
+
under both. Suite staged against 13.0.0 returned an identical 539/518/21 with a byte-identical
|
|
23
|
+
28-item failure set. Nothing in the CLI calls the CAS or FS adapters.
|
|
6
24
|
|
|
7
25
|
## 5.0.1
|
|
8
26
|
|
package/dist/cli.js
CHANGED
|
@@ -3028,7 +3028,7 @@ var require_package = __commonJS({
|
|
|
3028
3028
|
"package.json"(exports2, module2) {
|
|
3029
3029
|
module2.exports = {
|
|
3030
3030
|
name: "coderifts",
|
|
3031
|
-
version: "6.0.
|
|
3031
|
+
version: "6.0.1",
|
|
3032
3032
|
description: "Detect breaking API changes from the command line. Works locally or with the CodeRifts cloud API.",
|
|
3033
3033
|
author: "CodeRifts <hello@coderifts.com>",
|
|
3034
3034
|
license: "MIT",
|
|
@@ -3073,7 +3073,7 @@ var require_package = __commonJS({
|
|
|
3073
3073
|
test: "node --test test/*.test.js"
|
|
3074
3074
|
},
|
|
3075
3075
|
dependencies: {
|
|
3076
|
-
"@coderifts/agent-guard": "^
|
|
3076
|
+
"@coderifts/agent-guard": "^13.0.0",
|
|
3077
3077
|
chalk: "^4.1.2",
|
|
3078
3078
|
"cli-table3": "^0.6.4",
|
|
3079
3079
|
commander: "^12.0.0",
|
|
@@ -67189,6 +67189,9 @@ var require_conditional_write = __commonJS({
|
|
|
67189
67189
|
write_style,
|
|
67190
67190
|
mutating
|
|
67191
67191
|
};
|
|
67192
|
+
if (ctx.guarantee === "SAME_TRANSACTION" || ctx.guarantee === "CONDITIONAL_EXTERNAL" || ctx.guarantee === "NON_ATOMIC") {
|
|
67193
|
+
basis.guarantee = ctx.guarantee;
|
|
67194
|
+
}
|
|
67192
67195
|
if (conditional_write === true) {
|
|
67193
67196
|
if (typeof ctx.conditioned_on_token === "string") {
|
|
67194
67197
|
basis.conditioned_on_token = ctx.conditioned_on_token;
|
|
@@ -67324,8 +67327,11 @@ var require_fs = __commonJS({
|
|
|
67324
67327
|
};
|
|
67325
67328
|
})();
|
|
67326
67329
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
67327
|
-
exports2.tokensEqual = exports2.FS_ABSENT_TOKEN = exports2.FS_VERSION_TOKEN_PREFIX = void 0;
|
|
67330
|
+
exports2.tokensEqual = exports2.UnsafeCasPathError = exports2.FS_ABSENT_TOKEN = exports2.FS_VERSION_TOKEN_PREFIX = void 0;
|
|
67328
67331
|
exports2.fsTokenContentHash = fsTokenContentHash;
|
|
67332
|
+
exports2.assertSafeCasPath = assertSafeCasPath;
|
|
67333
|
+
exports2.fsObjectIdentity = fsObjectIdentity;
|
|
67334
|
+
exports2.identitiesEqual = identitiesEqual;
|
|
67329
67335
|
exports2.createFsVersionToken = createFsVersionToken;
|
|
67330
67336
|
exports2.readVersionedFile = readVersionedFile;
|
|
67331
67337
|
exports2.writeFileIfUnchanged = writeFileIfUnchanged;
|
|
@@ -67354,23 +67360,90 @@ var require_fs = __commonJS({
|
|
|
67354
67360
|
const hash = rest.slice(colon + 1);
|
|
67355
67361
|
return /^[a-f0-9]{64}$/.test(hash) ? hash : null;
|
|
67356
67362
|
}
|
|
67363
|
+
var UnsafeCasPathError = class extends Error {
|
|
67364
|
+
reason;
|
|
67365
|
+
casPath;
|
|
67366
|
+
constructor(reason, casPath) {
|
|
67367
|
+
super(`unsafe CAS path (${reason}): ${casPath}`);
|
|
67368
|
+
this.name = "UnsafeCasPathError";
|
|
67369
|
+
this.reason = reason;
|
|
67370
|
+
this.casPath = casPath;
|
|
67371
|
+
}
|
|
67372
|
+
};
|
|
67373
|
+
exports2.UnsafeCasPathError = UnsafeCasPathError;
|
|
67374
|
+
async function assertSafeCasPath(filePath) {
|
|
67375
|
+
const segments = filePath.split(/[\\/]+/);
|
|
67376
|
+
if (segments.includes(".."))
|
|
67377
|
+
throw new UnsafeCasPathError("path_traversal", filePath);
|
|
67378
|
+
const resolved = path.resolve(filePath);
|
|
67379
|
+
const dir = path.dirname(resolved);
|
|
67380
|
+
let canonicalDir = dir;
|
|
67381
|
+
try {
|
|
67382
|
+
canonicalDir = await node_fs_1.promises.realpath(dir);
|
|
67383
|
+
} catch (err) {
|
|
67384
|
+
const code = err && typeof err === "object" && "code" in err ? String(err.code) : "";
|
|
67385
|
+
if (code !== "ENOENT")
|
|
67386
|
+
throw err;
|
|
67387
|
+
}
|
|
67388
|
+
const target = path.join(canonicalDir, path.basename(resolved));
|
|
67389
|
+
try {
|
|
67390
|
+
const lst = await node_fs_1.promises.lstat(target);
|
|
67391
|
+
if (lst.isSymbolicLink())
|
|
67392
|
+
throw new UnsafeCasPathError("symlink_target", filePath);
|
|
67393
|
+
} catch (err) {
|
|
67394
|
+
if (err instanceof UnsafeCasPathError)
|
|
67395
|
+
throw err;
|
|
67396
|
+
const code = err && typeof err === "object" && "code" in err ? String(err.code) : "";
|
|
67397
|
+
if (code !== "ENOENT")
|
|
67398
|
+
throw err;
|
|
67399
|
+
}
|
|
67400
|
+
return target;
|
|
67401
|
+
}
|
|
67402
|
+
async function fsObjectIdentity(filePath) {
|
|
67403
|
+
let fh;
|
|
67404
|
+
try {
|
|
67405
|
+
fh = await node_fs_1.promises.open(filePath, "r");
|
|
67406
|
+
const st = await fh.stat();
|
|
67407
|
+
return { dev: st.dev, ino: st.ino };
|
|
67408
|
+
} catch (err) {
|
|
67409
|
+
const code = err && typeof err === "object" && "code" in err ? String(err.code) : "";
|
|
67410
|
+
if (code === "ENOENT")
|
|
67411
|
+
return null;
|
|
67412
|
+
throw err;
|
|
67413
|
+
} finally {
|
|
67414
|
+
if (fh)
|
|
67415
|
+
await fh.close().catch(() => {
|
|
67416
|
+
});
|
|
67417
|
+
}
|
|
67418
|
+
}
|
|
67419
|
+
function identitiesEqual(a, b) {
|
|
67420
|
+
if (!a || !b)
|
|
67421
|
+
return false;
|
|
67422
|
+
return a.dev === b.dev && a.ino === b.ino;
|
|
67423
|
+
}
|
|
67357
67424
|
async function createFsVersionToken(filePath) {
|
|
67358
|
-
let
|
|
67425
|
+
let fh;
|
|
67359
67426
|
try {
|
|
67360
|
-
|
|
67427
|
+
fh = await node_fs_1.promises.open(filePath, "r");
|
|
67361
67428
|
} catch (err) {
|
|
67362
67429
|
const code = err && typeof err === "object" && "code" in err ? String(err.code) : "";
|
|
67363
67430
|
if (code === "ENOENT")
|
|
67364
67431
|
return exports2.FS_ABSENT_TOKEN;
|
|
67365
67432
|
throw err;
|
|
67366
67433
|
}
|
|
67367
|
-
|
|
67368
|
-
|
|
67434
|
+
try {
|
|
67435
|
+
const st = await fh.stat();
|
|
67436
|
+
if (!st.isFile()) {
|
|
67437
|
+
throw new Error(`createFsVersionToken: not a regular file: ${filePath}`);
|
|
67438
|
+
}
|
|
67439
|
+
const buf = await fh.readFile();
|
|
67440
|
+
const hash = sha256hex(buf);
|
|
67441
|
+
const mtimeMs = Math.trunc(st.mtimeMs);
|
|
67442
|
+
return `${exports2.FS_VERSION_TOKEN_PREFIX}${mtimeMs}:${hash}`;
|
|
67443
|
+
} finally {
|
|
67444
|
+
await fh.close().catch(() => {
|
|
67445
|
+
});
|
|
67369
67446
|
}
|
|
67370
|
-
const buf = await node_fs_1.promises.readFile(filePath);
|
|
67371
|
-
const hash = sha256hex(buf);
|
|
67372
|
-
const mtimeMs = Math.trunc(st.mtimeMs);
|
|
67373
|
-
return `${exports2.FS_VERSION_TOKEN_PREFIX}${mtimeMs}:${hash}`;
|
|
67374
67447
|
}
|
|
67375
67448
|
async function readVersionedFile(filePath) {
|
|
67376
67449
|
const version_token = await createFsVersionToken(filePath);
|
|
@@ -67381,9 +67454,23 @@ var require_fs = __commonJS({
|
|
|
67381
67454
|
return { content, version_token };
|
|
67382
67455
|
}
|
|
67383
67456
|
async function writeFileIfUnchanged(args) {
|
|
67384
|
-
const target =
|
|
67457
|
+
const target = await assertSafeCasPath(args.path);
|
|
67385
67458
|
const body = typeof args.content === "string" ? Buffer.from(args.content, "utf8") : args.content;
|
|
67386
67459
|
const writtenHash = sha256hex(body);
|
|
67460
|
+
const checkedIdentity = await fsObjectIdentity(target);
|
|
67461
|
+
const hasT1Identity = Object.prototype.hasOwnProperty.call(args, "expected_identity");
|
|
67462
|
+
if (hasT1Identity) {
|
|
67463
|
+
const t1 = args.expected_identity ?? null;
|
|
67464
|
+
const held = t1 === null ? checkedIdentity === null : identitiesEqual(t1, checkedIdentity);
|
|
67465
|
+
if (!held) {
|
|
67466
|
+
return {
|
|
67467
|
+
status: "refused",
|
|
67468
|
+
reason: "stale_version_token",
|
|
67469
|
+
expected_token: args.expected_token,
|
|
67470
|
+
current_token: await createFsVersionToken(target).catch(() => null)
|
|
67471
|
+
};
|
|
67472
|
+
}
|
|
67473
|
+
}
|
|
67387
67474
|
return (0, conditional_write_js_1.executeIfUnchanged)({
|
|
67388
67475
|
expected_token: args.expected_token,
|
|
67389
67476
|
current_token: () => createFsVersionToken(target),
|
|
@@ -67402,6 +67489,15 @@ var require_fs = __commonJS({
|
|
|
67402
67489
|
const tmp = path.join(dir, `.coderifts-cas-${path.basename(target)}-${process.pid}-${(0, node_crypto_1.randomBytes)(6).toString("hex")}.tmp`);
|
|
67403
67490
|
try {
|
|
67404
67491
|
await node_fs_1.promises.writeFile(tmp, body);
|
|
67492
|
+
const stillIdentity = await fsObjectIdentity(target);
|
|
67493
|
+
const identityHeld = checkedIdentity === null ? stillIdentity === null : identitiesEqual(checkedIdentity, stillIdentity);
|
|
67494
|
+
if (!identityHeld) {
|
|
67495
|
+
try {
|
|
67496
|
+
await node_fs_1.promises.unlink(tmp);
|
|
67497
|
+
} catch {
|
|
67498
|
+
}
|
|
67499
|
+
throw new conditional_write_js_1.StaleVersionTokenAbort(await createFsVersionToken(target).catch(() => null));
|
|
67500
|
+
}
|
|
67405
67501
|
const still = await createFsVersionToken(target);
|
|
67406
67502
|
if (!(0, conditional_write_js_1.tokensEqual)(args.expected_token, still)) {
|
|
67407
67503
|
try {
|
|
@@ -67420,7 +67516,13 @@ var require_fs = __commonJS({
|
|
|
67420
67516
|
}
|
|
67421
67517
|
throw err;
|
|
67422
67518
|
}
|
|
67423
|
-
return {
|
|
67519
|
+
return {
|
|
67520
|
+
path: target,
|
|
67521
|
+
bytes: body.length,
|
|
67522
|
+
written_content_hash: writtenHash,
|
|
67523
|
+
checked_identity: checkedIdentity,
|
|
67524
|
+
committed_identity: await fsObjectIdentity(target)
|
|
67525
|
+
};
|
|
67424
67526
|
}
|
|
67425
67527
|
});
|
|
67426
67528
|
}
|
|
@@ -69409,6 +69511,10 @@ var require_cas_attestation = __commonJS({
|
|
|
69409
69511
|
const s = x;
|
|
69410
69512
|
return s.reason === "stale_during_commit" && typeof s.expected_token === "string";
|
|
69411
69513
|
}
|
|
69514
|
+
if (o.status === "indeterminate") {
|
|
69515
|
+
const i = x;
|
|
69516
|
+
return (i.reason === "response_lost" || i.reason === "ambiguous_provider_reply" || i.reason === "observation_failed") && typeof i.expected_token === "string";
|
|
69517
|
+
}
|
|
69412
69518
|
return false;
|
|
69413
69519
|
}
|
|
69414
69520
|
function freezeExecutionResultHash(h) {
|
|
@@ -69431,6 +69537,15 @@ var require_cas_attestation = __commonJS({
|
|
|
69431
69537
|
current_token: outcome.current_token == null ? null : outcome.current_token
|
|
69432
69538
|
});
|
|
69433
69539
|
}
|
|
69540
|
+
if (outcome.status === "indeterminate") {
|
|
69541
|
+
return Object.freeze({
|
|
69542
|
+
status: "indeterminate",
|
|
69543
|
+
write_ran: "unknown",
|
|
69544
|
+
reason: outcome.reason,
|
|
69545
|
+
expected_token: outcome.expected_token,
|
|
69546
|
+
observed_token: outcome.observed_token == null ? null : outcome.observed_token
|
|
69547
|
+
});
|
|
69548
|
+
}
|
|
69434
69549
|
return Object.freeze({
|
|
69435
69550
|
status: "committed_stale_detected",
|
|
69436
69551
|
write_ran: true,
|
|
@@ -69451,6 +69566,7 @@ var require_cas_attestation = __commonJS({
|
|
|
69451
69566
|
const write_ran = cas.write_ran === true;
|
|
69452
69567
|
const stale_during_commit = cas.status === "committed_stale_detected";
|
|
69453
69568
|
const refused = cas.status === "refused";
|
|
69569
|
+
const indeterminate = cas.status === "indeterminate";
|
|
69454
69570
|
const cas_evidence = evaluateCasEvidence(outcome, opts);
|
|
69455
69571
|
let authorized_and_committed = receipt_verified && cas.status === "committed";
|
|
69456
69572
|
if (opts.profile === "ENFORCING_STRICT") {
|
|
@@ -69471,7 +69587,8 @@ var require_cas_attestation = __commonJS({
|
|
|
69471
69587
|
authorized_and_committed,
|
|
69472
69588
|
write_ran,
|
|
69473
69589
|
stale_during_commit,
|
|
69474
|
-
refused
|
|
69590
|
+
refused,
|
|
69591
|
+
indeterminate
|
|
69475
69592
|
}),
|
|
69476
69593
|
cas_evidence,
|
|
69477
69594
|
limits: LIMITS
|
|
@@ -72729,6 +72846,8 @@ var require_fs_default_wire = __commonJS({
|
|
|
72729
72846
|
exports2.inferFsPathFromArgs = inferFsPathFromArgs;
|
|
72730
72847
|
exports2.inferFullFileWriteContent = inferFullFileWriteContent;
|
|
72731
72848
|
exports2.wrapWriteWithFsCas = wrapWriteWithFsCas;
|
|
72849
|
+
exports2.measureFsAuthorization = measureFsAuthorization;
|
|
72850
|
+
exports2.measureFsAuthorizationToken = measureFsAuthorizationToken;
|
|
72732
72851
|
var cas_attestation_js_1 = require_cas_attestation();
|
|
72733
72852
|
var fs_js_1 = require_fs();
|
|
72734
72853
|
function inferFsPathFromArgs(args) {
|
|
@@ -72755,20 +72874,16 @@ var require_fs_default_wire = __commonJS({
|
|
|
72755
72874
|
}
|
|
72756
72875
|
return null;
|
|
72757
72876
|
}
|
|
72758
|
-
async function wrapWriteWithFsCas(args, write) {
|
|
72877
|
+
async function wrapWriteWithFsCas(args, write, opts) {
|
|
72759
72878
|
const filePath = inferFsPathFromArgs(args);
|
|
72760
72879
|
const content = inferFullFileWriteContent(args);
|
|
72761
|
-
|
|
72762
|
-
|
|
72763
|
-
try {
|
|
72764
|
-
expected = await (0, fs_js_1.createFsVersionToken)(filePath);
|
|
72765
|
-
} catch {
|
|
72766
|
-
return write();
|
|
72767
|
-
}
|
|
72880
|
+
const expected = opts && typeof opts.expected_token === "string" ? opts.expected_token : null;
|
|
72881
|
+
if (filePath && content != null && expected !== null) {
|
|
72768
72882
|
return (0, fs_js_1.writeFileIfUnchanged)({
|
|
72769
72883
|
path: filePath,
|
|
72770
72884
|
expected_token: expected,
|
|
72771
|
-
content
|
|
72885
|
+
content,
|
|
72886
|
+
...opts && "expected_identity" in opts ? { expected_identity: opts.expected_identity ?? null } : {}
|
|
72772
72887
|
});
|
|
72773
72888
|
}
|
|
72774
72889
|
const raw = await write();
|
|
@@ -72776,6 +72891,24 @@ var require_fs_default_wire = __commonJS({
|
|
|
72776
72891
|
return raw;
|
|
72777
72892
|
return raw;
|
|
72778
72893
|
}
|
|
72894
|
+
async function measureFsAuthorization(args) {
|
|
72895
|
+
const filePath = inferFsPathFromArgs(args);
|
|
72896
|
+
const content = inferFullFileWriteContent(args);
|
|
72897
|
+
if (!filePath || content == null)
|
|
72898
|
+
return null;
|
|
72899
|
+
try {
|
|
72900
|
+
const target = await (0, fs_js_1.assertSafeCasPath)(filePath);
|
|
72901
|
+
const expected_identity = await (0, fs_js_1.fsObjectIdentity)(target);
|
|
72902
|
+
const expected_token = await (0, fs_js_1.createFsVersionToken)(target);
|
|
72903
|
+
return { expected_token, expected_identity };
|
|
72904
|
+
} catch {
|
|
72905
|
+
return null;
|
|
72906
|
+
}
|
|
72907
|
+
}
|
|
72908
|
+
async function measureFsAuthorizationToken(args) {
|
|
72909
|
+
const m = await measureFsAuthorization(args);
|
|
72910
|
+
return m ? m.expected_token : null;
|
|
72911
|
+
}
|
|
72779
72912
|
}
|
|
72780
72913
|
});
|
|
72781
72914
|
|
|
@@ -72960,6 +73093,11 @@ var require_tool_registry = __commonJS({
|
|
|
72960
73093
|
lastDerivation = d.derivation;
|
|
72961
73094
|
return d.call;
|
|
72962
73095
|
};
|
|
73096
|
+
const rebindAndRemeasure = async () => {
|
|
73097
|
+
const c = await rebind();
|
|
73098
|
+
casAuth = await (0, fs_default_wire_js_1.measureFsAuthorization)(args);
|
|
73099
|
+
return c;
|
|
73100
|
+
};
|
|
72963
73101
|
const call = await rebind();
|
|
72964
73102
|
const refreshContext = async (c) => (0, freshness_js_1.collectFreshnessCallContext)({
|
|
72965
73103
|
call: {
|
|
@@ -72970,16 +73108,17 @@ var require_tool_registry = __commonJS({
|
|
|
72970
73108
|
resolvePriorContent: guardCfg.resolvePriorContent
|
|
72971
73109
|
});
|
|
72972
73110
|
const fctx = await refreshContext(call);
|
|
73111
|
+
let casAuth = await (0, fs_default_wire_js_1.measureFsAuthorization)(args);
|
|
72973
73112
|
const factory = async (_envelope, redacted, execution) => {
|
|
72974
73113
|
const rawArgs = redacted ? redacted.arguments : args;
|
|
72975
|
-
return (0, fs_default_wire_js_1.wrapWriteWithFsCas)(rawArgs, () => execution ? rawExecute(rawArgs, execution) : rawExecute(rawArgs));
|
|
73114
|
+
return (0, fs_default_wire_js_1.wrapWriteWithFsCas)(rawArgs, () => execution ? rawExecute(rawArgs, execution) : rawExecute(rawArgs), casAuth ? { expected_token: casAuth.expected_token, expected_identity: casAuth.expected_identity } : {});
|
|
72976
73115
|
};
|
|
72977
73116
|
const outcome = (0, auto_recheck_js_1.normalizeAutoRecheck)(guardCfg.autoRecheck) ? await (0, auto_recheck_js_1.runAutoRecheckLoop)({
|
|
72978
73117
|
call,
|
|
72979
73118
|
factory,
|
|
72980
73119
|
config: guardCfg,
|
|
72981
73120
|
callContext: fctx,
|
|
72982
|
-
rebind,
|
|
73121
|
+
rebind: rebindAndRemeasure,
|
|
72983
73122
|
refreshContext
|
|
72984
73123
|
}) : await (0, guard_js_1.guardToolCall)(call, factory, guardCfg, fctx);
|
|
72985
73124
|
return (0, auto_derive_js_1.attachDerivation)(outcome, lastDerivation);
|
|
@@ -75298,9 +75437,10 @@ var require_cjs4 = __commonJS({
|
|
|
75298
75437
|
"use strict";
|
|
75299
75438
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
75300
75439
|
exports2.monitorAttestSigningInput = exports2.kidFromMonitoringAttestation = exports2.tryIssueMonitoringAttestation = exports2.DEFAULT_MONITORING_SINK_TIMEOUT_MS = exports2.ackBytes = exports2.verifyAckHmac = exports2.monitoringDeliveryFailClosed = exports2.formatMonitoringDeliveryLine = exports2.deliverMonitoring = exports2.hashObservedContent = exports2.observeCommit = exports2.deriveKeySignal = exports2.pathClass = exports2.classifyCommand = exports2.projectState = exports2.emptySessionState = exports2.computeTainted = exports2.evaluate = exports2.updateSession = exports2.SESSION_TAINT_VERSION = exports2.SessionTaintTracker = exports2.readDecision = exports2.EXECUTION_TIME_FP_REASONS = exports2.EXECUTION_STATE_UNMEASURABLE_NOTE = exports2.isUnmeasurableExecutionStateReason = exports2.computeCanonicalBundleFingerprint = exports2.authorizedFingerprintFromEnvelope = exports2.checkExecutionTimeFingerprint = exports2.computeBundleFingerprint = exports2.computeArtifactDigest = exports2.evaluateEnvelope = exports2.RECEIPT_PREV_NULL = exports2.decodeReceiptBodyPrev = exports2.previousReceiptCommitment = exports2.verifyReceiptChainLinkage = exports2.canonicalJson = exports2.computeBodyHash = exports2.bindReceiptToEnvelope = exports2.DETECTOR_VERSION = exports2.builtinDetector = exports2.resetPolicyWarnForTests = exports2.warnPolicyAbsentOnce = exports2.observePolicyPresence = exports2.detectPolicyPresence = exports2.policyPresenceOf = exports2.withPolicy = exports2.POLICY_ABSENT_WARN = exports2.POLICY_MARKER = exports2.CODERIFTS_POLICY = exports2.guardToolCall = void 0;
|
|
75301
|
-
exports2.
|
|
75302
|
-
exports2.
|
|
75303
|
-
exports2.
|
|
75440
|
+
exports2.createDbVersionToken = exports2.API_ABSENT_TOKEN = exports2.API_VERSION_TOKEN_PREFIX = exports2.apiTokenRaw = exports2.writeApiIfUnchanged = exports2.createApiVersionToken = exports2.identitiesEqual = exports2.fsObjectIdentity = exports2.UnsafeCasPathError = exports2.assertSafeCasPath = exports2.FS_ABSENT_TOKEN = exports2.FS_VERSION_TOKEN_PREFIX = exports2.fsTokenContentHash = exports2.createFsPriorContentResolver = exports2.writeFileIfUnchanged = exports2.readVersionedFile = exports2.createFsVersionToken = exports2.StaleVersionTokenAbort = exports2.executeIfUnchanged = exports2.RESIDUAL_UNCONDITIONAL_WRITE = exports2.conditionalWriteResidual = exports2.tokensEqual = exports2.buildConditionalWriteBasis = exports2.buildFreshnessBasis = exports2.collectFreshnessCallContext = exports2.artifactIdsForResolve = exports2.isMutatingCall = exports2.isWriteStyleCall = exports2.freshnessAllowsEnforce = exports2.computePathSetTreeHash = exports2.contentByteIdentical = exports2.assessWriteStylePrior = exports2.assessFreshness = exports2.deriveProofBanner = exports2.attachProofToAgentResponse = exports2.renderFinalAnswerProof = exports2.EXECUTION_PROOF_SPEC = exports2.assertEnforcedReceiptInvariant = exports2.hashExecutionResult = exports2.buildExecutionProof = exports2.COVERAGE_ATTEST_ENVELOPE_TAG = exports2.COVERAGE_ATTEST_SIGNING_PREFIX = exports2.COVERAGE_ATTEST_VERSION = exports2.coverageAttestSigningInput = exports2.kidFromCoverageAttestation = exports2.tryIssueCoverageAttestation = exports2.MONITOR_ATTEST_ENVELOPE_TAG = exports2.MONITOR_ATTEST_SIGNING_PREFIX = exports2.MONITOR_ATTEST_VERSION = exports2.receiptDigestOfToken = void 0;
|
|
75441
|
+
exports2.guardedFractionAmongRoutes = exports2.foldTableSettledCalls = exports2.withCodeRifts = exports2.AUTO_DERIVE_READ_TIMEOUT_MS = exports2.AUTO_DERIVE_SOURCE = exports2.defaultFsReader = exports2.normalizeAutoDerive = exports2.runAutoDerive = exports2.AUTO_RECHECK_MAX_CAP = exports2.clampMaxAttempts = exports2.normalizeAutoRecheck = exports2.runAutoRecheckLoop = exports2.coverageReport = exports2.DEPLOY_REPAIRABLE_REASONS = exports2.bindDeploy = exports2.verifyDeployReceiptToken = exports2.DEPLOY_RECEIPT_VIEW_SPEC = exports2.isVerifiedDeployReceiptView = exports2.asVerifiedDeployReceiptView = exports2.deployGate = exports2.gateDecision = exports2.RegistryConstructionError = exports2.guardToolRegistry = exports2.globToRegExp = exports2.matchGlob = exports2.blobMapKey = exports2.classifyByName = exports2.resolveArtifacts = exports2.REMEDIATION_LOOP_ATTESTATION_SPEC = exports2.isCasAttestation = exports2.readPriorBlockRemediation = exports2.readRemediationTransaction = exports2.buildRemediationLoopAttestation = exports2.COMMIT_EVIDENCE_MISSING = exports2.CAS_ATTESTATION_SPEC = exports2.strictCommitObservation = exports2.extractExecutorAttestationToken = exports2.evaluateCasEvidence = exports2.isExecuteIfUnchangedOutcome = exports2.isGuardExecutionProof = exports2.buildCasAttestation = exports2.REGISTRY_ABSENT_TOKEN = exports2.REGISTRY_VERSION_TOKEN_PREFIX = exports2.registryTokenRaw = exports2.writeRegistryIfUnchanged = exports2.createRegistryVersionToken = exports2.DB_ABSENT_TOKEN = exports2.DB_VERSION_TOKEN_PREFIX = exports2.dbTokenRaw = exports2.writeDbIfUnchanged = void 0;
|
|
75442
|
+
exports2.TOOLSET_ATTEST_ENVELOPE_TAG = exports2.TOOLSET_ATTEST_SIGNING_PREFIX = exports2.TOOLSET_ATTEST_VERSION = exports2.surfaceEnvelopeFields = exports2.isGuardOutcome = exports2.executeLangGraphToolCall = exports2.executeGeminiToolCall = exports2.executeAnthropicToolCall = exports2.executeOpenAIToolCall = exports2.executeProtectedTool = exports2.defaultSerializeGeminiToolResult = exports2.bindGeminiGuardOutcome = exports2.protectedToolToFunctionDeclaration = exports2.toGeminiTools = exports2.geminiToolAdapter = exports2.withCodeRiftsGemini = exports2.measureFsAuthorizationToken = exports2.measureFsAuthorization = exports2.wrapWriteWithFsCas = exports2.inferFullFileWriteContent = exports2.inferFsPathFromArgs = exports2.FRESHNESS_RESOLVER_FIX = exports2.freshnessRefusalTeaching = exports2.formatGateRefusalBody = exports2.defaultSerializeLangGraphToolResult = exports2.bindLangGraphGuardOutcome = exports2.LangGraphToolsNotStructuredError = exports2.isLangGraphReactAgentTool = exports2.bindLangGraphTools = exports2.protectedToolToLangGraph = exports2.toLangGraphTools = exports2.langGraphToolAdapter = exports2.withCodeRiftsLangGraph = exports2.defaultSerializeAnthropicToolResult = exports2.bindAnthropicGuardOutcome = exports2.protectedToolToAnthropic = exports2.toAnthropicTools = exports2.anthropicToolAdapter = exports2.withCodeRiftsAnthropic = exports2.defaultSerializeOpenAIToolResult = exports2.bindOpenAIGuardOutcome = exports2.protectedToolToOpenAI = exports2.toOpenAITools = exports2.openAIToolAdapter = exports2.withCodeRiftsOpenAI = exports2.formatCoverageObservedLine = exports2.freezeCoverageObserved = exports2.createCoverageObserver = exports2.readExecutionGrantToken = exports2.isExecutionGrantEnabled = void 0;
|
|
75443
|
+
exports2.kidFromToolsetAttestation = exports2.tryIssueToolsetAttestation = exports2.toolsetAttestSigningInput = exports2.declarationEntriesFromTools = exports2.computeToolsetDigest = exports2.TOOLSET_ATTEST_STATEMENT = void 0;
|
|
75304
75444
|
var guard_js_1 = require_guard();
|
|
75305
75445
|
Object.defineProperty(exports2, "guardToolCall", { enumerable: true, get: function() {
|
|
75306
75446
|
return guard_js_1.guardToolCall;
|
|
@@ -75589,6 +75729,18 @@ var require_cjs4 = __commonJS({
|
|
|
75589
75729
|
Object.defineProperty(exports2, "FS_ABSENT_TOKEN", { enumerable: true, get: function() {
|
|
75590
75730
|
return fs_js_1.FS_ABSENT_TOKEN;
|
|
75591
75731
|
} });
|
|
75732
|
+
Object.defineProperty(exports2, "assertSafeCasPath", { enumerable: true, get: function() {
|
|
75733
|
+
return fs_js_1.assertSafeCasPath;
|
|
75734
|
+
} });
|
|
75735
|
+
Object.defineProperty(exports2, "UnsafeCasPathError", { enumerable: true, get: function() {
|
|
75736
|
+
return fs_js_1.UnsafeCasPathError;
|
|
75737
|
+
} });
|
|
75738
|
+
Object.defineProperty(exports2, "fsObjectIdentity", { enumerable: true, get: function() {
|
|
75739
|
+
return fs_js_1.fsObjectIdentity;
|
|
75740
|
+
} });
|
|
75741
|
+
Object.defineProperty(exports2, "identitiesEqual", { enumerable: true, get: function() {
|
|
75742
|
+
return fs_js_1.identitiesEqual;
|
|
75743
|
+
} });
|
|
75592
75744
|
var api_js_1 = require_api3();
|
|
75593
75745
|
Object.defineProperty(exports2, "createApiVersionToken", { enumerable: true, get: function() {
|
|
75594
75746
|
return api_js_1.createApiVersionToken;
|
|
@@ -75876,6 +76028,12 @@ var require_cjs4 = __commonJS({
|
|
|
75876
76028
|
Object.defineProperty(exports2, "wrapWriteWithFsCas", { enumerable: true, get: function() {
|
|
75877
76029
|
return fs_default_wire_js_1.wrapWriteWithFsCas;
|
|
75878
76030
|
} });
|
|
76031
|
+
Object.defineProperty(exports2, "measureFsAuthorization", { enumerable: true, get: function() {
|
|
76032
|
+
return fs_default_wire_js_1.measureFsAuthorization;
|
|
76033
|
+
} });
|
|
76034
|
+
Object.defineProperty(exports2, "measureFsAuthorizationToken", { enumerable: true, get: function() {
|
|
76035
|
+
return fs_default_wire_js_1.measureFsAuthorizationToken;
|
|
76036
|
+
} });
|
|
75879
76037
|
var gemini_js_1 = require_gemini();
|
|
75880
76038
|
Object.defineProperty(exports2, "withCodeRiftsGemini", { enumerable: true, get: function() {
|
|
75881
76039
|
return gemini_js_1.withCodeRiftsGemini;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coderifts",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.1",
|
|
4
4
|
"description": "Detect breaking API changes from the command line. Works locally or with the CodeRifts cloud API.",
|
|
5
5
|
"author": "CodeRifts <hello@coderifts.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"test": "node --test test/*.test.js"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@coderifts/agent-guard": "^
|
|
48
|
+
"@coderifts/agent-guard": "^13.0.0",
|
|
49
49
|
"chalk": "^4.1.2",
|
|
50
50
|
"cli-table3": "^0.6.4",
|
|
51
51
|
"commander": "^12.0.0",
|
|
@@ -45,13 +45,33 @@
|
|
|
45
45
|
* raise, and no product code. The floor rises anyway, because a semantics floor is about
|
|
46
46
|
* what the CLI may RUN against: a guard that silently skips the atomicity demand on an ordinary
|
|
47
47
|
* edit is exactly the class of difference this gate exists to refuse.)
|
|
48
|
+
* 6.0.0: floor raised to 13 (the CAS now conditions on the AUTHORIZATION-TIME token. Through 12.0.0
|
|
49
|
+
* wrapWriteWithFsCas measured its expected token INSIDE executeFactory — after preflight and after
|
|
50
|
+
* the T2 recheck — and conditioned the write on that self-fetched value, which asks whether the
|
|
51
|
+
* state changed since a read a microsecond earlier. Measured on 12.0.0: a writer landing in that
|
|
52
|
+
* window had its state adopted as the legitimate starting point and the CAS still returned
|
|
53
|
+
* committed with enforced:true, clobbering it. 13.0.0 threads the T1 token, and adds three FS
|
|
54
|
+
* defences that were measured ABSENT rather than assumed: `..` refused before resolution, a
|
|
55
|
+
* symlinked final component refused (stat/readFile measured the TARGET while rename replaced the
|
|
56
|
+
* LINK — check and write named different objects), the token read through one file descriptor,
|
|
57
|
+
* and dev+ino recorded in the evidence. COST MEASURED AS ZERO, and measured more carefully than
|
|
58
|
+
* the last two raises: the CLI imports only deployGate, asVerifiedDeployReceiptView,
|
|
59
|
+
* DEPLOY_RECEIPT_VIEW_SPEC and matchGlob, whose implementing modules (deploy-gate.js,
|
|
60
|
+
* resolver-glob.js, deploy-receipt-token.js, merge-gate.js) are BYTE-IDENTICAL 12.0.0 -> 13.0.0.
|
|
61
|
+
* Note the honest qualifier the earlier raises did not state: requiring the barrel index.js LOADS
|
|
62
|
+
* every changed module, so the changed code is in the process — it is simply not on the code path
|
|
63
|
+
* of any symbol the CLI calls, and the four symbols return identical values under both versions.
|
|
64
|
+
* Suite staged against 13.0.0 returned an identical 539/518/21 with a byte-identical 28-item
|
|
65
|
+
* failure set. The floor rises anyway, because a semantics floor is about what the CLI may RUN
|
|
66
|
+
* against: a CAS that reports committed after adopting another writer's state is exactly the
|
|
67
|
+
* class this gate exists to refuse.)
|
|
48
68
|
*/
|
|
49
69
|
|
|
50
70
|
const fs = require('fs');
|
|
51
71
|
const path = require('path');
|
|
52
72
|
|
|
53
73
|
/** Minimum acceptable major for @coderifts/agent-guard in THIS package (the CLI). */
|
|
54
|
-
const MIN_GUARD_MAJOR =
|
|
74
|
+
const MIN_GUARD_MAJOR = 13;
|
|
55
75
|
const DEP = '@coderifts/agent-guard';
|
|
56
76
|
|
|
57
77
|
/**
|