@dsh-enhanced/assistant-isolation 0.1.30

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.
Files changed (85) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +171 -0
  3. package/cordis.patch.yml +3 -0
  4. package/lib/audit-archive.d.ts +52 -0
  5. package/lib/audit-archive.d.ts.map +1 -0
  6. package/lib/audit-archive.js +775 -0
  7. package/lib/audit-archive.js.map +1 -0
  8. package/lib/cleanup-receipt.d.ts +26 -0
  9. package/lib/cleanup-receipt.d.ts.map +1 -0
  10. package/lib/cleanup-receipt.js +131 -0
  11. package/lib/cleanup-receipt.js.map +1 -0
  12. package/lib/cli.d.ts +16 -0
  13. package/lib/cli.d.ts.map +1 -0
  14. package/lib/cli.js +183 -0
  15. package/lib/cli.js.map +1 -0
  16. package/lib/config.d.ts +20 -0
  17. package/lib/config.d.ts.map +1 -0
  18. package/lib/config.js +61 -0
  19. package/lib/config.js.map +1 -0
  20. package/lib/daemon-binding.d.ts +13 -0
  21. package/lib/daemon-binding.d.ts.map +1 -0
  22. package/lib/daemon-binding.js +120 -0
  23. package/lib/daemon-binding.js.map +1 -0
  24. package/lib/diagnostics.d.ts +19 -0
  25. package/lib/diagnostics.d.ts.map +1 -0
  26. package/lib/diagnostics.js +122 -0
  27. package/lib/diagnostics.js.map +1 -0
  28. package/lib/index.d.ts +19 -0
  29. package/lib/index.d.ts.map +1 -0
  30. package/lib/index.js +13 -0
  31. package/lib/index.js.map +1 -0
  32. package/lib/ledger.d.ts +88 -0
  33. package/lib/ledger.d.ts.map +1 -0
  34. package/lib/ledger.js +623 -0
  35. package/lib/ledger.js.map +1 -0
  36. package/lib/probe.d.ts +5 -0
  37. package/lib/probe.d.ts.map +1 -0
  38. package/lib/probe.js +45 -0
  39. package/lib/probe.js.map +1 -0
  40. package/lib/reconcile.d.ts +5 -0
  41. package/lib/reconcile.d.ts.map +1 -0
  42. package/lib/reconcile.js +29 -0
  43. package/lib/reconcile.js.map +1 -0
  44. package/lib/runner.d.ts +12 -0
  45. package/lib/runner.d.ts.map +1 -0
  46. package/lib/runner.js +201 -0
  47. package/lib/runner.js.map +1 -0
  48. package/lib/runtime-witness.d.ts +32 -0
  49. package/lib/runtime-witness.d.ts.map +1 -0
  50. package/lib/runtime-witness.js +225 -0
  51. package/lib/runtime-witness.js.map +1 -0
  52. package/lib/service.d.ts +47 -0
  53. package/lib/service.d.ts.map +1 -0
  54. package/lib/service.js +361 -0
  55. package/lib/service.js.map +1 -0
  56. package/lib/storage-policy.d.ts +7 -0
  57. package/lib/storage-policy.d.ts.map +1 -0
  58. package/lib/storage-policy.js +82 -0
  59. package/lib/storage-policy.js.map +1 -0
  60. package/lib/storage.d.ts +18 -0
  61. package/lib/storage.d.ts.map +1 -0
  62. package/lib/storage.js +102 -0
  63. package/lib/storage.js.map +1 -0
  64. package/lib/tools.d.ts +4 -0
  65. package/lib/tools.d.ts.map +1 -0
  66. package/lib/tools.js +49 -0
  67. package/lib/tools.js.map +1 -0
  68. package/lib/types.d.ts +143 -0
  69. package/lib/types.d.ts.map +1 -0
  70. package/lib/types.js +2 -0
  71. package/lib/types.js.map +1 -0
  72. package/lib/verifier-runner.d.ts +21 -0
  73. package/lib/verifier-runner.d.ts.map +1 -0
  74. package/lib/verifier-runner.js +192 -0
  75. package/lib/verifier-runner.js.map +1 -0
  76. package/lib/version.d.ts +2 -0
  77. package/lib/version.d.ts.map +1 -0
  78. package/lib/version.js +2 -0
  79. package/lib/version.js.map +1 -0
  80. package/lib/workspace.d.ts +6 -0
  81. package/lib/workspace.d.ts.map +1 -0
  82. package/lib/workspace.js +140 -0
  83. package/lib/workspace.js.map +1 -0
  84. package/package.json +105 -0
  85. package/runtime/supervisor.mjs +290 -0
@@ -0,0 +1,120 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { readFile } from 'node:fs/promises';
3
+ import { basename } from 'node:path';
4
+ import { processWitness } from './runtime-witness.js';
5
+ const systemctl = '/usr/bin/systemctl';
6
+ const outputMaximum = 16_384;
7
+ const invocationId = /^[0-9a-f]{32}$/;
8
+ const pid = /^[1-9][0-9]*$/;
9
+ const properties = ['MainPID', 'InvocationID', 'ActiveState', 'SubState', 'TriggeredBy', 'Triggers', 'Listen', 'ExecStart'];
10
+ const required = {
11
+ 'docker.service': ['MainPID', 'InvocationID', 'ActiveState', 'SubState', 'TriggeredBy', 'ExecStart'],
12
+ 'docker.socket': ['InvocationID', 'ActiveState', 'SubState', 'Triggers', 'Listen'],
13
+ };
14
+ function equalUnit(left, right) { return properties.every(key => left[key] === right[key]); }
15
+ function includesUnit(value, unit) { return value.split(/\s+/).includes(unit); }
16
+ async function show(unit) {
17
+ return await new Promise(resolve => {
18
+ let stdout = Buffer.alloc(0);
19
+ let stderr = Buffer.alloc(0);
20
+ let complete = false;
21
+ let timeout;
22
+ const finish = (value) => { if (complete)
23
+ return; complete = true; if (timeout !== undefined)
24
+ clearTimeout(timeout); resolve(value); };
25
+ let child;
26
+ try {
27
+ child = spawn(systemctl, ['show', unit, ...properties.map(property => `--property=${property}`)], { shell: false, env: { LANG: 'C', LC_ALL: 'C' }, stdio: ['ignore', 'pipe', 'pipe'] });
28
+ }
29
+ catch {
30
+ finish(undefined);
31
+ return;
32
+ }
33
+ const collect = (target, chunk) => {
34
+ const bytes = stdout.length + stderr.length + chunk.length;
35
+ if (bytes > outputMaximum) {
36
+ child.kill('SIGKILL');
37
+ finish(undefined);
38
+ return;
39
+ }
40
+ if (target === 'stdout')
41
+ stdout = Buffer.concat([stdout, chunk]);
42
+ else
43
+ stderr = Buffer.concat([stderr, chunk]);
44
+ };
45
+ child.stdout?.on('data', chunk => collect('stdout', chunk));
46
+ child.stderr?.on('data', chunk => collect('stderr', chunk));
47
+ child.once('error', () => finish(undefined));
48
+ child.once('close', code => {
49
+ if (code !== 0 || stderr.length !== 0) {
50
+ finish(undefined);
51
+ return;
52
+ }
53
+ const values = new Map();
54
+ for (const line of stdout.toString('utf8').split('\n').filter(Boolean)) {
55
+ const separator = line.indexOf('=');
56
+ if (separator <= 0) {
57
+ finish(undefined);
58
+ return;
59
+ }
60
+ const key = line.slice(0, separator);
61
+ const value = line.slice(separator + 1);
62
+ if (!properties.includes(key) || values.has(key)) {
63
+ finish(undefined);
64
+ return;
65
+ }
66
+ values.set(key, value);
67
+ }
68
+ if (required[unit].some(property => !values.has(property))) {
69
+ finish(undefined);
70
+ return;
71
+ }
72
+ finish(Object.fromEntries(properties.map(property => [property, values.get(property) ?? ''])));
73
+ });
74
+ timeout = setTimeout(() => { child.kill('SIGKILL'); finish(undefined); }, 5_000);
75
+ timeout.unref();
76
+ });
77
+ }
78
+ function matches(daemon, service, socket) {
79
+ if (!pid.test(service.MainPID) || Number(service.MainPID) !== daemon.process.pid || !invocationId.test(service.InvocationID) || !invocationId.test(socket.InvocationID)
80
+ || service.ActiveState !== 'active' || service.SubState !== 'running' || socket.ActiveState !== 'active' || socket.SubState !== 'running'
81
+ || !includesUnit(service.TriggeredBy, 'docker.socket') || !includesUnit(socket.Triggers, 'docker.service') || socket.Listen !== `${daemon.socketPath} (Stream)`
82
+ || !/\bpath=\/usr\/bin\/dockerd\b/.test(service.ExecStart) || !/\bargv\[\]=.*\bdockerd -H fd:\/\//.test(service.ExecStart))
83
+ return undefined;
84
+ return { kind: 'systemd', serviceInvocationId: service.InvocationID, socketInvocationId: socket.InvocationID };
85
+ }
86
+ function sameProcess(left, daemon) {
87
+ return !!left && left.bootId === daemon.process.bootId && left.pid === daemon.process.pid && left.startTicks === daemon.process.startTicks;
88
+ }
89
+ async function dockerdFdCommand(pid) {
90
+ try {
91
+ const arguments_ = (await readFile(`/proc/${pid}/cmdline`)).toString('utf8').split('\0').filter(Boolean);
92
+ return basename(arguments_[0] ?? '') === 'dockerd' && arguments_.some((value, index) => value === '-H' && arguments_[index + 1] === 'fd://');
93
+ }
94
+ catch {
95
+ return false;
96
+ }
97
+ }
98
+ /**
99
+ * Attests the systemd configuration chain, not a kernel-level ownership proof
100
+ * for a particular inherited file descriptor. Every missing or changing datum
101
+ * is rejected so callers retain uncertainty rather than freeing work.
102
+ */
103
+ export async function captureSystemdBinding(daemon) {
104
+ if (!daemon || typeof daemon !== 'object' || daemon.socketPath !== '/run/docker.sock')
105
+ return undefined;
106
+ if (!sameProcess(await processWitness(daemon.process.pid), daemon))
107
+ return undefined;
108
+ const [firstService, firstSocket] = await Promise.all([show('docker.service'), show('docker.socket')]);
109
+ if (!firstService || !firstSocket || !matches(daemon, firstService, firstSocket) || !await dockerdFdCommand(daemon.process.pid))
110
+ return undefined;
111
+ if (!sameProcess(await processWitness(daemon.process.pid), daemon))
112
+ return undefined;
113
+ const [secondService, secondSocket] = await Promise.all([show('docker.service'), show('docker.socket')]);
114
+ if (!secondService || !secondSocket || !equalUnit(firstService, secondService) || !equalUnit(firstSocket, secondSocket))
115
+ return undefined;
116
+ if (!sameProcess(await processWitness(daemon.process.pid), daemon) || !await dockerdFdCommand(daemon.process.pid))
117
+ return undefined;
118
+ return matches(daemon, secondService, secondSocket);
119
+ }
120
+ //# sourceMappingURL=daemon-binding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-binding.js","sourceRoot":"","sources":["../src/daemon-binding.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { IsolationGrant } from './types.js';
2
+ export type IsolationGrantDiagnosticReason = 'database-missing' | 'database-unavailable' | 'database-corrupt' | 'schema-unsupported' | 'grant-missing' | 'grant-config-mismatch' | 'grant-revoked' | 'grant-expired' | 'max-runs-exhausted' | 'duration-budget-exhausted';
3
+ export interface IsolationGrantDiagnostic {
4
+ readonly status: 'available' | 'ineligible' | 'unavailable';
5
+ readonly reasons: readonly IsolationGrantDiagnosticReason[];
6
+ readonly runsUsed: number | null;
7
+ readonly durationReservedMs: number | null;
8
+ readonly remainingRuns: number | null;
9
+ readonly remainingDurationMs: number | null;
10
+ readonly activeJobs: number | null;
11
+ readonly unknownJobs: number | null;
12
+ }
13
+ /** Read-only ledger inspection for an operator doctor. It never creates, migrates, leases, or consumes grants. */
14
+ export declare function inspectIsolationGrant(input: {
15
+ stateRoot: string;
16
+ grant: IsolationGrant;
17
+ now?: number;
18
+ }): IsolationGrantDiagnostic;
19
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD,MAAM,MAAM,8BAA8B,GACtC,kBAAkB,GAAG,sBAAsB,GAAG,kBAAkB,GAAG,oBAAoB,GACvF,eAAe,GAAG,uBAAuB,GAAG,eAAe,GAAG,eAAe,GAC7E,oBAAoB,GAAG,2BAA2B,CAAA;AAEtD,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,YAAY,GAAG,aAAa,CAAA;IAC3D,QAAQ,CAAC,OAAO,EAAE,SAAS,8BAA8B,EAAE,CAAA;IAC3D,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1C,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IACrC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CACpC;AAiCD,kHAAkH;AAClH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,cAAc,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,wBAAwB,CAqDjI"}
@@ -0,0 +1,122 @@
1
+ import { existsSync, lstatSync, realpathSync } from 'node:fs';
2
+ import { isAbsolute, join, resolve } from 'node:path';
3
+ import { DatabaseSync } from 'node:sqlite';
4
+ const DIGEST = /^[a-f0-9]{64}$/u;
5
+ const TEXT = /^[^\p{Cc}]{1,4096}$/u;
6
+ const positive = (value) => Number.isSafeInteger(value) && value > 0;
7
+ const timestamp = (value) => Number.isSafeInteger(value) && value >= 0;
8
+ function freeze(value) {
9
+ if (value !== null && typeof value === 'object' && !Object.isFrozen(value)) {
10
+ for (const item of Object.values(value))
11
+ freeze(item);
12
+ Object.freeze(value);
13
+ }
14
+ return value;
15
+ }
16
+ function unavailable(reason) {
17
+ return freeze({ status: 'unavailable', reasons: freeze([reason]), runsUsed: null, durationReservedMs: null,
18
+ remainingRuns: null, remainingDurationMs: null, activeJobs: null, unknownJobs: null });
19
+ }
20
+ function validate(input) {
21
+ const grantKeys = ['id', 'revision', 'principalDigest', 'principalRecordId', 'principalVersion', 'workspace', 'agentPreset', 'expiresAt', 'maxRuns', 'maxTotalDurationMs'];
22
+ if (input === null || typeof input !== 'object' || Object.getPrototypeOf(input) !== Object.prototype || Object.keys(input).some(key => key !== 'stateRoot' && key !== 'grant' && key !== 'now')
23
+ || typeof input.stateRoot !== 'string' || !isAbsolute(input.stateRoot) || resolve(input.stateRoot) !== input.stateRoot || input.stateRoot === '/' || /[\p{Cc}]/u.test(input.stateRoot)
24
+ || !input.grant || typeof input.grant !== 'object' || Object.getPrototypeOf(input.grant) !== Object.prototype || Object.keys(input.grant).length !== grantKeys.length || grantKeys.some(key => !Object.hasOwn(input.grant, key)))
25
+ throw new Error('invalid isolation grant diagnostic input');
26
+ const grant = input.grant;
27
+ if (typeof grant.id !== 'string' || !TEXT.test(grant.id) || !positive(grant.revision) || typeof grant.principalDigest !== 'string' || !DIGEST.test(grant.principalDigest) || typeof grant.principalRecordId !== 'string' || !TEXT.test(grant.principalRecordId)
28
+ || !positive(grant.principalVersion) || typeof grant.workspace !== 'string' || !isAbsolute(grant.workspace) || resolve(grant.workspace) !== grant.workspace || /[\p{Cc}]/u.test(grant.workspace)
29
+ || typeof grant.agentPreset !== 'string' || !TEXT.test(grant.agentPreset) || !positive(grant.expiresAt) || !positive(grant.maxRuns) || !positive(grant.maxTotalDurationMs))
30
+ throw new Error('invalid isolation grant diagnostic input');
31
+ const now = input.now ?? Date.now();
32
+ if (!timestamp(now))
33
+ throw new Error('invalid isolation grant diagnostic clock');
34
+ return { stateRoot: input.stateRoot, grant: freeze({ ...grant }), now };
35
+ }
36
+ function safeCount(value) { return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0 ? value : undefined; }
37
+ /** Read-only ledger inspection for an operator doctor. It never creates, migrates, leases, or consumes grants. */
38
+ export function inspectIsolationGrant(input) {
39
+ const { stateRoot, grant, now } = validate(input);
40
+ const path = join(stateRoot, 'ledger.sqlite');
41
+ if (!existsSync(path) && !existsSync(stateRoot))
42
+ return unavailable('database-missing');
43
+ try {
44
+ const root = lstatSync(stateRoot);
45
+ if (!root.isDirectory() || root.isSymbolicLink() || realpathSync(stateRoot) !== stateRoot
46
+ || root.uid !== process.getuid?.() || (root.mode & 0o077) !== 0)
47
+ return unavailable('database-unavailable');
48
+ const file = lstatSync(path);
49
+ if (!file.isFile() || file.isSymbolicLink() || file.uid !== process.getuid?.())
50
+ return unavailable('database-unavailable');
51
+ }
52
+ catch {
53
+ return existsSync(stateRoot) ? unavailable('database-unavailable') : unavailable('database-missing');
54
+ }
55
+ let database;
56
+ let transaction = false;
57
+ try {
58
+ database = new DatabaseSync(path, { readOnly: true });
59
+ database.exec('PRAGMA query_only=ON; PRAGMA busy_timeout=250; BEGIN;');
60
+ transaction = true;
61
+ const version = database.prepare('PRAGMA user_version').get().user_version;
62
+ if (version !== 6)
63
+ return unavailable('schema-unsupported');
64
+ const schema = database.prepare("SELECT value FROM schema_meta WHERE key='schema-version'").get();
65
+ if (schema?.value !== '6')
66
+ return unavailable('schema-unsupported');
67
+ const row = database.prepare('SELECT revision, expires_at, max_runs, max_total_duration_ms, revoked, principal_digest, principal_record_id, principal_version, workspace, agent_preset FROM isolation_grants WHERE id=?').get(grant.id);
68
+ if (row !== undefined) {
69
+ const positiveFields = ['revision', 'expires_at', 'max_runs', 'max_total_duration_ms', 'principal_version'];
70
+ if (positiveFields.some(key => !positive(row[key])) || (row.revoked !== 0 && row.revoked !== 1) || typeof row.principal_digest !== 'string' || typeof row.principal_record_id !== 'string' || typeof row.workspace !== 'string' || typeof row.agent_preset !== 'string')
71
+ return unavailable('database-corrupt');
72
+ }
73
+ const usage = database.prepare('SELECT COUNT(*) AS runs, COALESCE(SUM(reserved_duration_ms), 0) AS duration FROM isolation_jobs WHERE grant_id=?').get(grant.id);
74
+ const active = database.prepare("SELECT COUNT(*) AS active FROM isolation_jobs WHERE grant_id=? AND (status IN ('prepared','running') OR (result_json IS NOT NULL AND json_extract(result_json, '$.quiescent')=0))").get(grant.id);
75
+ const unknown = database.prepare("SELECT COUNT(*) AS unknown_jobs FROM isolation_jobs WHERE grant_id=? AND (status='unknown' OR (result_json IS NOT NULL AND json_extract(result_json, '$.status')='unknown'))").get(grant.id);
76
+ const runsUsed = safeCount(usage.runs);
77
+ const durationReservedMs = safeCount(usage.duration);
78
+ const activeJobs = safeCount(active.active);
79
+ const unknownJobs = safeCount(unknown.unknown_jobs);
80
+ if (runsUsed === undefined || durationReservedMs === undefined || activeJobs === undefined || unknownJobs === undefined)
81
+ return unavailable('database-corrupt');
82
+ const remainingRuns = Math.max(0, grant.maxRuns - runsUsed);
83
+ const remainingDurationMs = Math.max(0, grant.maxTotalDurationMs - durationReservedMs);
84
+ const reasons = [];
85
+ if (row === undefined)
86
+ reasons.push('grant-missing');
87
+ else {
88
+ const mismatch = row.revision !== grant.revision || row.expires_at !== grant.expiresAt || row.max_runs !== grant.maxRuns || row.max_total_duration_ms !== grant.maxTotalDurationMs
89
+ || row.principal_digest !== grant.principalDigest || row.principal_record_id !== grant.principalRecordId || row.principal_version !== grant.principalVersion || row.workspace !== grant.workspace || row.agent_preset !== grant.agentPreset;
90
+ if (mismatch)
91
+ reasons.push('grant-config-mismatch');
92
+ if (row.revoked === 1)
93
+ reasons.push('grant-revoked');
94
+ }
95
+ if (grant.expiresAt <= now)
96
+ reasons.push('grant-expired');
97
+ if (runsUsed >= grant.maxRuns)
98
+ reasons.push('max-runs-exhausted');
99
+ if (durationReservedMs >= grant.maxTotalDurationMs)
100
+ reasons.push('duration-budget-exhausted');
101
+ return freeze({ status: reasons.length === 0 ? 'available' : 'ineligible', reasons: freeze(reasons), runsUsed, durationReservedMs,
102
+ remainingRuns, remainingDurationMs, activeJobs, unknownJobs });
103
+ }
104
+ catch (error) {
105
+ const message = error instanceof Error ? error.message.toLowerCase() : '';
106
+ return unavailable(message.includes('malformed') || message.includes('database disk image') || message.includes('not a database') ? 'database-corrupt' : 'database-unavailable');
107
+ }
108
+ finally {
109
+ if (transaction)
110
+ try {
111
+ database?.exec('COMMIT');
112
+ }
113
+ catch {
114
+ try {
115
+ database?.exec('ROLLBACK');
116
+ }
117
+ catch { }
118
+ }
119
+ database?.close();
120
+ }
121
+ }
122
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"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"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import { version } from './version.js';
3
+ import { AssistantIsolationService, Config } from './service.js';
4
+ export declare const name = "dsh-enhanced-assistant-isolation";
5
+ export { version, AssistantIsolationService, Config };
6
+ export { IsolatedVerifierRunner, type IsolatedVerifierRunnerConfig } from './verifier-runner.js';
7
+ export { inspectIsolationGrant, type IsolationGrantDiagnostic, type IsolationGrantDiagnosticReason } from './diagnostics.js';
8
+ export { probeIsolationRuntime } from './probe.js';
9
+ export * from './audit-archive.js';
10
+ export { isolationPrincipalDigest } from './service.js';
11
+ export type * from './types.js';
12
+ export declare function apply(ctx: Context, config?: Config): void;
13
+ declare const _default: {
14
+ name: string;
15
+ Config: import("@deepseek-ai/schemastery").default<Config>;
16
+ apply: typeof apply;
17
+ };
18
+ export default _default;
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,yBAAyB,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAEhE,eAAO,MAAM,IAAI,qCAAqC,CAAA;AACtD,OAAO,EAAE,OAAO,EAAE,yBAAyB,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,sBAAsB,EAAE,KAAK,4BAA4B,EAAE,MAAM,sBAAsB,CAAA;AAChG,OAAO,EAAE,qBAAqB,EAAE,KAAK,wBAAwB,EAAE,KAAK,8BAA8B,EAAE,MAAM,kBAAkB,CAAA;AAC5H,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAClD,cAAc,oBAAoB,CAAA;AAClC,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAA;AACvD,mBAAmB,YAAY,CAAA;AAE/B,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,GAAE,MAAW,GAAG,IAAI,CAA+C;;;;;;AAE7G,wBAAsC"}
package/lib/index.js ADDED
@@ -0,0 +1,13 @@
1
+ import { version } from './version.js';
2
+ import { AssistantIsolationService, Config } from './service.js';
3
+ export const name = 'dsh-enhanced-assistant-isolation';
4
+ export { version, AssistantIsolationService, Config };
5
+ export { IsolatedVerifierRunner } from './verifier-runner.js';
6
+ export { inspectIsolationGrant } from './diagnostics.js';
7
+ export { probeIsolationRuntime } from './probe.js';
8
+ export * from './audit-archive.js';
9
+ export { isolationPrincipalDigest } from './service.js';
10
+ export function apply(ctx, config = {}) { new AssistantIsolationService(ctx, config); }
11
+ // Loader unwraps the default export; preserve the trusted plugin identity there.
12
+ export default { name, Config, apply };
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,yBAAyB,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAEhE,MAAM,CAAC,MAAM,IAAI,GAAG,kCAAkC,CAAA;AACtD,OAAO,EAAE,OAAO,EAAE,yBAAyB,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,sBAAsB,EAAqC,MAAM,sBAAsB,CAAA;AAChG,OAAO,EAAE,qBAAqB,EAAsE,MAAM,kBAAkB,CAAA;AAC5H,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAClD,cAAc,oBAAoB,CAAA;AAClC,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAA;AAGvD,MAAM,UAAU,KAAK,CAAC,GAAY,EAAE,SAAiB,EAAE,IAAU,IAAI,yBAAyB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA,CAAC,CAAC;AAC7G,iFAAiF;AACjF,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA"}
@@ -0,0 +1,88 @@
1
+ import { type CreationWitness, type DaemonWitness } from './runtime-witness.js';
2
+ import type { SystemdBinding } from './daemon-binding.js';
3
+ import { type IsolationCleanupReceipt } from './cleanup-receipt.js';
4
+ import type { IsolationArtifactBinding, IsolationGrant, IsolationIdentity, IsolationJob, IsolationResult, IsolationStorageBudget } from './types.js';
5
+ export type IsolationLedgerErrorCode = 'conflict' | 'invalid-input' | 'invalid-path' | 'invalid-state' | 'not-found' | 'schema' | 'schema-too-new' | 'unauthorized';
6
+ export declare class IsolationLedgerError extends Error {
7
+ readonly code: IsolationLedgerErrorCode;
8
+ constructor(code: IsolationLedgerErrorCode, message?: string);
9
+ }
10
+ export interface IsolationControllerAuthority {
11
+ ownerId: string;
12
+ fence: number;
13
+ }
14
+ type ResourceReservation = {
15
+ memoryMiB: number;
16
+ workspaceInodes: number;
17
+ maxMemoryMiB: number;
18
+ maxWorkspaceInodes: number;
19
+ };
20
+ /** Durable Host-owned authorization and job state. This database is never mounted in workers. */
21
+ export declare class IsolationLedger {
22
+ #private;
23
+ constructor(path: string, { now }?: {
24
+ now?: () => number;
25
+ });
26
+ syncGrants(grants: IsolationGrant[], authority?: IsolationControllerAuthority): void;
27
+ prepare(input: {
28
+ identity: IsolationIdentity;
29
+ sessionId: string;
30
+ grantId: string;
31
+ idempotencyKey: string;
32
+ requestDigest: string;
33
+ durationMs: number;
34
+ maxActiveJobs?: number;
35
+ authority?: IsolationControllerAuthority;
36
+ resourceReservation?: ResourceReservation;
37
+ storageBudget?: IsolationStorageBudget;
38
+ artifactBinding?: IsolationArtifactBinding;
39
+ }): {
40
+ job: IsolationJob;
41
+ created: boolean;
42
+ };
43
+ /** Commit the crash boundary before a supervisor can receive create authority. */
44
+ markDispatched(jobId: string, expectedVersion: number, authority: IsolationControllerAuthority): IsolationJob;
45
+ start(jobId: string, expectedVersion: number, authority?: IsolationControllerAuthority): IsolationJob;
46
+ settle(jobId: string, expectedVersion: number, input: IsolationResult, authority?: IsolationControllerAuthority, creationWitness?: CreationWitness): IsolationJob;
47
+ /** Host-only release after exact cleanup; outcome and origin evidence remain immutable. */
48
+ settleReconciledUnknown(jobId: string, expectedVersion: number, proof: {
49
+ original: CreationWitness;
50
+ current: DaemonWitness;
51
+ currentBinding?: SystemdBinding;
52
+ checkedAt: number;
53
+ cleanup: IsolationCleanupReceipt;
54
+ }, authority: IsolationControllerAuthority): IsolationJob;
55
+ revoke(grantId: string, revision: number, reason: string): void;
56
+ claimController(ownerId: string, ttlMs: number): IsolationControllerAuthority;
57
+ renewController(authority: IsolationControllerAuthority, ttlMs: number): boolean;
58
+ releaseController(authority: IsolationControllerAuthority): void;
59
+ hasController(authority: IsolationControllerAuthority): boolean;
60
+ get(jobId: string): IsolationJob | undefined;
61
+ recoverable(afterId?: string): IsolationJob[];
62
+ retentionCandidates(cutoff: number, afterId?: string, limit?: number): Array<{
63
+ id: string;
64
+ version: number;
65
+ }>;
66
+ compactResult(id: string, expectedVersion: number, cutoff: number, authority: IsolationControllerAuthority): {
67
+ changed: boolean;
68
+ removedBytes: number;
69
+ };
70
+ storageStats(): {
71
+ jobRecords: number;
72
+ reusableBytes: number;
73
+ activeReservedBytes: number;
74
+ legacyActiveJobs: number;
75
+ };
76
+ maintainStorage(authority: IsolationControllerAuthority): {
77
+ checkpoint: 'complete' | 'busy';
78
+ reclaimMode: 'incremental' | 'page-reuse';
79
+ };
80
+ /** Newer declared output attempts mask older success, including failed/unknown attempts. */
81
+ acceptedArtifactJob(contractId: string, contractDigest: string, path: string): IsolationJob | undefined;
82
+ /** Read-only current grant check for the exact native tool preauthorization. */
83
+ permitsGrant(value: IsolationIdentity, grantId: string): boolean;
84
+ usable(jobId: string): boolean;
85
+ close(): void;
86
+ }
87
+ export {};
88
+ //# sourceMappingURL=ledger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"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"}