kiokuko 1.0.12 → 1.0.13
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/assurance/snapshot.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/assurance/snapshot.ts"],"names":[],"mappings":"AAQA,yFAAyF;AACzF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1D"}
|
|
@@ -1,21 +1,36 @@
|
|
|
1
1
|
import { execFileSync } from 'node:child_process';
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
|
-
import { lstatSync, readFileSync, realpathSync, existsSync } from 'node:fs';
|
|
3
|
+
import { lstatSync, readFileSync, readlinkSync, realpathSync, existsSync } from 'node:fs';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { KiokukoError } from '../errors.js';
|
|
6
6
|
/** Hash the Git-visible source, tests and configuration; never persist file contents. */
|
|
7
7
|
export function repositoryStateDigest(root) {
|
|
8
|
+
return snapshotRepository(root, { files: 0, bytes: 0 }, 0);
|
|
9
|
+
}
|
|
10
|
+
function snapshotRepository(root, budget, depth) {
|
|
11
|
+
if (depth > 16)
|
|
12
|
+
throw new KiokukoError('VALIDATION_ERROR', 'Repository snapshot exceeds its submodule depth budget');
|
|
8
13
|
const canonical = realpathSync(root);
|
|
9
14
|
const gitRoot = execFileSync('git', ['-C', canonical, 'rev-parse', '--show-toplevel'], { encoding: 'utf8', timeout: 5000 }).trim();
|
|
10
15
|
if (realpathSync(gitRoot) !== canonical)
|
|
11
16
|
throw new KiokukoError('CONFLICT', 'Evidence requires the canonical repository root');
|
|
12
17
|
const names = execFileSync('git', ['-C', canonical, 'ls-files', '-z', '--cached', '--others', '--exclude-standard'], { encoding: 'utf8', timeout: 5000, maxBuffer: 4 * 1024 * 1024 });
|
|
18
|
+
const index = execFileSync('git', ['-C', canonical, 'ls-files', '--stage', '-z'], { encoding: 'utf8', timeout: 5000, maxBuffer: 4 * 1024 * 1024 });
|
|
19
|
+
const gitlinks = new Map();
|
|
20
|
+
for (const row of index.split('\0')) {
|
|
21
|
+
const separator = row.indexOf('\t');
|
|
22
|
+
if (separator < 0)
|
|
23
|
+
continue;
|
|
24
|
+
const match = /^160000 ([0-9a-f]{40,64}) 0$/u.exec(row.slice(0, separator));
|
|
25
|
+
if (match)
|
|
26
|
+
gitlinks.set(row.slice(separator + 1), match[1]);
|
|
27
|
+
}
|
|
13
28
|
const configuration = ['.env', '.env.local', '.codex/config.toml', '.codex/hooks.json', '.kiokuko.json'].filter(name => existsSync(path.join(canonical, name)));
|
|
14
29
|
const files = [...new Set([...names.split('\0').filter(Boolean), ...configuration])].sort();
|
|
15
|
-
|
|
30
|
+
budget.files += files.length;
|
|
31
|
+
if (budget.files > 20000)
|
|
16
32
|
throw new KiokukoError('VALIDATION_ERROR', 'Repository snapshot exceeds its file budget');
|
|
17
33
|
const hash = createHash('sha256').update('kiokuko-state-v1\0');
|
|
18
|
-
let bytes = 0;
|
|
19
34
|
for (const file of files) {
|
|
20
35
|
const full = path.resolve(canonical, file);
|
|
21
36
|
if (!full.startsWith(canonical + path.sep))
|
|
@@ -32,10 +47,30 @@ export function repositoryStateDigest(root) {
|
|
|
32
47
|
}
|
|
33
48
|
throw error;
|
|
34
49
|
}
|
|
50
|
+
if (stat.isSymbolicLink()) {
|
|
51
|
+
const target = readlinkSync(full);
|
|
52
|
+
const resolvedTarget = realpathSync(full);
|
|
53
|
+
if (!resolvedTarget.startsWith(canonical + path.sep))
|
|
54
|
+
throw new KiokukoError('VALIDATION_ERROR', 'Snapshot symlink escapes the repository');
|
|
55
|
+
const targetStat = lstatSync(resolvedTarget);
|
|
56
|
+
if (!targetStat.isFile())
|
|
57
|
+
throw new KiokukoError('VALIDATION_ERROR', 'Snapshot symlink target is not a regular file');
|
|
58
|
+
budget.bytes += Buffer.byteLength(target) + targetStat.size;
|
|
59
|
+
if (budget.bytes > 64 * 1024 * 1024)
|
|
60
|
+
throw new KiokukoError('VALIDATION_ERROR', 'Repository snapshot exceeds its byte budget');
|
|
61
|
+
hash.update(String(stat.mode)).update('\0').update(target).update('\0');
|
|
62
|
+
hash.update(String(targetStat.mode)).update('\0').update(readFileSync(resolvedTarget)).update('\0');
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (stat.isDirectory() && gitlinks.has(file) && realpathSync(full) === full) {
|
|
66
|
+
hash.update('gitlink\0').update(gitlinks.get(file)).update('\0');
|
|
67
|
+
hash.update(snapshotRepository(full, budget, depth + 1)).update('\0');
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
35
70
|
if (!stat.isFile() || realpathSync(full) !== full)
|
|
36
|
-
throw new KiokukoError('VALIDATION_ERROR', 'Snapshot cannot verify
|
|
37
|
-
bytes += stat.size;
|
|
38
|
-
if (bytes > 64 * 1024 * 1024)
|
|
71
|
+
throw new KiokukoError('VALIDATION_ERROR', 'Snapshot cannot verify non-regular files');
|
|
72
|
+
budget.bytes += stat.size;
|
|
73
|
+
if (budget.bytes > 64 * 1024 * 1024)
|
|
39
74
|
throw new KiokukoError('VALIDATION_ERROR', 'Repository snapshot exceeds its byte budget');
|
|
40
75
|
hash.update(String(stat.mode)).update('\0').update(readFileSync(full)).update('\0');
|
|
41
76
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/assurance/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/assurance/snapshot.ts"],"names":[],"mappings":"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"}
|