@jterrats/open-orchestra 1.0.16 → 1.0.17

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 (99) hide show
  1. package/CLAUDE.md +24 -2
  2. package/README.md +32 -9
  3. package/dist/benchmark.js +65 -27
  4. package/dist/benchmark.js.map +1 -1
  5. package/dist/metrics-commands.js +3 -0
  6. package/dist/metrics-commands.js.map +1 -1
  7. package/dist/runtime-bootstrap.js +33 -8
  8. package/dist/runtime-bootstrap.js.map +1 -1
  9. package/dist/runtime-capacity-policy.d.ts +38 -0
  10. package/dist/runtime-capacity-policy.js +117 -0
  11. package/dist/runtime-capacity-policy.js.map +1 -0
  12. package/dist/runtime-capacity-scheduler-helpers.d.ts +40 -0
  13. package/dist/runtime-capacity-scheduler-helpers.js +111 -0
  14. package/dist/runtime-capacity-scheduler-helpers.js.map +1 -0
  15. package/dist/runtime-capacity-scheduler-state.d.ts +44 -0
  16. package/dist/runtime-capacity-scheduler-state.js +128 -0
  17. package/dist/runtime-capacity-scheduler-state.js.map +1 -0
  18. package/dist/runtime-capacity-scheduler.d.ts +34 -0
  19. package/dist/runtime-capacity-scheduler.js +193 -0
  20. package/dist/runtime-capacity-scheduler.js.map +1 -0
  21. package/dist/runtime-capacity-snapshot.d.ts +14 -0
  22. package/dist/runtime-capacity-snapshot.js +87 -0
  23. package/dist/runtime-capacity-snapshot.js.map +1 -0
  24. package/dist/runtime-child-prompt.d.ts +2 -1
  25. package/dist/runtime-child-prompt.js +4 -1
  26. package/dist/runtime-child-prompt.js.map +1 -1
  27. package/dist/runtime-claude-native-bridge.js +2 -1
  28. package/dist/runtime-claude-native-bridge.js.map +1 -1
  29. package/dist/runtime-commands.js +6 -0
  30. package/dist/runtime-commands.js.map +1 -1
  31. package/dist/runtime-lifecycle-watch.d.ts +5 -2
  32. package/dist/runtime-lifecycle-watch.js +19 -3
  33. package/dist/runtime-lifecycle-watch.js.map +1 -1
  34. package/dist/runtime-load-balancer.d.ts +12 -0
  35. package/dist/runtime-load-balancer.js +106 -0
  36. package/dist/runtime-load-balancer.js.map +1 -0
  37. package/dist/runtime-spawn-bridge.js +23 -0
  38. package/dist/runtime-spawn-bridge.js.map +1 -1
  39. package/dist/runtime-spawn-guidance.js +15 -0
  40. package/dist/runtime-spawn-guidance.js.map +1 -1
  41. package/dist/runtime-worker-registry.d.ts +19 -0
  42. package/dist/runtime-worker-registry.js +84 -0
  43. package/dist/runtime-worker-registry.js.map +1 -0
  44. package/dist/security/content-classifier.d.ts +2 -0
  45. package/dist/security/content-classifier.js +147 -0
  46. package/dist/security/content-classifier.js.map +1 -0
  47. package/dist/security/operation-contract-types.d.ts +28 -0
  48. package/dist/security/operation-contract-types.js +2 -0
  49. package/dist/security/operation-contract-types.js.map +1 -0
  50. package/dist/security/operation-contract.d.ts +2 -0
  51. package/dist/security/operation-contract.js +169 -0
  52. package/dist/security/operation-contract.js.map +1 -0
  53. package/dist/security/policy-engine.d.ts +2 -0
  54. package/dist/security/policy-engine.js +142 -0
  55. package/dist/security/policy-engine.js.map +1 -0
  56. package/dist/security/policy-types.d.ts +79 -0
  57. package/dist/security/policy-types.js +7 -0
  58. package/dist/security/policy-types.js.map +1 -0
  59. package/dist/security/prompt-intake.d.ts +13 -0
  60. package/dist/security/prompt-intake.js +33 -0
  61. package/dist/security/prompt-intake.js.map +1 -0
  62. package/dist/security/redaction.d.ts +3 -0
  63. package/dist/security/redaction.js +64 -0
  64. package/dist/security/redaction.js.map +1 -0
  65. package/dist/security/sink-encoding.d.ts +6 -0
  66. package/dist/security/sink-encoding.js +40 -0
  67. package/dist/security/sink-encoding.js.map +1 -0
  68. package/dist/sprint-commands.js +33 -22
  69. package/dist/sprint-commands.js.map +1 -1
  70. package/dist/transcription-failures.d.ts +2 -0
  71. package/dist/transcription-failures.js +4 -0
  72. package/dist/transcription-failures.js.map +1 -0
  73. package/dist/transcription-media-preflight.d.ts +9 -0
  74. package/dist/transcription-media-preflight.js +147 -0
  75. package/dist/transcription-media-preflight.js.map +1 -0
  76. package/dist/transcription-request.d.ts +13 -0
  77. package/dist/transcription-request.js +150 -0
  78. package/dist/transcription-request.js.map +1 -0
  79. package/dist/transcription-source-policy.d.ts +4 -0
  80. package/dist/transcription-source-policy.js +43 -0
  81. package/dist/transcription-source-policy.js.map +1 -0
  82. package/dist/transcription-types.d.ts +161 -0
  83. package/dist/transcription-types.js +2 -0
  84. package/dist/transcription-types.js.map +1 -0
  85. package/dist/types/runtime.d.ts +147 -0
  86. package/dist/types.d.ts +3 -1
  87. package/dist/types.js +1 -0
  88. package/dist/types.js.map +1 -1
  89. package/dist/workflow-phase-planner.js +5 -3
  90. package/dist/workflow-phase-planner.js.map +1 -1
  91. package/dist/workflow-phases.js +5 -0
  92. package/dist/workflow-phases.js.map +1 -1
  93. package/dist/workflow-run-commands.js +89 -10
  94. package/dist/workflow-run-commands.js.map +1 -1
  95. package/docs/audio-video-transcription-skill.md +102 -70
  96. package/docs/runtime-adapters.md +7 -0
  97. package/docs/runtime-capacity.md +57 -0
  98. package/docs/security-saas-orchestrator.md +368 -0
  99. package/package.json +1 -1
@@ -0,0 +1,169 @@
1
+ import { encodeForSink } from "./sink-encoding.js";
2
+ import { evaluateSecurityPolicy } from "./policy-engine.js";
3
+ import { intakePromptSegment } from "./prompt-intake.js";
4
+ import { redactPromptSegments } from "./redaction.js";
5
+ const specs = {
6
+ evidence: {
7
+ action: "evidence.write",
8
+ resourceType: "evidence",
9
+ sink: "evidence",
10
+ segmentKind: "evidence",
11
+ },
12
+ provider: {
13
+ action: "provider.message",
14
+ resourceType: "prompt",
15
+ sink: "provider",
16
+ segmentKind: "data",
17
+ },
18
+ pythonWorker: {
19
+ action: "pythonWorker.process",
20
+ resourceType: "pythonWorker",
21
+ sink: "json",
22
+ segmentKind: "data",
23
+ },
24
+ runtime: {
25
+ action: "command.execute",
26
+ resourceType: "command",
27
+ sink: "log",
28
+ segmentKind: "instruction",
29
+ },
30
+ tool: {
31
+ action: "command.execute",
32
+ resourceType: "command",
33
+ sink: "log",
34
+ segmentKind: "toolInput",
35
+ },
36
+ };
37
+ export function validateOperationPacket(input) {
38
+ const contractRules = validateContractShape(input);
39
+ if (contractRules.length > 0)
40
+ return contractDeny(input.packetId, contractRules);
41
+ const kind = input.kind;
42
+ const spec = specs[kind];
43
+ const packetId = input.packetId;
44
+ const subject = input.subject;
45
+ const action = input.action;
46
+ const resource = input.resource;
47
+ const sink = input.sink;
48
+ const semanticRules = [
49
+ exactRule("operation.contract.action", action, spec.action, "action"),
50
+ exactRule("operation.contract.resource", resource.resourceType, spec.resourceType, "resource type"),
51
+ exactRule("operation.contract.sink", sink, spec.sink, "sink"),
52
+ ...validatePythonWorkerContract(input),
53
+ ].filter((rule) => rule !== null);
54
+ if (semanticRules.length > 0)
55
+ return contractDeny(input.packetId, semanticRules);
56
+ const segment = normalizedSegment(input, spec, packetId, sink);
57
+ const redactionReport = redactPromptSegments([segment]);
58
+ const policySegment = redactedPolicySegment(input, spec, redactionReport, packetId, sink);
59
+ const policyDecision = evaluateSecurityPolicy({
60
+ requestId: packetId,
61
+ subject,
62
+ action,
63
+ resource,
64
+ sink,
65
+ dataClassification: policySegment.classification.classification,
66
+ segments: [policySegment],
67
+ redactionReport,
68
+ });
69
+ if (policyDecision.outcome === "deny")
70
+ return policyDecision;
71
+ return {
72
+ ...policyDecision,
73
+ encodedPayload: encodeForSink(policySegment.text, sink).value,
74
+ };
75
+ }
76
+ function validateContractShape(input) {
77
+ return [
78
+ requiredRule("operation.contract.packet-id", "packet id", input.packetId),
79
+ requiredRule("operation.contract.kind", "operation kind", input.kind),
80
+ requiredRule("operation.contract.subject", "subject", input.subject),
81
+ requiredRule("operation.contract.action", "action", input.action),
82
+ requiredRule("operation.contract.resource", "resource", input.resource),
83
+ requiredRule("operation.contract.resource-type", "resource type", input.resource?.resourceType),
84
+ requiredRule("operation.contract.sink", "sink", input.sink),
85
+ requiredRule("operation.contract.payload", "payload", input.payload),
86
+ requiredRule("operation.contract.payload-text", "payload text", input.payload?.text),
87
+ ].filter((rule) => rule !== null);
88
+ }
89
+ function validatePythonWorkerContract(input) {
90
+ if (input.kind !== "pythonWorker")
91
+ return [];
92
+ const worker = input.pythonWorker;
93
+ const rules = [
94
+ requiredRule("operation.python-worker.contract", "worker contract", worker),
95
+ exactRule("operation.python-worker.json-contract", worker?.contract, "json", "worker contract"),
96
+ falseRule("operation.python-worker.no-auth", "worker authorization authority", worker?.authorizes),
97
+ falseRule("operation.python-worker.no-network", "worker network access", worker?.network),
98
+ falseRule("operation.python-worker.no-filesystem", "worker filesystem access", worker?.filesystem),
99
+ boundedNumberRule("operation.python-worker.timeout", "worker timeout", worker?.timeoutMs, 1, 5000),
100
+ boundedNumberRule("operation.python-worker.input-bytes", "worker max input bytes", worker?.maxInputBytes, 1, 1_000_000),
101
+ jsonRule(input.payload?.text),
102
+ ];
103
+ return rules.filter((rule) => rule !== null);
104
+ }
105
+ function normalizedSegment(input, spec, packetId, sink) {
106
+ return intakePromptSegment({
107
+ id: `${packetId}:payload`,
108
+ kind: input.payload?.kind ?? spec.segmentKind,
109
+ provenance: input.payload?.provenance ?? `${input.kind}:packet`,
110
+ sink,
111
+ text: input.payload?.text ?? "",
112
+ });
113
+ }
114
+ function redactedPolicySegment(input, spec, redactionReport, packetId, sink) {
115
+ return intakePromptSegment({
116
+ id: `${packetId}:payload:redacted`,
117
+ kind: input.payload?.kind ?? spec.segmentKind,
118
+ provenance: input.payload?.provenance ?? `${input.kind}:packet`,
119
+ sink,
120
+ text: redactionReport.redactedSegments[0]?.text ?? "",
121
+ });
122
+ }
123
+ function requiredRule(ruleId, label, value) {
124
+ if (value)
125
+ return null;
126
+ return { ruleId, reason: `missing ${label}` };
127
+ }
128
+ function exactRule(ruleId, actual, expected, label) {
129
+ if (actual === expected)
130
+ return null;
131
+ return { ruleId, reason: `ambiguous ${label}` };
132
+ }
133
+ function falseRule(ruleId, label, value) {
134
+ if (value === false)
135
+ return null;
136
+ return { ruleId, reason: `${label} must be disabled` };
137
+ }
138
+ function boundedNumberRule(ruleId, label, value, min, max) {
139
+ if (typeof value === "number" &&
140
+ Number.isInteger(value) &&
141
+ value >= min &&
142
+ value <= max) {
143
+ return null;
144
+ }
145
+ return { ruleId, reason: `${label} must be between ${min} and ${max}` };
146
+ }
147
+ function jsonRule(text) {
148
+ try {
149
+ JSON.parse(text ?? "");
150
+ return null;
151
+ }
152
+ catch {
153
+ return {
154
+ ruleId: "operation.python-worker.json-payload",
155
+ reason: "worker payload must be valid JSON",
156
+ };
157
+ }
158
+ }
159
+ function contractDeny(packetId, rules) {
160
+ return {
161
+ requestId: packetId ?? "unknown",
162
+ outcome: "deny",
163
+ matchedRuleIds: rules.map((rule) => rule.ruleId),
164
+ redactionStatus: "unsafeUnredacted",
165
+ sanitizedReasons: rules.map((rule) => rule.reason),
166
+ evidenceSummary: "deny: operation contract failed closed",
167
+ };
168
+ }
169
+ //# sourceMappingURL=operation-contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operation-contract.js","sourceRoot":"","sources":["../../src/security/operation-contract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { PolicyDecision, PolicyRequestInput } from "./policy-types.js";
2
+ export declare function evaluateSecurityPolicy(input: PolicyRequestInput): PolicyDecision;
@@ -0,0 +1,142 @@
1
+ const sensitiveSinks = ["evidence", "log", "provider"];
2
+ export function evaluateSecurityPolicy(input) {
3
+ const validation = validatePolicyRequest(input);
4
+ if (validation.length > 0) {
5
+ return denyDecision(input.requestId, validation, "unsafeUnredacted");
6
+ }
7
+ const request = input;
8
+ const denied = deniedRules(request);
9
+ if (denied.length > 0) {
10
+ return denyDecision(request.requestId, denied, highestRedactionStatus(denied, request.redactionReport.status));
11
+ }
12
+ const quarantined = quarantineRules(request);
13
+ if (quarantined.length > 0) {
14
+ return quarantineDecision(request.requestId, quarantined, request.redactionReport.status);
15
+ }
16
+ return {
17
+ requestId: request.requestId,
18
+ outcome: "allow",
19
+ matchedRuleIds: ["policy.default.allow-after-rules"],
20
+ redactionStatus: request.redactionReport.status,
21
+ sanitizedReasons: ["request satisfied deterministic policy rules"],
22
+ evidenceSummary: "allow: deterministic security policy accepted request",
23
+ };
24
+ }
25
+ function validatePolicyRequest(input) {
26
+ const missing = [
27
+ requiredRule("policy.input.request-id", "request id", input.requestId),
28
+ requiredRule("policy.input.subject", "subject", input.subject),
29
+ requiredRule("policy.input.action", "action", input.action),
30
+ requiredRule("policy.input.resource", "resource", input.resource),
31
+ requiredRule("policy.input.sink", "sink", input.sink),
32
+ requiredRule("policy.input.data-classification", "data classification", input.dataClassification),
33
+ requiredRule("policy.input.redaction", "redaction report", input.redactionReport),
34
+ ].filter((rule) => rule !== null);
35
+ if (missing.length > 0)
36
+ return missing;
37
+ const scoped = input.subject?.tenantId ?? input.subject?.workspaceId;
38
+ const resourceScoped = input.resource?.tenantId ?? input.resource?.workspaceId;
39
+ const scopeRules = [
40
+ requiredRule("policy.scope.subject", "subject tenant or workspace", scoped),
41
+ requiredRule("policy.scope.resource", "resource tenant or workspace", resourceScoped),
42
+ ].filter((rule) => rule !== null);
43
+ if (scopeRules.length > 0)
44
+ return scopeRules;
45
+ if (input.subject?.tenantId && input.resource?.tenantId) {
46
+ if (input.subject.tenantId !== input.resource.tenantId) {
47
+ return [
48
+ {
49
+ ruleId: "policy.scope.tenant-mismatch",
50
+ reason: "subject and resource tenant scope do not match",
51
+ },
52
+ ];
53
+ }
54
+ }
55
+ return [];
56
+ }
57
+ function deniedRules(request) {
58
+ const rules = [];
59
+ if (request.redactionReport.status === "unsafeUnredacted") {
60
+ rules.push({
61
+ ruleId: "policy.redaction.fail-closed",
62
+ reason: "restricted content is not safely redacted",
63
+ redactionStatus: "unsafeUnredacted",
64
+ });
65
+ }
66
+ if (request.action === "url.fetch" || request.sink === "url") {
67
+ rules.push(...findingRules(request, "unsafeUrl", "deny"));
68
+ }
69
+ if (request.action === "file.write") {
70
+ rules.push(...findingRules(request, "pathTraversal", "deny"));
71
+ }
72
+ return rules;
73
+ }
74
+ function quarantineRules(request) {
75
+ const rules = request.segments.flatMap((segment) => {
76
+ if (segment.kind === "unknown" && isSensitiveSink(request.sink)) {
77
+ return [
78
+ {
79
+ ruleId: "policy.segment.unknown-sensitive-sink",
80
+ reason: `segment ${segment.id} is unknown for sensitive sink`,
81
+ },
82
+ ];
83
+ }
84
+ return segment.classification.findings
85
+ .filter((finding) => finding.severity === "critical" || finding.severity === "high")
86
+ .map((finding) => findingRule(segment.id, finding, "quarantine"));
87
+ });
88
+ if (request.dataClassification === "unknown" &&
89
+ isSensitiveSink(request.sink)) {
90
+ rules.push({
91
+ ruleId: "policy.data.unknown-sensitive-sink",
92
+ reason: "unknown data classification cannot reach sensitive sink",
93
+ });
94
+ }
95
+ return rules;
96
+ }
97
+ function findingRules(request, kind, disposition) {
98
+ return request.segments.flatMap((segment) => segment.classification.findings
99
+ .filter((finding) => finding.kind === kind)
100
+ .map((finding) => findingRule(segment.id, finding, disposition)));
101
+ }
102
+ function findingRule(segmentId, finding, disposition) {
103
+ return {
104
+ ruleId: `policy.${disposition}.${finding.kind}`,
105
+ reason: `segment ${segmentId} matched ${finding.summary}`,
106
+ };
107
+ }
108
+ function requiredRule(ruleId, label, value) {
109
+ if (value)
110
+ return null;
111
+ return {
112
+ ruleId,
113
+ reason: `missing ${label}`,
114
+ };
115
+ }
116
+ function denyDecision(requestId, rules, redactionStatus) {
117
+ return {
118
+ requestId: requestId ?? "unknown",
119
+ outcome: "deny",
120
+ matchedRuleIds: rules.map((rule) => rule.ruleId),
121
+ redactionStatus,
122
+ sanitizedReasons: rules.map((rule) => rule.reason),
123
+ evidenceSummary: "deny: deterministic security policy failed closed",
124
+ };
125
+ }
126
+ function quarantineDecision(requestId, rules, redactionStatus) {
127
+ return {
128
+ requestId,
129
+ outcome: "quarantine",
130
+ matchedRuleIds: rules.map((rule) => rule.ruleId),
131
+ redactionStatus,
132
+ sanitizedReasons: rules.map((rule) => rule.reason),
133
+ evidenceSummary: "quarantine: deterministic security policy isolated content",
134
+ };
135
+ }
136
+ function highestRedactionStatus(rules, fallback) {
137
+ return (rules.find((rule) => rule.redactionStatus)?.redactionStatus ?? fallback);
138
+ }
139
+ function isSensitiveSink(sink) {
140
+ return sensitiveSinks.some((sensitiveSink) => sensitiveSink === sink);
141
+ }
142
+ //# sourceMappingURL=policy-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-engine.js","sourceRoot":"","sources":["../../src/security/policy-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ export declare const policyDecisionOutcomes: readonly ["allow", "deny", "requiresApproval", "quarantine"];
2
+ export type PolicyDecisionOutcome = (typeof policyDecisionOutcomes)[number];
3
+ export type PolicyAction = "content.ingest" | "evidence.write" | "pythonWorker.process" | "provider.message" | "url.fetch" | "file.write" | "command.execute";
4
+ export type PolicySink = "evidence" | "htmlText" | "json" | "log" | "markdown" | "provider" | "shellArgument" | "url";
5
+ export type SegmentKind = "data" | "evidence" | "instruction" | "providerResponse" | "toolInput" | "toolOutput" | "unknown";
6
+ export type DataClassification = "public" | "internal" | "restricted" | "unknown";
7
+ export type FindingSeverity = "low" | "medium" | "high" | "critical";
8
+ export type ContentFindingKind = "indirectPromptInjection" | "noSqlLike" | "pathTraversal" | "promptInjection" | "secretShaped" | "shellLike" | "sqlLike" | "unsafeUrl";
9
+ export interface ContentFinding {
10
+ kind: ContentFindingKind;
11
+ ruleId: string;
12
+ severity: FindingSeverity;
13
+ summary: string;
14
+ }
15
+ export interface ContentClassification {
16
+ classification: DataClassification;
17
+ findings: ContentFinding[];
18
+ }
19
+ export interface PromptSegment {
20
+ id: string;
21
+ kind: SegmentKind;
22
+ provenance: string;
23
+ sink: PolicySink;
24
+ text: string;
25
+ byteLength: number;
26
+ classification: ContentClassification;
27
+ }
28
+ export type RedactionStatus = "notRequired" | "redacted" | "quarantined" | "unsafeUnredacted";
29
+ export interface RedactedSegment {
30
+ id: string;
31
+ text: string;
32
+ status: RedactionStatus;
33
+ redactedFindings: ContentFindingKind[];
34
+ }
35
+ export interface RedactionReport {
36
+ status: RedactionStatus;
37
+ redactedSegments: RedactedSegment[];
38
+ sanitizedReasons: string[];
39
+ }
40
+ export interface PolicySubject {
41
+ id: string;
42
+ subjectType: "human" | "runtime" | "system" | "tool";
43
+ tenantId?: string;
44
+ workspaceId?: string;
45
+ }
46
+ export interface PolicyResource {
47
+ resourceType: "command" | "evidence" | "file" | "prompt" | "pythonWorker" | "url";
48
+ summary: string;
49
+ tenantId?: string;
50
+ workspaceId?: string;
51
+ }
52
+ export interface PolicyRequest {
53
+ requestId: string;
54
+ subject: PolicySubject;
55
+ action: PolicyAction;
56
+ resource: PolicyResource;
57
+ sink: PolicySink;
58
+ dataClassification: DataClassification;
59
+ segments: PromptSegment[];
60
+ redactionReport: RedactionReport;
61
+ }
62
+ export interface PolicyRequestInput {
63
+ requestId?: string;
64
+ subject?: Partial<PolicySubject>;
65
+ action?: PolicyAction;
66
+ resource?: Partial<PolicyResource>;
67
+ sink?: PolicySink;
68
+ dataClassification?: DataClassification;
69
+ segments?: PromptSegment[];
70
+ redactionReport?: RedactionReport;
71
+ }
72
+ export interface PolicyDecision {
73
+ requestId: string;
74
+ outcome: PolicyDecisionOutcome;
75
+ matchedRuleIds: string[];
76
+ redactionStatus: RedactionStatus;
77
+ sanitizedReasons: string[];
78
+ evidenceSummary: string;
79
+ }
@@ -0,0 +1,7 @@
1
+ export const policyDecisionOutcomes = [
2
+ "allow",
3
+ "deny",
4
+ "requiresApproval",
5
+ "quarantine",
6
+ ];
7
+ //# sourceMappingURL=policy-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-types.js","sourceRoot":"","sources":["../../src/security/policy-types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,OAAO;IACP,MAAM;IACN,kBAAkB;IAClB,YAAY;CACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { PolicySink, PromptSegment, SegmentKind } from "./policy-types.js";
2
+ export interface PromptSegmentInput {
3
+ id?: string;
4
+ kind?: SegmentKind;
5
+ provenance?: string;
6
+ sink?: PolicySink;
7
+ text?: string;
8
+ }
9
+ export interface PromptPacketInput {
10
+ segments?: PromptSegmentInput[];
11
+ }
12
+ export declare function intakePromptPacket(packet: PromptPacketInput): PromptSegment[];
13
+ export declare function intakePromptSegment(input: PromptSegmentInput, fallbackId?: string): PromptSegment;
@@ -0,0 +1,33 @@
1
+ import { Buffer } from "node:buffer";
2
+ import { classifyContent } from "./content-classifier.js";
3
+ export function intakePromptPacket(packet) {
4
+ if (!Array.isArray(packet.segments)) {
5
+ return [unknownSegment("segment-1", "malformed prompt packet")];
6
+ }
7
+ return packet.segments.map((segment, index) => intakePromptSegment(segment, `segment-${index + 1}`));
8
+ }
9
+ export function intakePromptSegment(input, fallbackId = "segment-1") {
10
+ const text = typeof input.text === "string" ? input.text : "";
11
+ const kind = input.kind ?? "unknown";
12
+ return {
13
+ id: input.id ?? fallbackId,
14
+ kind,
15
+ provenance: input.provenance ?? "unknown",
16
+ sink: input.sink ?? "provider",
17
+ text,
18
+ byteLength: Buffer.byteLength(text, "utf8"),
19
+ classification: classifyContent(text),
20
+ };
21
+ }
22
+ function unknownSegment(id, text) {
23
+ return {
24
+ id,
25
+ kind: "unknown",
26
+ provenance: "unknown",
27
+ sink: "provider",
28
+ text,
29
+ byteLength: Buffer.byteLength(text, "utf8"),
30
+ classification: classifyContent(text),
31
+ };
32
+ }
33
+ //# sourceMappingURL=prompt-intake.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-intake.js","sourceRoot":"","sources":["../../src/security/prompt-intake.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAe1D,MAAM,UAAU,kBAAkB,CAAC,MAAyB;IAC1D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpC,OAAO,CAAC,cAAc,CAAC,WAAW,EAAE,yBAAyB,CAAC,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAC5C,mBAAmB,CAAC,OAAO,EAAE,WAAW,KAAK,GAAG,CAAC,EAAE,CAAC,CACrD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,KAAyB,EACzB,UAAU,GAAG,WAAW;IAExB,MAAM,IAAI,GAAG,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9D,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,SAAS,CAAC;IACrC,OAAO;QACL,EAAE,EAAE,KAAK,CAAC,EAAE,IAAI,UAAU;QAC1B,IAAI;QACJ,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,SAAS;QACzC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,UAAU;QAC9B,IAAI;QACJ,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC;QAC3C,cAAc,EAAE,eAAe,CAAC,IAAI,CAAC;KACtC,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,EAAU,EAAE,IAAY;IAC9C,OAAO;QACL,EAAE;QACF,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,SAAS;QACrB,IAAI,EAAE,UAAU;QAChB,IAAI;QACJ,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC;QAC3C,cAAc,EAAE,eAAe,CAAC,IAAI,CAAC;KACtC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PromptSegment, RedactedSegment, RedactionReport } from "./policy-types.js";
2
+ export declare function redactPromptSegments(segments: PromptSegment[]): RedactionReport;
3
+ export declare function redactPromptSegment(segment: PromptSegment): RedactedSegment;
@@ -0,0 +1,64 @@
1
+ const secretReplacement = "[REDACTED_SECRET]";
2
+ const bearerPattern = /\bbearer\s+[a-z0-9._-]{12,}/gi;
3
+ const assignmentPattern = /\b(api[_-]?key|password|secret|token)(\s*[:=]\s*)[^\s"']{12,}/gi;
4
+ const secretPatterns = [bearerPattern, assignmentPattern];
5
+ export function redactPromptSegments(segments) {
6
+ const redactedSegments = segments.map(redactPromptSegment);
7
+ const status = reportStatus(redactedSegments);
8
+ return {
9
+ status,
10
+ redactedSegments,
11
+ sanitizedReasons: sanitizedReasons(redactedSegments, status),
12
+ };
13
+ }
14
+ export function redactPromptSegment(segment) {
15
+ const secretFindings = segment.classification.findings.filter((finding) => finding.kind === "secretShaped");
16
+ const redactedText = redactSecrets(segment.text);
17
+ const wasRedacted = redactedText !== segment.text;
18
+ const hasRemainingSecret = secretPatterns.some((pattern) => {
19
+ pattern.lastIndex = 0;
20
+ return pattern.test(redactedText);
21
+ });
22
+ return {
23
+ id: segment.id,
24
+ text: redactedText,
25
+ status: redactionStatus(secretFindings.length, wasRedacted, hasRemainingSecret),
26
+ redactedFindings: wasRedacted ? ["secretShaped"] : [],
27
+ };
28
+ }
29
+ function redactSecrets(text) {
30
+ return text
31
+ .replace(bearerPattern, secretReplacement)
32
+ .replace(assignmentPattern, (_match, label, separator) => {
33
+ return `${label}${separator}${secretReplacement}`;
34
+ });
35
+ }
36
+ function redactionStatus(secretFindingCount, wasRedacted, hasRemainingSecret) {
37
+ if (hasRemainingSecret)
38
+ return "unsafeUnredacted";
39
+ if (wasRedacted)
40
+ return "redacted";
41
+ if (secretFindingCount > 0)
42
+ return "unsafeUnredacted";
43
+ return "notRequired";
44
+ }
45
+ function reportStatus(segments) {
46
+ if (segments.some((segment) => segment.status === "unsafeUnredacted")) {
47
+ return "unsafeUnredacted";
48
+ }
49
+ if (segments.some((segment) => segment.status === "redacted")) {
50
+ return "redacted";
51
+ }
52
+ return "notRequired";
53
+ }
54
+ function sanitizedReasons(segments, status) {
55
+ if (status === "notRequired")
56
+ return ["no restricted values detected"];
57
+ return segments
58
+ .filter((segment) => segment.redactedFindings.length > 0)
59
+ .map((segment) => redactionReason(segment.id, segment.redactedFindings));
60
+ }
61
+ function redactionReason(segmentId, findings) {
62
+ return `segment ${segmentId} redacted ${findings.join(", ")}`;
63
+ }
64
+ //# sourceMappingURL=redaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redaction.js","sourceRoot":"","sources":["../../src/security/redaction.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { PolicySink } from "./policy-types.js";
2
+ export interface EncodedSinkValue {
3
+ sink: PolicySink;
4
+ value: string;
5
+ }
6
+ export declare function encodeForSink(text: string, sink: PolicySink): EncodedSinkValue;
@@ -0,0 +1,40 @@
1
+ export function encodeForSink(text, sink) {
2
+ return {
3
+ sink,
4
+ value: sinkEncoder(sink)(text),
5
+ };
6
+ }
7
+ function sinkEncoder(sink) {
8
+ const encoders = {
9
+ evidence: escapeMarkdown,
10
+ htmlText: escapeHtmlText,
11
+ json: JSON.stringify,
12
+ log: normalizeLogLine,
13
+ markdown: escapeMarkdown,
14
+ provider: wrapProviderData,
15
+ shellArgument: preserveArgumentValue,
16
+ url: encodeURI,
17
+ };
18
+ return encoders[sink];
19
+ }
20
+ function escapeMarkdown(text) {
21
+ return text.replaceAll("```", "`\\`\\`");
22
+ }
23
+ function escapeHtmlText(text) {
24
+ return text
25
+ .replaceAll("&", "&amp;")
26
+ .replaceAll("<", "&lt;")
27
+ .replaceAll(">", "&gt;")
28
+ .replaceAll('"', "&quot;")
29
+ .replaceAll("'", "&#39;");
30
+ }
31
+ function normalizeLogLine(text) {
32
+ return text.replaceAll(/\r?\n/g, "\\n");
33
+ }
34
+ function wrapProviderData(text) {
35
+ return `<untrusted-data>${text}</untrusted-data>`;
36
+ }
37
+ function preserveArgumentValue(text) {
38
+ return text;
39
+ }
40
+ //# sourceMappingURL=sink-encoding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sink-encoding.js","sourceRoot":"","sources":["../../src/security/sink-encoding.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,aAAa,CAC3B,IAAY,EACZ,IAAgB;IAEhB,OAAO;QACL,IAAI;QACJ,KAAK,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;KAC/B,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,IAAgB;IACnC,MAAM,QAAQ,GAAG;QACf,QAAQ,EAAE,cAAc;QACxB,QAAQ,EAAE,cAAc;QACxB,IAAI,EAAE,IAAI,CAAC,SAAS;QACpB,GAAG,EAAE,gBAAgB;QACrB,QAAQ,EAAE,cAAc;QACxB,QAAQ,EAAE,gBAAgB;QAC1B,aAAa,EAAE,qBAAqB;QACpC,GAAG,EAAE,SAAS;KAC6C,CAAC;IAC9D,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,cAAc,CAAC,IAAY;IAClC,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,cAAc,CAAC,IAAY;IAClC,OAAO,IAAI;SACR,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC;SACxB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;SACvB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;SACvB,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC;SACzB,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY;IACpC,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY;IACpC,OAAO,mBAAmB,IAAI,mBAAmB,CAAC;AACpD,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC;AACd,CAAC"}