@skill-harness/adapters 0.17.0 → 0.19.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.
Files changed (121) hide show
  1. package/dist/index.d.ts +0 -30
  2. package/dist/index.js +0 -30
  3. package/dist/model-pricing.d.ts +3 -0
  4. package/dist/model-pricing.js +24 -0
  5. package/dist/pi.js +26 -135
  6. package/package.json +5 -4
  7. package/prices/model-prices.json +43 -0
  8. package/dist/archive-access.d.ts +0 -58
  9. package/dist/archive-access.js +0 -61
  10. package/dist/archive-checkpoint.d.ts +0 -47
  11. package/dist/archive-checkpoint.js +0 -116
  12. package/dist/archive-facts.d.ts +0 -19
  13. package/dist/archive-facts.js +0 -20
  14. package/dist/archive-observer.d.ts +0 -21
  15. package/dist/archive-observer.js +0 -79
  16. package/dist/archive-policy.d.ts +0 -107
  17. package/dist/archive-policy.js +0 -135
  18. package/dist/archive-read-capability.d.ts +0 -49
  19. package/dist/archive-read-capability.js +0 -45
  20. package/dist/archive-retention-policy.d.ts +0 -52
  21. package/dist/archive-retention-policy.js +0 -49
  22. package/dist/archived-work.d.ts +0 -45
  23. package/dist/archived-work.js +0 -78
  24. package/dist/blind-intervention.d.ts +0 -35
  25. package/dist/blind-intervention.js +0 -218
  26. package/dist/codex-diagnostic-model.d.ts +0 -14
  27. package/dist/codex-diagnostic-model.js +0 -39
  28. package/dist/codex-host-observer.d.ts +0 -111
  29. package/dist/codex-host-observer.js +0 -309
  30. package/dist/codex-https.d.ts +0 -7
  31. package/dist/codex-https.js +0 -221
  32. package/dist/codex-model-profile.d.ts +0 -38
  33. package/dist/codex-model-profile.js +0 -54
  34. package/dist/codex-producer-ipc.d.ts +0 -55
  35. package/dist/codex-producer-ipc.js +0 -67
  36. package/dist/codex-sdk-transport.d.ts +0 -50
  37. package/dist/codex-sdk-transport.js +0 -294
  38. package/dist/codex-subscription.d.ts +0 -114
  39. package/dist/codex-subscription.js +0 -268
  40. package/dist/evidence-archive.d.ts +0 -65
  41. package/dist/evidence-archive.js +0 -225
  42. package/dist/execution-projection-schema.d.ts +0 -10
  43. package/dist/execution-projection-schema.js +0 -30
  44. package/dist/execution-retention-archive.d.ts +0 -69
  45. package/dist/execution-retention-archive.js +0 -154
  46. package/dist/generated/retention-v2-contract.d.ts +0 -72
  47. package/dist/generated/retention-v2-contract.js +0 -105
  48. package/dist/generated/retention-v2-json.d.ts +0 -24
  49. package/dist/generated/retention-v2-json.js +0 -268
  50. package/dist/generated/retention-v2-native-json.d.ts +0 -2
  51. package/dist/generated/retention-v2-native-json.js +0 -33
  52. package/dist/generated/retention-v2-native.d.ts +0 -58
  53. package/dist/generated/retention-v2-native.js +0 -155
  54. package/dist/generated/retention-v2-pin.d.ts +0 -2
  55. package/dist/generated/retention-v2-pin.js +0 -4
  56. package/dist/generated/retention-v2-types.d.ts +0 -49
  57. package/dist/generated/retention-v2-types.js +0 -2
  58. package/dist/generated/retention-v2-work-types.d.ts +0 -260
  59. package/dist/generated/retention-v2-work-types.js +0 -13
  60. package/dist/generated/work-v4/execution-id.d.ts +0 -5
  61. package/dist/generated/work-v4/execution-id.js +0 -14
  62. package/dist/generated/work-v4/json.d.ts +0 -24
  63. package/dist/generated/work-v4/json.js +0 -268
  64. package/dist/generated/work-v4/occurrences.d.ts +0 -226
  65. package/dist/generated/work-v4/occurrences.js +0 -116
  66. package/dist/generated/work-v4/pin.d.ts +0 -1
  67. package/dist/generated/work-v4/pin.js +0 -3
  68. package/dist/generated/work-v4/projection.d.ts +0 -294
  69. package/dist/generated/work-v4/projection.js +0 -238
  70. package/dist/generated/work-v4/reader.d.ts +0 -24
  71. package/dist/generated/work-v4/reader.js +0 -109
  72. package/dist/generated/work-v4/snapshot.d.ts +0 -28
  73. package/dist/generated/work-v4/snapshot.js +0 -268
  74. package/dist/generated/work-v4/types.d.ts +0 -260
  75. package/dist/generated/work-v4/types.js +0 -13
  76. package/dist/generated/work-v4/validation.d.ts +0 -13
  77. package/dist/generated/work-v4/validation.js +0 -227
  78. package/dist/installed-review-session.d.ts +0 -28
  79. package/dist/installed-review-session.js +0 -166
  80. package/dist/intervention-run.d.ts +0 -403
  81. package/dist/intervention-run.js +0 -169
  82. package/dist/learning-case.d.ts +0 -12
  83. package/dist/learning-case.js +0 -15
  84. package/dist/learning-journal.d.ts +0 -18
  85. package/dist/learning-journal.js +0 -256
  86. package/dist/learning-lifecycle.d.ts +0 -28
  87. package/dist/learning-lifecycle.js +0 -66
  88. package/dist/learning-trust-setup.d.ts +0 -64
  89. package/dist/learning-trust-setup.js +0 -55
  90. package/dist/learning-workspace.d.ts +0 -1084
  91. package/dist/learning-workspace.js +0 -705
  92. package/dist/principal-payload-port.d.ts +0 -25
  93. package/dist/principal-payload-port.js +0 -40
  94. package/dist/producer-product.d.ts +0 -70
  95. package/dist/producer-product.js +0 -186
  96. package/dist/producer-review.d.ts +0 -53
  97. package/dist/producer-review.js +0 -207
  98. package/dist/prompt-capture-extension.d.ts +0 -10
  99. package/dist/prompt-capture-extension.js +0 -26
  100. package/dist/prompt-provenance.d.ts +0 -22
  101. package/dist/prompt-provenance.js +0 -146
  102. package/dist/reviewed-archive-export.d.ts +0 -42
  103. package/dist/reviewed-archive-export.js +0 -78
  104. package/dist/session-observation.d.ts +0 -50
  105. package/dist/session-observation.js +0 -186
  106. package/dist/session-retention.d.ts +0 -48
  107. package/dist/session-retention.js +0 -121
  108. package/dist/trust-lifecycle.d.ts +0 -152
  109. package/dist/trust-lifecycle.js +0 -209
  110. package/dist/weekly-investigation.d.ts +0 -237
  111. package/dist/weekly-investigation.js +0 -330
  112. package/dist/work-candidates.d.ts +0 -29
  113. package/dist/work-candidates.js +0 -78
  114. package/dist/work-case-archive.d.ts +0 -25
  115. package/dist/work-case-archive.js +0 -63
  116. package/dist/work-case-review.d.ts +0 -45
  117. package/dist/work-case-review.js +0 -220
  118. package/dist/work-signal-cases.d.ts +0 -15
  119. package/dist/work-signal-cases.js +0 -54
  120. package/dist/work-signal-observation.d.ts +0 -23
  121. package/dist/work-signal-observation.js +0 -89
@@ -1,116 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { parseArchivedJsonl, readArchiveSource, retainArchiveSource, } from "./evidence-archive.js";
3
- const hash = (value) => createHash("sha256").update(value).digest("hex");
4
- const SHA = /^[a-f0-9]{64}$/;
5
- const LIMIT = 8 * 1024 * 1024;
6
- const parserEqual = (a, b) => a.id === b.id && a.version === b.version;
7
- function reject() { throw new Error("invalid archive checkpoint"); }
8
- function parseCheckpoint(bytes) {
9
- const text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
10
- const v = JSON.parse(text);
11
- if (JSON.stringify(v) !== text)
12
- reject();
13
- const names = ["version", "sourceId", "sourceManifestId", "sourceSha256", "sourceBytes", "previousCheckpointId", "lineage", "declaredParser", "reader", "retention", "change", "syntax", "completeBytes", "pendingBytes", "invalidLines", "issues", "activeBranch", "acceptance"];
14
- if (!v || Object.keys(v).length !== names.length || Object.keys(v).some(k => !names.includes(k))
15
- || v.version !== "archive-checkpoint-v1" || v.reader !== "jsonl-syntax-v1"
16
- || typeof v.sourceId !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(v.sourceId)
17
- || ![v.sourceManifestId, v.sourceSha256, v.lineage].every(h => typeof h === "string" && SHA.test(h))
18
- || !(v.previousCheckpointId === null || (typeof v.previousCheckpointId === "string" && SHA.test(v.previousCheckpointId)))
19
- || ![v.sourceBytes, v.completeBytes, v.pendingBytes, v.invalidLines].every(n => Number.isSafeInteger(n) && n >= 0 && n <= LIMIT)
20
- || v.completeBytes + v.pendingBytes !== v.sourceBytes
21
- || !v.declaredParser || Object.keys(v.declaredParser).sort().join() !== "id,version"
22
- || ![v.declaredParser.id, v.declaredParser.version].every(s => typeof s === "string" && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(s))
23
- || !["exact", "redacted", "reference-only"].includes(v.retention)
24
- || !["initial", "append", "replaced", "unknown"].includes(v.change)
25
- || !["complete", "partial", "error", "unavailable"].includes(v.syntax)
26
- || (v.retention === "reference-only" && (v.syntax !== "unavailable" || v.completeBytes !== 0 || v.invalidLines !== 0))
27
- || !Array.isArray(v.issues) || v.issues.length > 16 || v.issues.some(i => typeof i !== "string" || i.length > 128)
28
- || v.activeBranch !== null || v.acceptance !== "not-assessed")
29
- reject();
30
- return v;
31
- }
32
- function records(checkpoint, source) {
33
- if (source.status !== "available")
34
- return [];
35
- const parsed = parseArchivedJsonl(source.bytes);
36
- return parsed.records.map(record => ({
37
- ...record, id: hash(JSON.stringify([checkpoint.sourceId, checkpoint.lineage, record.start, hash(source.bytes.subarray(record.start, record.end))])),
38
- }));
39
- }
40
- /** Restart from the immutable checkpoint ID. This never advances a worker or invokes a gate. */
41
- export function readArchiveCheckpoint(root, checkpointId) {
42
- const stored = readArchiveSource(root, checkpointId);
43
- if (stored.status !== "available" || stored.reference.retention !== "exact")
44
- reject();
45
- const checkpoint = parseCheckpoint(stored.bytes);
46
- const source = readArchiveSource(root, checkpoint.sourceManifestId);
47
- if (source.status === "available") {
48
- const ref = source.reference;
49
- if (ref.sourceId !== checkpoint.sourceId || ref.sha256 !== checkpoint.sourceSha256 || ref.bytes !== checkpoint.sourceBytes
50
- || ref.retention !== checkpoint.retention || !parserEqual(ref.parser, checkpoint.declaredParser))
51
- reject();
52
- const actual = parseArchivedJsonl(source.bytes);
53
- if (actual.status !== checkpoint.syntax || actual.completeBytes !== checkpoint.completeBytes
54
- || actual.pendingBytes !== checkpoint.pendingBytes || actual.errors.length !== checkpoint.invalidLines)
55
- reject();
56
- }
57
- return { checkpoint, source, records: records(checkpoint, source) };
58
- }
59
- /** Caller supplies an explicit snapshot, policy and prior receipt. No inferred active branch or acceptance. */
60
- export function ingestArchiveSnapshot(root, input) {
61
- // Inspect the prior bytes BEFORE storing this snapshot, so reacquisition cannot disguise a prior gap.
62
- const previous = input.previousCheckpointId ? readArchiveCheckpoint(root, input.previousCheckpointId) : undefined;
63
- if (previous && previous.checkpoint.sourceId !== input.sourceId)
64
- throw new Error("checkpoint source mismatch");
65
- const captured = retainArchiveSource(root, input);
66
- const source = readArchiveSource(root, captured.manifestId);
67
- const issues = [];
68
- let change = previous ? "unknown" : "initial";
69
- let lineage = captured.manifestId;
70
- if (previous) {
71
- if (!parserEqual(previous.checkpoint.declaredParser, captured.reference.parser) || previous.checkpoint.retention !== input.retention) {
72
- issues.push("parser-or-representation-changed");
73
- }
74
- else if (previous.source.status !== "available") {
75
- issues.push("previous-content-unavailable");
76
- }
77
- else if (input.retention !== "exact") {
78
- issues.push("non-exact-continuity-unknown");
79
- }
80
- else if (source.status === "available") {
81
- if (captured.manifestId === previous.checkpoint.sourceManifestId) {
82
- return { ...previous, checkpointId: input.previousCheckpointId, change: "repeat", newRecords: [] };
83
- }
84
- if (source.bytes.length >= previous.source.bytes.length && source.bytes.subarray(0, previous.source.bytes.length).equals(previous.source.bytes)) {
85
- change = "append";
86
- lineage = previous.checkpoint.lineage;
87
- }
88
- else {
89
- change = "replaced";
90
- issues.push("source-replaced");
91
- }
92
- }
93
- }
94
- if (input.retention === "redacted")
95
- issues.push("redacted-representation");
96
- if (source.status !== "available")
97
- issues.push("content-not-retained");
98
- const syntax = source.status === "available" ? parseArchivedJsonl(source.bytes) : undefined;
99
- const checkpoint = {
100
- version: "archive-checkpoint-v1", sourceId: input.sourceId,
101
- sourceManifestId: captured.manifestId, sourceSha256: captured.reference.sha256, sourceBytes: captured.reference.bytes,
102
- previousCheckpointId: input.previousCheckpointId ?? null, lineage,
103
- declaredParser: captured.reference.parser, reader: "jsonl-syntax-v1", retention: input.retention, change,
104
- syntax: syntax?.status ?? "unavailable", completeBytes: syntax?.completeBytes ?? 0,
105
- pendingBytes: syntax?.pendingBytes ?? captured.reference.bytes, invalidLines: syntax?.errors.length ?? 0,
106
- issues, activeBranch: null, acceptance: "not-assessed",
107
- };
108
- const result = retainArchiveSource(root, {
109
- sourceId: `checkpoint-${hash(input.sourceId)}`, parser: { id: "archive-checkpoint", version: "1" },
110
- retention: "exact", bytes: Buffer.from(JSON.stringify(checkpoint)),
111
- });
112
- const all = records(checkpoint, source);
113
- return { checkpointId: result.manifestId, checkpoint, source, records: all, change,
114
- newRecords: change === "append" ? all.filter(record => record.start >= previous.checkpoint.completeBytes) : all };
115
- }
116
- //# sourceMappingURL=archive-checkpoint.js.map
@@ -1,19 +0,0 @@
1
- import type { WorkSignalFacts } from '@skill-harness/core';
2
- import { type GovernedArchiveRoute } from './archive-access.js';
3
- /** Operational fixed-order fact adapter, not arbitrary model/host fact inference.
4
- * The caller supplies independent scope/source pins; all actual bytes use consent. */
5
- export declare function readFixedOrderFacts(root: string, manifestId: string, route: GovernedArchiveRoute, raw: {
6
- producerCommit: string;
7
- scopeDigest: string;
8
- population: string;
9
- obligations: string[];
10
- }, now?: number): {
11
- facts: WorkSignalFacts;
12
- source: {
13
- manifestId: string;
14
- sha256: string;
15
- producerCommit: string;
16
- };
17
- unknownNodes: any;
18
- acceptance: "not-assessed";
19
- };
@@ -1,20 +0,0 @@
1
- import { createHash } from 'node:crypto';
2
- import { readGovernedArchive } from './archive-access.js';
3
- import { learningCopy } from './learning-journal.js';
4
- /** Operational fixed-order fact adapter, not arbitrary model/host fact inference.
5
- * The caller supplies independent scope/source pins; all actual bytes use consent. */
6
- export function readFixedOrderFacts(root, manifestId, route, raw, now = Date.now()) {
7
- const expected = learningCopy(raw);
8
- if (!/^[a-f0-9]{40}$/.test(expected.producerCommit) || !/^[a-f0-9]{64}$/.test(expected.scopeDigest) || typeof expected.population !== 'string' || !expected.population.length || expected.population.length > 512 || /[\u0000-\u001f\u007f]/.test(expected.population) || !Array.isArray(expected.obligations) || expected.obligations.length > 128 || expected.obligations.some(h => !/^[a-f0-9]{64}$/.test(h)))
9
- throw Error('explicit fact source/scope pins required');
10
- const read = readGovernedArchive(root, manifestId, 1024 * 1024, route, now);
11
- if (read.status !== 'available' || read.reference.retention !== 'exact' || read.reference.parser.id !== 'factory-order-readback' || read.reference.parser.version !== '1')
12
- throw Error('exact governed order readback required');
13
- const value = JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(read.bytes));
14
- if (value.kind !== 'actual-fixed-profile-order' || value.producerCommit !== expected.producerCommit || !Array.isArray(value.nodes) || !value.nodes.length || value.nodes.length > 128 || value.nodes.some((n) => !n || !expected.obligations.includes(n.obligation?.digest) || typeof n.state !== 'string'))
15
- throw Error('order facts source/scope mismatch');
16
- const digest = createHash('sha256').update(read.bytes).digest('hex');
17
- const facts = { scopeDigest: expected.scopeDigest, version: 'fixed-order-facts-v1', population: expected.population, expectedWaits: [], checkpoints: [], violations: value.nodes.filter((n) => n.state === 'exhausted').map((n) => ({ obligationDigest: n.obligation.digest, status: 'FAIL', evidence: digest })), priorAccepted: [] };
18
- return { facts, source: { manifestId, sha256: digest, producerCommit: expected.producerCommit }, unknownNodes: value.nodes.filter((n) => !['satisfied', 'exhausted'].includes(n.state)).length, acceptance: 'not-assessed' };
19
- }
20
- //# sourceMappingURL=archive-facts.js.map
@@ -1,21 +0,0 @@
1
- import { ingestPolicySource } from "./archive-policy.js";
2
- export interface ArchiveObserverOptions {
3
- policyPath: string;
4
- sourceId: string;
5
- intervalMs: number;
6
- maxPolls: number;
7
- previousCheckpointId?: string;
8
- signal?: AbortSignal;
9
- /** Optional synchronous metadata consumer, never a worker hook. Its failure does not stop capture. */
10
- onObservation?: (value: ReturnType<typeof ingestPolicySource>) => void;
11
- }
12
- /** Bounded external file observation. No worker process, socket, session API, prompt or control channel is used. */
13
- export declare function observeArchiveSource(options: ArchiveObserverOptions): Promise<{
14
- observerId: `${string}-${string}-${string}-${string}-${string}`;
15
- polls: number;
16
- lastCheckpointId: string | null;
17
- receiptId: string;
18
- stopped: "aborted" | "poll-limit" | "policy-change";
19
- gaps: string[];
20
- workerInteractions: 0;
21
- }>;
@@ -1,79 +0,0 @@
1
- import { randomUUID } from "node:crypto";
2
- import { archivePolicyBinding, ingestPolicySource } from "./archive-policy.js";
3
- import { retainArchiveSource } from "./evidence-archive.js";
4
- function cadence(ms, signal) {
5
- return new Promise(resolve => {
6
- if (signal?.aborted) {
7
- resolve();
8
- return;
9
- }
10
- const finish = () => { clearTimeout(timer); signal?.removeEventListener("abort", finish); resolve(); };
11
- const timer = setTimeout(finish, ms);
12
- signal?.addEventListener("abort", finish, { once: true });
13
- });
14
- }
15
- /** Bounded external file observation. No worker process, socket, session API, prompt or control channel is used. */
16
- export async function observeArchiveSource(options) {
17
- if (!Number.isSafeInteger(options.intervalMs) || options.intervalMs < 1 || options.intervalMs > 60000
18
- || !Number.isSafeInteger(options.maxPolls) || options.maxPolls < 1 || options.maxPolls > 128)
19
- throw new Error("bounded observer interval/poll count required");
20
- const binding = archivePolicyBinding(options.policyPath, options.sourceId), observerId = randomUUID(), startedAt = new Date().toISOString();
21
- let lastCheckpointId = options.previousCheckpointId ?? null, polls = 0, receiptId = "", consumer = options.onObservation;
22
- let stopped = "poll-limit", terminal = false;
23
- const gaps = new Set();
24
- const records = [];
25
- const persist = () => retainArchiveSource(binding.archiveRoot, {
26
- sourceId: `observer-${observerId}`, parser: { id: "archive-observer", version: "1" }, retention: "exact",
27
- bytes: Buffer.from(JSON.stringify({ version: "archive-observer-v1", observerId, policySha256: binding.policySha256, sourceId: binding.sourceId,
28
- startedAt, polls, lastCheckpointId, state: terminal ? "terminal" : "running", stopped: terminal ? stopped : null, gaps: [...gaps].sort(), records, workerInteractions: 0, continuity: "bounded-observations-not-complete-live-coverage" })),
29
- }).manifestId;
30
- for (let i = 0; i < options.maxPolls; i++) {
31
- if (options.signal?.aborted) {
32
- stopped = "aborted";
33
- break;
34
- }
35
- try {
36
- if (archivePolicyBinding(options.policyPath, options.sourceId).policySha256 !== binding.policySha256)
37
- throw new Error("changed");
38
- }
39
- catch {
40
- gaps.add("policy-changed-or-unavailable");
41
- stopped = "policy-change";
42
- break;
43
- }
44
- polls++;
45
- try {
46
- const observation = ingestPolicySource(options.policyPath, options.sourceId, lastCheckpointId ?? undefined, binding.policySha256);
47
- lastCheckpointId = observation.checkpointId;
48
- records.push({ poll: polls, at: new Date().toISOString(), checkpointId: lastCheckpointId, state: "captured" });
49
- if (consumer) {
50
- try {
51
- const returned = consumer(observation);
52
- if (returned && typeof returned.then === "function") {
53
- gaps.add("async-consumer-outcome-unobserved");
54
- consumer = undefined;
55
- // The unsupported asynchronous outcome is already an explicit durable gap; never await it on capture.
56
- void Promise.resolve(returned).catch(() => undefined);
57
- }
58
- }
59
- catch {
60
- gaps.add("observation-consumer-failed");
61
- consumer = undefined;
62
- }
63
- }
64
- }
65
- catch {
66
- gaps.add("source-observation-failed");
67
- records.push({ poll: polls, at: new Date().toISOString(), checkpointId: lastCheckpointId, state: "gap" });
68
- }
69
- receiptId = persist();
70
- if (i + 1 < options.maxPolls)
71
- await cadence(options.intervalMs, options.signal);
72
- }
73
- if (options.signal?.aborted)
74
- stopped = "aborted";
75
- terminal = true;
76
- receiptId = persist();
77
- return { observerId, polls, lastCheckpointId, receiptId, stopped, gaps: [...gaps].sort(), workerInteractions: 0 };
78
- }
79
- //# sourceMappingURL=archive-observer.js.map
@@ -1,107 +0,0 @@
1
- import { type ArchiveRetention } from "./evidence-archive.js";
2
- export interface PolicySource {
3
- id: string;
4
- path: string;
5
- parser: {
6
- id: string;
7
- version: string;
8
- };
9
- contentPolicy?: "manifest-only" | "referenced-blobs";
10
- }
11
- export interface ArchiveIngestionPolicy {
12
- version: "archive-policy-v1" | "archive-policy-v2";
13
- id: string;
14
- revision: string;
15
- sourceRoot: string;
16
- archiveRoot: string;
17
- maxBytes: number;
18
- retention: ArchiveRetention;
19
- expiresAt: string;
20
- sources: PolicySource[];
21
- }
22
- /** Host-only policy binding for bounded external observation; no source bytes are read. */
23
- export declare function archivePolicyBinding(policyPath: string, sourceId: string): Readonly<{
24
- policySha256: string;
25
- archiveRoot: string;
26
- sourceId: string;
27
- archiveSourceId: string;
28
- expiresAt: string;
29
- }>;
30
- /** Explicit operator-selected file policy. Not a credential, authorization attestation or hostile-agent sandbox. */
31
- export declare function ingestPolicySource(policyPath: string, sourceId: string, previousCheckpointId?: string, expectedPolicySha256?: string): {
32
- change: string;
33
- policyReceiptId: string;
34
- kind: "execution-retention-v2";
35
- checkpointId: string;
36
- policySha256: string;
37
- sourceId: string;
38
- archiveSourceId: string;
39
- sourceSha256: string;
40
- sourceStatus: "available";
41
- retention: "exact";
42
- syntax: "not-applicable";
43
- runtime: "running" | "terminal";
44
- content: Record<"session" | "stdout" | "stderr" | "paneSnapshot" | "checkReceipt" | "result", {
45
- status: "available" | "missing" | "mismatch";
46
- sha256: string | null;
47
- bytes: number | null;
48
- }>;
49
- activeBranch: null;
50
- coverage: "partial";
51
- issueCount: number;
52
- acceptance: "not-assessed";
53
- } | {
54
- sourceId: string;
55
- archiveSourceId: string;
56
- change: import("./archive-checkpoint.js").SnapshotChange | "repeat";
57
- policyReceiptId: string;
58
- checkpointId: string;
59
- policySha256: string;
60
- sourceSha256: string;
61
- sourceStatus: "available" | "missing" | "error";
62
- retention: ArchiveRetention;
63
- syntax: "error" | "complete" | "partial" | "unavailable";
64
- completeBytes: number;
65
- pendingBytes: number;
66
- invalidLines: number;
67
- issues: string[];
68
- activeBranch: null;
69
- acceptance: "not-assessed";
70
- };
71
- /** Metadata-only CLI/read-model output; no payload, local path or policy file is exported. */
72
- export declare function inspectPolicyCheckpoint(policyPath: string, sourceId: string, checkpointId: string): {
73
- kind: "execution-retention-v2";
74
- checkpointId: string;
75
- policySha256: string;
76
- sourceId: string;
77
- archiveSourceId: string;
78
- sourceSha256: string;
79
- sourceStatus: "available";
80
- retention: "exact";
81
- syntax: "not-applicable";
82
- runtime: "running" | "terminal";
83
- content: Record<"session" | "stdout" | "stderr" | "paneSnapshot" | "checkReceipt" | "result", {
84
- status: "available" | "missing" | "mismatch";
85
- sha256: string | null;
86
- bytes: number | null;
87
- }>;
88
- activeBranch: null;
89
- coverage: "partial";
90
- issueCount: number;
91
- acceptance: "not-assessed";
92
- } | {
93
- sourceId: string;
94
- archiveSourceId: string;
95
- checkpointId: string;
96
- policySha256: string;
97
- sourceSha256: string;
98
- sourceStatus: "available" | "missing" | "error";
99
- retention: ArchiveRetention;
100
- syntax: "error" | "complete" | "partial" | "unavailable";
101
- completeBytes: number;
102
- pendingBytes: number;
103
- invalidLines: number;
104
- issues: string[];
105
- activeBranch: null;
106
- acceptance: "not-assessed";
107
- };
@@ -1,135 +0,0 @@
1
- import { closeSync, constants, fstatSync, lstatSync, openSync, readSync } from "node:fs";
2
- import { createHash } from "node:crypto";
3
- import { dirname, isAbsolute, join, parse, resolve, sep } from "node:path";
4
- import { ingestArchiveSnapshot, readArchiveCheckpoint } from "./archive-checkpoint.js";
5
- import { retainArchiveSource } from "./evidence-archive.js";
6
- import { ingestNativePolicy, inspectNativePolicy } from "./archive-retention-policy.js";
7
- const ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
8
- const forbidden = new Set([".pi", ".env", "auth.json", "credentials", "credentials.json"]);
9
- function fail() { throw new Error("archive policy refused invalid, expired or inaccessible input"); }
10
- const keys = (v, names) => !!v && typeof v === "object" && !Array.isArray(v)
11
- && Object.keys(v).length === names.length && Object.keys(v).every(k => names.includes(k));
12
- const identifier = (v) => typeof v === "string" && ID.test(v);
13
- function regularBytes(path, limit) {
14
- if (!constants.O_NOFOLLOW || !constants.O_NONBLOCK)
15
- fail();
16
- const absolute = resolve(path);
17
- if (absolute.split(sep).some(part => forbidden.has(part)))
18
- fail();
19
- let current = parse(absolute).root;
20
- for (const part of dirname(absolute).slice(current.length).split(sep).filter(Boolean)) {
21
- current = join(current, part);
22
- const stat = lstatSync(current);
23
- if (!stat.isDirectory() || stat.isSymbolicLink())
24
- fail();
25
- }
26
- const fd = openSync(absolute, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
27
- try {
28
- const stat = fstatSync(fd);
29
- if (!stat.isFile() || stat.size > limit || (stat.mode & 0o077) !== 0 || (process.getuid && stat.uid !== process.getuid()))
30
- fail();
31
- const bytes = Buffer.alloc(limit + 1);
32
- let size = 0;
33
- while (size <= limit) {
34
- const n = readSync(fd, bytes, size, bytes.length - size, size);
35
- if (!n)
36
- break;
37
- size += n;
38
- }
39
- if (size > limit)
40
- fail();
41
- return bytes.subarray(0, size);
42
- }
43
- finally {
44
- closeSync(fd);
45
- }
46
- }
47
- function selectedPolicy(path, sourceId) {
48
- const bytes = regularBytes(path, 65536);
49
- const text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
50
- const p = JSON.parse(text);
51
- // Canonical JSON excludes duplicate-key ambiguity. This is a selected operator configuration, not a signed approval.
52
- if (JSON.stringify(p) !== text || !keys(p, ["version", "id", "revision", "sourceRoot", "archiveRoot", "maxBytes", "retention", "expiresAt", "sources"])
53
- || !["archive-policy-v1", "archive-policy-v2"].includes(p.version) || !identifier(p.id) || !identifier(p.revision)
54
- || typeof p.sourceRoot !== "string" || !isAbsolute(p.sourceRoot) || typeof p.archiveRoot !== "string" || !isAbsolute(p.archiveRoot)
55
- || resolve(p.sourceRoot) === resolve(p.archiveRoot)
56
- || [p.sourceRoot, p.archiveRoot].some(root => root.split(/[\\/]/).some(part => forbidden.has(part)))
57
- || !Number.isSafeInteger(p.maxBytes) || p.maxBytes < 1 || p.maxBytes > 8 * 1024 * 1024
58
- || !["exact", "redacted", "reference-only"].includes(p.retention)
59
- || typeof p.expiresAt !== "string" || !Number.isFinite(Date.parse(p.expiresAt))
60
- || new Date(p.expiresAt).toISOString() !== p.expiresAt || Date.parse(p.expiresAt) <= Date.now()
61
- || !Array.isArray(p.sources) || p.sources.length < 1 || p.sources.length > 128)
62
- fail();
63
- const ids = new Set();
64
- for (const item of p.sources) {
65
- if (!keys(item, p.version === "archive-policy-v2" ? ["id", "path", "parser", "contentPolicy"] : ["id", "path", "parser"]) || !identifier(item.id) || ids.has(item.id)
66
- || typeof item.path !== "string" || !item.path || isAbsolute(item.path) || item.path.includes("\\")
67
- || item.path.split("/").some(part => !part || part === "." || part === ".." || forbidden.has(part))
68
- || !keys(item.parser, ["id", "version"]) || !identifier(item.parser.id) || !identifier(item.parser.version))
69
- fail();
70
- if (p.version === "archive-policy-v2" && !["manifest-only", "referenced-blobs"].includes(item.contentPolicy))
71
- fail();
72
- if (item.contentPolicy === "referenced-blobs" && (p.retention !== "exact" || item.parser.id !== "pi-daddy-execution-retention" || item.parser.version !== "2.0"))
73
- fail();
74
- ids.add(item.id);
75
- }
76
- const source = p.sources.find(s => s.id === sourceId);
77
- if (!source)
78
- fail();
79
- const root = lstatSync(p.sourceRoot);
80
- if (!root.isDirectory() || root.isSymbolicLink() || (root.mode & 0o077) !== 0 || (process.getuid && root.uid !== process.getuid()))
81
- fail();
82
- const archiveSourceId = `policy-source-${createHash("sha256").update(JSON.stringify([p.id, source.id, resolve(p.sourceRoot), source.path])).digest("hex")}`;
83
- return { policy: p, source, archiveSourceId, policySha256: createHash("sha256").update(bytes).digest("hex") };
84
- }
85
- function metadata(result, checkpointId, policySha256) {
86
- return { checkpointId, policySha256, sourceId: result.checkpoint.sourceId, sourceSha256: result.checkpoint.sourceSha256,
87
- sourceStatus: result.source.status, retention: result.checkpoint.retention, syntax: result.checkpoint.syntax,
88
- completeBytes: result.checkpoint.completeBytes, pendingBytes: result.checkpoint.pendingBytes,
89
- invalidLines: result.checkpoint.invalidLines, issues: result.checkpoint.issues,
90
- activeBranch: result.checkpoint.activeBranch, acceptance: result.checkpoint.acceptance };
91
- }
92
- /** Host-only policy binding for bounded external observation; no source bytes are read. */
93
- export function archivePolicyBinding(policyPath, sourceId) {
94
- const selected = selectedPolicy(policyPath, sourceId);
95
- return Object.freeze({ policySha256: selected.policySha256, archiveRoot: selected.policy.archiveRoot,
96
- sourceId, archiveSourceId: selected.archiveSourceId, expiresAt: selected.policy.expiresAt });
97
- }
98
- /** Explicit operator-selected file policy. Not a credential, authorization attestation or hostile-agent sandbox. */
99
- export function ingestPolicySource(policyPath, sourceId, previousCheckpointId, expectedPolicySha256) {
100
- try {
101
- const { policy, source, archiveSourceId, policySha256 } = selectedPolicy(policyPath, sourceId);
102
- if (expectedPolicySha256 !== undefined && expectedPolicySha256 !== policySha256)
103
- throw new Error("archive policy changed");
104
- if (source.contentPolicy === "referenced-blobs")
105
- return ingestNativePolicy({ policy, source, archiveSourceId, policySha256 }, previousCheckpointId, regularBytes);
106
- const bytes = regularBytes(join(policy.sourceRoot, source.path), policy.maxBytes);
107
- const result = ingestArchiveSnapshot(policy.archiveRoot, { sourceId: archiveSourceId, parser: source.parser, retention: policy.retention, bytes, previousCheckpointId });
108
- const receipt = retainArchiveSource(policy.archiveRoot, {
109
- sourceId: `policy-${policySha256}`, parser: { id: "archive-policy-receipt", version: "1" }, retention: "exact",
110
- bytes: Buffer.from(JSON.stringify({ version: "archive-policy-receipt-v1", policySha256, checkpointId: result.checkpointId, sourceId })),
111
- });
112
- return { ...metadata(result, result.checkpointId, policySha256), sourceId, archiveSourceId, change: result.change, policyReceiptId: receipt.manifestId };
113
- }
114
- catch {
115
- fail();
116
- }
117
- }
118
- /** Metadata-only CLI/read-model output; no payload, local path or policy file is exported. */
119
- export function inspectPolicyCheckpoint(policyPath, sourceId, checkpointId) {
120
- try {
121
- const { policy, source, archiveSourceId, policySha256 } = selectedPolicy(policyPath, sourceId);
122
- if (source.contentPolicy === "referenced-blobs")
123
- return inspectNativePolicy({ policy, source, archiveSourceId, policySha256 }, checkpointId);
124
- const result = readArchiveCheckpoint(policy.archiveRoot, checkpointId);
125
- const c = result.checkpoint;
126
- if (c.sourceId !== archiveSourceId || c.retention !== policy.retention || c.sourceBytes > policy.maxBytes
127
- || c.declaredParser.id !== source.parser.id || c.declaredParser.version !== source.parser.version)
128
- fail();
129
- return { ...metadata(result, checkpointId, policySha256), sourceId, archiveSourceId };
130
- }
131
- catch {
132
- fail();
133
- }
134
- }
135
- //# sourceMappingURL=archive-policy.js.map
@@ -1,49 +0,0 @@
1
- import { type GovernedArchiveRoute } from './archive-access.js';
2
- export interface ArchiveReadCapabilityOptions {
3
- root: string;
4
- /** Optional durable shared policy; absent preserves the historical raw route. */
5
- access?: GovernedArchiveRoute;
6
- /** Independently selected, content-reviewed artifact IDs; never accepted from model requests. */
7
- manifestIds: readonly string[];
8
- maxCalls: number;
9
- /** Total returned bytes, not a claim about OS-level read bandwidth or process memory. */
10
- maxBytes: number;
11
- durationMs: number;
12
- representations?: readonly ("exact" | "redacted")[];
13
- }
14
- /** A closed read interface for an existing host/tool integration, not an OS sandbox or model route qualification. */
15
- export declare function createArchiveReadCapability(options: ArchiveReadCapabilityOptions, clock?: () => number): Readonly<{
16
- snapshot: Readonly<{
17
- id: string;
18
- version: string;
19
- manifestIds: readonly any[];
20
- maxCalls: number;
21
- maxBytes: number;
22
- durationMs: number;
23
- representations: readonly string[];
24
- access?: Readonly<{
25
- directory: string;
26
- purpose: string;
27
- }> | undefined;
28
- }>;
29
- status: () => Readonly<{
30
- calls: number;
31
- bytes: number;
32
- expired: boolean;
33
- }>;
34
- read(manifestId: string): Readonly<{
35
- manifestId: string;
36
- reference: Readonly<{
37
- schema: "archive-source-v1";
38
- sourceId: string;
39
- parser: {
40
- id: string;
41
- version: string;
42
- };
43
- sha256: string;
44
- bytes: number;
45
- retention: import("./evidence-archive.js").ArchiveRetention;
46
- }>;
47
- bytes: Buffer<ArrayBuffer>;
48
- }>;
49
- }>;
@@ -1,45 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { performance } from "node:perf_hooks";
3
- import { readGovernedArchive } from './archive-access.js';
4
- import { readArchiveSource } from "./evidence-archive.js";
5
- /** A closed read interface for an existing host/tool integration, not an OS sandbox or model route qualification. */
6
- export function createArchiveReadCapability(options, clock = () => performance.now()) {
7
- if (!Array.isArray(options.manifestIds) || !options.manifestIds.length || options.manifestIds.length > 4096
8
- || options.manifestIds.some(id => typeof id !== "string" || !/^[a-f0-9]{64}$/.test(id))
9
- || !Number.isSafeInteger(options.maxCalls) || options.maxCalls < 1 || options.maxCalls > 128
10
- || !Number.isSafeInteger(options.maxBytes) || options.maxBytes < 1 || options.maxBytes > 64 * 1024 * 1024
11
- || !Number.isSafeInteger(options.durationMs) || options.durationMs < 1 || options.durationMs > 3600000)
12
- throw new Error("invalid archive capability bounds");
13
- const root = options.root, maxCalls = options.maxCalls, maxBytes = options.maxBytes, durationMs = options.durationMs;
14
- const representations = [...new Set(options.representations ?? ["redacted"])].sort();
15
- if (!representations.length || representations.some(r => r !== "exact" && r !== "redacted"))
16
- throw new Error("invalid archive representation policy");
17
- const ids = Object.freeze([...new Set(options.manifestIds)].sort()), allowed = new Set(ids), started = clock();
18
- if (!Number.isFinite(started))
19
- throw new Error("invalid host clock");
20
- const access = options.access ? Object.freeze({ ...options.access }) : undefined;
21
- const descriptor = { ...(access ? { access } : {}), version: "archive-read-capability-v1", manifestIds: ids, maxCalls, maxBytes, durationMs, representations: Object.freeze(representations) };
22
- const snapshot = Object.freeze({ ...descriptor, id: createHash("sha256").update(JSON.stringify(descriptor)).digest("hex") });
23
- let calls = 0, returned = 0;
24
- const elapsed = () => { const now = clock(); if (!Number.isFinite(now) || now < started)
25
- return Infinity; return now - started; };
26
- return Object.freeze({
27
- snapshot,
28
- status: () => Object.freeze({ calls, bytes: returned, expired: elapsed() >= durationMs }),
29
- read(manifestId) {
30
- if (calls >= maxCalls || elapsed() >= durationMs)
31
- throw new Error("archive read refused");
32
- calls++;
33
- if (typeof manifestId !== "string" || !allowed.has(manifestId))
34
- throw new Error("archive read refused");
35
- const limit = Math.min(8 * 1024 * 1024, maxBytes - returned);
36
- const source = access ? readGovernedArchive(root, manifestId, limit, access) : readArchiveSource(root, manifestId, limit);
37
- if (source.status !== "available" || !representations.includes(source.reference.retention)
38
- || source.bytes.length > maxBytes - returned || elapsed() >= durationMs)
39
- throw new Error("archive read refused");
40
- returned += source.bytes.length;
41
- return Object.freeze({ manifestId, reference: Object.freeze({ ...source.reference }), bytes: Buffer.from(source.bytes) });
42
- },
43
- });
44
- }
45
- //# sourceMappingURL=archive-read-capability.js.map
@@ -1,52 +0,0 @@
1
- import type { ArchiveIngestionPolicy, PolicySource } from "./archive-policy.js";
2
- interface Context {
3
- policy: ArchiveIngestionPolicy;
4
- source: PolicySource;
5
- archiveSourceId: string;
6
- policySha256: string;
7
- }
8
- export declare function inspectNativePolicy(context: Context, checkpointId: string): {
9
- kind: "execution-retention-v2";
10
- checkpointId: string;
11
- policySha256: string;
12
- sourceId: string;
13
- archiveSourceId: string;
14
- sourceSha256: string;
15
- sourceStatus: "available";
16
- retention: "exact";
17
- syntax: "not-applicable";
18
- runtime: "running" | "terminal";
19
- content: Record<"session" | "stdout" | "stderr" | "paneSnapshot" | "checkReceipt" | "result", {
20
- status: "available" | "missing" | "mismatch";
21
- sha256: string | null;
22
- bytes: number | null;
23
- }>;
24
- activeBranch: null;
25
- coverage: "partial";
26
- issueCount: number;
27
- acceptance: "not-assessed";
28
- };
29
- export declare function ingestNativePolicy(context: Context, previous: string | undefined, readBytes: (path: string, limit: number) => Buffer): {
30
- change: string;
31
- policyReceiptId: string;
32
- kind: "execution-retention-v2";
33
- checkpointId: string;
34
- policySha256: string;
35
- sourceId: string;
36
- archiveSourceId: string;
37
- sourceSha256: string;
38
- sourceStatus: "available";
39
- retention: "exact";
40
- syntax: "not-applicable";
41
- runtime: "running" | "terminal";
42
- content: Record<"session" | "stdout" | "stderr" | "paneSnapshot" | "checkReceipt" | "result", {
43
- status: "available" | "missing" | "mismatch";
44
- sha256: string | null;
45
- bytes: number | null;
46
- }>;
47
- activeBranch: null;
48
- coverage: "partial";
49
- issueCount: number;
50
- acceptance: "not-assessed";
51
- };
52
- export {};