pi-harness-runtime 1.1.148 → 1.1.152

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 (158) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/harness/key-loader.ts +84 -0
  3. package/harness/langchain/agents.ts +65 -15
  4. package/harness/langchain/daemon.ts +58 -30
  5. package/harness/langchain/graph.ts +55 -7
  6. package/harness/langchain/jev-logger.ts +274 -0
  7. package/harness/langchain/run.ts +64 -161
  8. package/harness/langchain/surge.test.ts +42 -0
  9. package/harness/langchain/surge.ts +22 -1
  10. package/index.ts +65 -26
  11. package/package.json +1 -1
  12. package/packages/a2a-adapter/package.json +1 -1
  13. package/packages/agent-policy/dist/extension.d.ts +19 -0
  14. package/packages/agent-policy/dist/extension.d.ts.map +1 -0
  15. package/packages/agent-policy/dist/extension.js +322 -0
  16. package/packages/agent-policy/dist/extension.js.map +1 -0
  17. package/packages/agent-policy/dist/index.d.ts +25 -0
  18. package/packages/agent-policy/dist/index.d.ts.map +1 -0
  19. package/packages/agent-policy/dist/index.js +27 -0
  20. package/packages/agent-policy/dist/index.js.map +1 -0
  21. package/packages/agent-policy/dist/policy-loader.d.ts +90 -0
  22. package/packages/agent-policy/dist/policy-loader.d.ts.map +1 -0
  23. package/packages/agent-policy/dist/policy-loader.js +331 -0
  24. package/packages/agent-policy/dist/policy-loader.js.map +1 -0
  25. package/packages/agent-policy/dist/policy-renderer.d.ts +42 -0
  26. package/packages/agent-policy/dist/policy-renderer.d.ts.map +1 -0
  27. package/packages/agent-policy/dist/policy-renderer.js +295 -0
  28. package/packages/agent-policy/dist/policy-renderer.js.map +1 -0
  29. package/packages/agent-policy/dist/policy-store.d.ts +99 -0
  30. package/packages/agent-policy/dist/policy-store.d.ts.map +1 -0
  31. package/packages/agent-policy/dist/policy-store.js +244 -0
  32. package/packages/agent-policy/dist/policy-store.js.map +1 -0
  33. package/packages/agent-policy/dist/types.d.ts +237 -0
  34. package/packages/agent-policy/dist/types.d.ts.map +1 -0
  35. package/packages/agent-policy/dist/types.js +130 -0
  36. package/packages/agent-policy/dist/types.js.map +1 -0
  37. package/packages/agent-policy/package.json +45 -0
  38. package/packages/agent-policy/src/extension.ts +413 -0
  39. package/packages/agent-policy/src/index.ts +52 -0
  40. package/packages/agent-policy/src/policy-loader.ts +398 -0
  41. package/packages/agent-policy/src/policy-renderer.ts +362 -0
  42. package/packages/agent-policy/src/policy-store.ts +319 -0
  43. package/packages/agent-policy/src/types.ts +385 -0
  44. package/packages/agent-policy/test/policy.test.ts +383 -0
  45. package/packages/architecture-generator/package.json +1 -1
  46. package/packages/auth/package.json +1 -1
  47. package/packages/autonomous-refactor/package.json +1 -1
  48. package/packages/autonomous-runtime/package.json +1 -1
  49. package/packages/cache-strategy/package.json +1 -1
  50. package/packages/capability-registry/package.json +1 -1
  51. package/packages/checkpoint/package.json +1 -1
  52. package/packages/cli-plugin-sdk/package.json +1 -1
  53. package/packages/clipboard/package.json +1 -1
  54. package/packages/clipboard-plugin/package.json +1 -1
  55. package/packages/code-generation/package.json +1 -1
  56. package/packages/code-review/package.json +1 -1
  57. package/packages/codex-adapter/package.json +1 -1
  58. package/packages/codex-watcher/dist/src/parser.d.ts.map +1 -1
  59. package/packages/codex-watcher/dist/src/parser.js +35 -0
  60. package/packages/codex-watcher/dist/src/parser.js.map +1 -1
  61. package/packages/codex-watcher/package.json +1 -1
  62. package/packages/codex-watcher/src/parser.ts +41 -0
  63. package/packages/config-capture/package.json +1 -1
  64. package/packages/context-compiler/package.json +1 -1
  65. package/packages/context-discovery/package.json +1 -1
  66. package/packages/context-manager/package.json +1 -1
  67. package/packages/cookie-sanitizer/package.json +1 -1
  68. package/packages/cost-optimizer/package.json +1 -1
  69. package/packages/dependency-analyzer/package.json +1 -1
  70. package/packages/django-plugin/package.json +1 -1
  71. package/packages/doc-generator/package.json +1 -1
  72. package/packages/evaluation-engine/package.json +1 -1
  73. package/packages/evaluation-runner/package.json +1 -1
  74. package/packages/event-bus/package.json +1 -1
  75. package/packages/event-store/package.json +1 -1
  76. package/packages/experience-replay/package.json +1 -1
  77. package/packages/feedback-collector/package.json +1 -1
  78. package/packages/file-copy-helper/package.json +1 -1
  79. package/packages/framework-detector/package.json +1 -1
  80. package/packages/framework-plugin-sdk/package.json +1 -1
  81. package/packages/frappe-plugin/package.json +1 -1
  82. package/packages/generic-web-plugin/package.json +1 -1
  83. package/packages/health-monitor/package.json +1 -1
  84. package/packages/intent-analyzer/package.json +1 -1
  85. package/packages/jev-judge/package.json +1 -1
  86. package/packages/knowledge-graph/package.json +1 -1
  87. package/packages/knowledge-retrieval/package.json +1 -1
  88. package/packages/laravel-plugin/package.json +1 -1
  89. package/packages/learning-engine/package.json +1 -1
  90. package/packages/mcp-adapter/package.json +1 -1
  91. package/packages/memory-engine/package.json +1 -1
  92. package/packages/milestone-manager/package.json +1 -1
  93. package/packages/model-registry/package.json +1 -1
  94. package/packages/nextjs-plugin/package.json +1 -1
  95. package/packages/notification/dist/adapters/telegram-adapter.d.ts +5 -0
  96. package/packages/notification/dist/adapters/telegram-adapter.d.ts.map +1 -1
  97. package/packages/notification/dist/adapters/telegram-adapter.js +54 -0
  98. package/packages/notification/dist/adapters/telegram-adapter.js.map +1 -1
  99. package/packages/notification/dist/notification-center.d.ts +13 -0
  100. package/packages/notification/dist/notification-center.d.ts.map +1 -1
  101. package/packages/notification/dist/notification-center.js +36 -0
  102. package/packages/notification/dist/notification-center.js.map +1 -1
  103. package/packages/notification/package.json +1 -1
  104. package/packages/notification/src/adapters/telegram-adapter.ts +71 -0
  105. package/packages/notification/src/notification-center.ts +53 -0
  106. package/packages/observability/package.json +1 -1
  107. package/packages/okf-indexer/package.json +1 -1
  108. package/packages/paperclip-integration/package.json +1 -1
  109. package/packages/performance-optimizer/package.json +1 -1
  110. package/packages/privilege-broker/package.json +1 -1
  111. package/packages/project-analyzer/package.json +1 -1
  112. package/packages/project-bootstrap/package.json +1 -1
  113. package/packages/projection-engine/package.json +1 -1
  114. package/packages/prompt-compiler/package.json +1 -1
  115. package/packages/prompt-versioning/package.json +1 -1
  116. package/packages/provider-adapter-sdk/package.json +1 -1
  117. package/packages/provider-router/package.json +1 -1
  118. package/packages/provider-selector/package.json +1 -1
  119. package/packages/providers/package.json +1 -1
  120. package/packages/qdrant-skills/package.json +1 -1
  121. package/packages/quota-manager/package.json +1 -1
  122. package/packages/rate-limiter/package.json +1 -1
  123. package/packages/react-vite-plugin/package.json +1 -1
  124. package/packages/release-manager/package.json +1 -1
  125. package/packages/requirement-compiler/package.json +1 -1
  126. package/packages/runtime/package.json +1 -1
  127. package/packages/scheduler/package.json +1 -1
  128. package/packages/scheduler-adapter/package.json +1 -1
  129. package/packages/session/package.json +1 -1
  130. package/packages/session-api/package.json +1 -1
  131. package/packages/session-export/package.json +1 -1
  132. package/packages/shared-context/package.json +1 -1
  133. package/packages/skill-mcp-client/package.json +1 -1
  134. package/packages/skill-registry/package.json +1 -1
  135. package/packages/skills/package.json +1 -1
  136. package/packages/sprint-planner/package.json +1 -1
  137. package/packages/subscription-engine/package.json +1 -1
  138. package/packages/task-compiler/package.json +1 -1
  139. package/packages/tencentdb-memory/package.json +1 -1
  140. package/packages/tencentdb-sync/package.json +1 -1
  141. package/packages/test-data-generator/package.json +1 -1
  142. package/packages/test-generator/package.json +1 -1
  143. package/packages/todo-bd-sync/package.json +1 -1
  144. package/packages/token-estimation/package.json +1 -1
  145. package/packages/token-optimizer/package.json +1 -1
  146. package/packages/trajectory/package.json +1 -1
  147. package/packages/tui/package.json +1 -1
  148. package/packages/types/package.json +1 -1
  149. package/packages/workflow-events/package.json +1 -1
  150. package/packages/workspace-scanner/package.json +1 -1
  151. package/packages/worktree/package.json +1 -1
  152. package/packages/write-review/package.json +1 -1
  153. package/proactive-compact.ts +2 -2
  154. package/scripts/debug-codex-integration.ts +203 -0
  155. package/scripts/sync-keys-from-pi.ts +188 -0
  156. package/scripts/test-codex-session.ts +23 -0
  157. package/scripts/test-openai.ts +14 -0
  158. package/scripts/test-telegram.ts +34 -0
@@ -0,0 +1,295 @@
1
+ /**
2
+ * PolicyRenderer - Renders compact system contract for agent injection.
3
+ *
4
+ * Responsibilities:
5
+ * - Render a compact, deterministic contract for before_agent_start injection
6
+ * - Render full rule text for the harness_rules tool
7
+ * - Render policy status for display
8
+ */
9
+ import { readFileSync, existsSync } from "node:fs";
10
+ // ---------------------------------------------------------------------------
11
+ // System Contract Rendering
12
+ // ---------------------------------------------------------------------------
13
+ /**
14
+ * Render the compact mandatory contract for system prompt injection.
15
+ */
16
+ export function renderSystemContract(manifest) {
17
+ const lines = [];
18
+ // Header
19
+ lines.push(`PI-HARNESS POLICY revision=${manifest.revision} coverage=${manifest.coverage}`);
20
+ lines.push("");
21
+ // Mandatory rules
22
+ lines.push("Mandatory:");
23
+ lines.push("- Read and follow the active harness and scoped project rules.");
24
+ lines.push("- Before mutation, call harness_rules when the current revision is not loaded.");
25
+ lines.push("- Treat [BLOCKING] code findings as completion gates.");
26
+ lines.push("- Treat [DEGRADED] as incomplete evidence, never as clean.");
27
+ lines.push("- Re-read a file after the harness reports an automatic mutation.");
28
+ lines.push("");
29
+ // Tool reference
30
+ lines.push("Use harness_rules for full text and source attribution.");
31
+ lines.push("");
32
+ // Trust indicator
33
+ if (manifest.trust === "untrusted") {
34
+ lines.push("WARNING: Project is not trusted. Project rules are advisory only.");
35
+ lines.push("");
36
+ }
37
+ // Coverage warning
38
+ if (manifest.coverage !== "complete") {
39
+ lines.push(`WARNING: Policy coverage is ${manifest.coverage}. Some rules may be missing.`);
40
+ lines.push("");
41
+ }
42
+ return lines.join("\n");
43
+ }
44
+ // ---------------------------------------------------------------------------
45
+ // Rule Section Parsing
46
+ // ---------------------------------------------------------------------------
47
+ /**
48
+ * Parse markdown content into sections.
49
+ */
50
+ export function parseSections(content, source, scope, priority) {
51
+ const sections = [];
52
+ const lines = content.split("\n");
53
+ let currentSection = null;
54
+ let sectionIndex = 0;
55
+ for (let i = 0; i < lines.length; i++) {
56
+ const line = lines[i];
57
+ const lineOffset = content.split("\n").slice(0, i).join("\n").length;
58
+ // Check for markdown heading
59
+ const headingMatch = line.match(/^(#{1,6})\s+(.+)$/);
60
+ if (headingMatch) {
61
+ // Save previous section
62
+ if (currentSection) {
63
+ sections.push({
64
+ id: currentSection.id,
65
+ title: currentSection.title,
66
+ content: currentSection.content.join("\n").trim(),
67
+ source,
68
+ scope,
69
+ priority,
70
+ offset: currentSection.offset,
71
+ truncated: false,
72
+ });
73
+ }
74
+ // Start new section
75
+ const level = headingMatch[1].length;
76
+ const title = headingMatch[2].trim();
77
+ currentSection = {
78
+ id: `section-${sectionIndex++}`,
79
+ title,
80
+ content: [],
81
+ offset: lineOffset,
82
+ };
83
+ }
84
+ else if (currentSection) {
85
+ currentSection.content.push(line);
86
+ }
87
+ }
88
+ // Save last section
89
+ if (currentSection) {
90
+ sections.push({
91
+ id: currentSection.id,
92
+ title: currentSection.title,
93
+ content: currentSection.content.join("\n").trim(),
94
+ source,
95
+ scope,
96
+ priority,
97
+ offset: currentSection.offset,
98
+ truncated: false,
99
+ });
100
+ }
101
+ // If no sections found, create a single section with the whole content
102
+ if (sections.length === 0) {
103
+ sections.push({
104
+ id: "section-0",
105
+ title: "Full Content",
106
+ content: content.trim(),
107
+ source,
108
+ scope,
109
+ priority,
110
+ offset: 0,
111
+ truncated: false,
112
+ });
113
+ }
114
+ return sections;
115
+ }
116
+ // ---------------------------------------------------------------------------
117
+ // Full Rules Rendering
118
+ // ---------------------------------------------------------------------------
119
+ /**
120
+ * Render full rules for the harness_rules tool.
121
+ */
122
+ export function renderFullRules(manifest, options = {}) {
123
+ const sections = [];
124
+ const maxBytes = options.maxBytes ?? 50 * 1024; // Default 50KB cap
125
+ // Filter sources
126
+ let sources = manifest.sources;
127
+ if (options.source) {
128
+ sources = sources.filter(s => s.path.includes(options.source));
129
+ }
130
+ // Parse sections from each source
131
+ for (const source of sources) {
132
+ const content = readSourceContent(source.path);
133
+ if (!content)
134
+ continue;
135
+ const sourceSections = parseSections(content, source.path, source.scope, source.priority);
136
+ // Filter by section if requested
137
+ const filteredSections = options.section
138
+ ? sourceSections.filter(s => s.title.toLowerCase().includes(options.section.toLowerCase()) ||
139
+ s.id === options.section)
140
+ : sourceSections;
141
+ sections.push(...filteredSections);
142
+ }
143
+ // Truncate if needed
144
+ let totalBytes = 0;
145
+ let truncated = false;
146
+ const truncatedSections = [];
147
+ for (const section of sections) {
148
+ const sectionBytes = Buffer.byteLength(section.content, "utf8");
149
+ if (totalBytes + sectionBytes > maxBytes) {
150
+ // Check if we can fit a partial section
151
+ const remainingBytes = maxBytes - totalBytes;
152
+ if (remainingBytes > 100) {
153
+ // Fit as much as possible
154
+ truncatedSections.push({
155
+ ...section,
156
+ content: section.content.slice(0, remainingBytes),
157
+ truncated: true,
158
+ });
159
+ }
160
+ truncated = true;
161
+ break;
162
+ }
163
+ truncatedSections.push(section);
164
+ totalBytes += sectionBytes;
165
+ }
166
+ return {
167
+ sections: truncatedSections,
168
+ };
169
+ }
170
+ /**
171
+ * Render a manifest summary.
172
+ */
173
+ export function renderManifestSummary(manifest) {
174
+ const lines = [];
175
+ lines.push(`Policy Manifest`);
176
+ lines.push(`================`);
177
+ lines.push(`Revision: ${manifest.revision}`);
178
+ lines.push(`Project: ${manifest.projectRoot}`);
179
+ lines.push(`Trust: ${manifest.trust}`);
180
+ lines.push(`Coverage: ${manifest.coverage}`);
181
+ lines.push(`Loaded: ${new Date(manifest.loadedAt).toISOString()}`);
182
+ lines.push("");
183
+ lines.push("Sources:");
184
+ for (const source of manifest.sources) {
185
+ const scope = source.scope || "(root)";
186
+ const priority = source.priority;
187
+ const owner = source.harnessOwned ? "[harness]" : "[project]";
188
+ lines.push(` ${owner} ${scope} ${priority} ${source.path}`);
189
+ }
190
+ if (manifest.loadError) {
191
+ lines.push("");
192
+ lines.push(`ERROR: ${manifest.loadError}`);
193
+ }
194
+ return lines.join("\n");
195
+ }
196
+ // ---------------------------------------------------------------------------
197
+ // Finding Envelope Rendering
198
+ // ---------------------------------------------------------------------------
199
+ /**
200
+ * Render a finding envelope for display.
201
+ */
202
+ export function renderFindingEnvelope(envelope) {
203
+ const lines = [];
204
+ // Header with verdict
205
+ const verdictPrefix = {
206
+ blocking: "[BLOCKING]",
207
+ advisory: "[ADVISORY]",
208
+ clean: "[CLEAN]",
209
+ degraded: "[DEGRADED]",
210
+ }[envelope.verdict];
211
+ lines.push(`${verdictPrefix} Code Analysis (${envelope.coverage} coverage, ${envelope.freshness})`);
212
+ lines.push("");
213
+ // Summary
214
+ if (envelope.summary) {
215
+ lines.push(envelope.summary);
216
+ lines.push("");
217
+ }
218
+ // Individual findings
219
+ if (envelope.findings.length > 0) {
220
+ for (const finding of envelope.findings) {
221
+ const severity = {
222
+ error: "ERROR",
223
+ warning: "WARN",
224
+ information: "INFO",
225
+ hint: "HINT",
226
+ }[finding.severity];
227
+ const location = finding.line ? `${finding.path}:${finding.line}` : finding.path;
228
+ const blocking = finding.blocking ? " [BLOCKING]" : "";
229
+ lines.push(`${severity} ${location}: ${finding.message}${blocking}`);
230
+ if (finding.fix) {
231
+ lines.push(` Fix: ${finding.fix}`);
232
+ }
233
+ }
234
+ lines.push("");
235
+ }
236
+ // Next action
237
+ if (envelope.nextAction) {
238
+ const actionText = {
239
+ fix: "Required: fix these issues before reporting completion.",
240
+ reread: "Required: re-read affected files to get updated analysis.",
241
+ run_full: "Required: do not report the project clean; run a full analysis.",
242
+ continue: "No blocking issues found.",
243
+ }[envelope.nextAction];
244
+ lines.push(actionText);
245
+ }
246
+ return lines.join("\n");
247
+ }
248
+ /**
249
+ * Create a clean finding envelope.
250
+ */
251
+ export function createCleanEnvelope(coverage = "full") {
252
+ return {
253
+ verdict: "clean",
254
+ coverage,
255
+ freshness: "fresh",
256
+ findings: [],
257
+ nextAction: "continue",
258
+ summary: "No blocking issues found in code analysis.",
259
+ };
260
+ }
261
+ /**
262
+ * Create a degraded finding envelope.
263
+ */
264
+ export function createDegradedEnvelope(reason, coverage = "delta") {
265
+ return {
266
+ verdict: "degraded",
267
+ coverage,
268
+ freshness: "indeterminate",
269
+ findings: [],
270
+ nextAction: "run_full",
271
+ summary: `Analysis degraded: ${reason}. Do not claim the project is clean.`,
272
+ };
273
+ }
274
+ // ---------------------------------------------------------------------------
275
+ // Helpers
276
+ // ---------------------------------------------------------------------------
277
+ /**
278
+ * Read source content from a path.
279
+ */
280
+ function readSourceContent(path) {
281
+ // Handle file:// URLs
282
+ const normalizedPath = path.startsWith("file://")
283
+ ? path.slice(7)
284
+ : path;
285
+ if (existsSync(normalizedPath)) {
286
+ try {
287
+ return readFileSync(normalizedPath, "utf8");
288
+ }
289
+ catch {
290
+ return null;
291
+ }
292
+ }
293
+ return null;
294
+ }
295
+ //# sourceMappingURL=policy-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-renderer.js","sourceRoot":"","sources":["../src/policy-renderer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * PolicyStore - Session receipt tracking and validation.
3
+ *
4
+ * Responsibilities:
5
+ * - Record when a policy revision was delivered to a session
6
+ * - Validate receipts against current manifest
7
+ * - Invalidate receipts when rules change
8
+ * - Track delivery method (system_prompt vs tool)
9
+ */
10
+ import type { PolicyManifest, PolicyReceipt } from "./types.js";
11
+ /**
12
+ * Policy store configuration.
13
+ */
14
+ export interface PolicyStoreConfig {
15
+ /** Maximum receipts to keep per session (prevents memory leaks) */
16
+ maxReceiptsPerSession?: number;
17
+ /** Receipt TTL in milliseconds (default: 24 hours) */
18
+ receiptTtlMs?: number;
19
+ }
20
+ /**
21
+ * Stores policy receipts and validates delivery.
22
+ */
23
+ export declare class PolicyStore {
24
+ private receipts;
25
+ private sessionScopes;
26
+ private lastKnownManifests;
27
+ private config;
28
+ constructor(config?: PolicyStoreConfig);
29
+ /**
30
+ * Record a policy delivery for a session.
31
+ */
32
+ noteDelivered(sessionId: string, manifest: PolicyManifest, deliveryMethod?: "system_prompt" | "tool", sectionsDelivered?: string[]): PolicyReceipt;
33
+ /**
34
+ * Get receipt for a session, if it exists.
35
+ */
36
+ getReceipt(sessionId: string, projectRoot?: string, scope?: string): PolicyReceipt | null;
37
+ /**
38
+ * Check if a session has a valid receipt for the given manifest.
39
+ */
40
+ hasValidReceipt(sessionId: string, manifest: PolicyManifest): boolean;
41
+ /**
42
+ * Validate a receipt against the current manifest.
43
+ */
44
+ validateReceipt(sessionId: string, manifest: PolicyManifest): {
45
+ valid: boolean;
46
+ reason?: string;
47
+ };
48
+ /**
49
+ * Invalidate receipts when a rule file changes.
50
+ */
51
+ invalidateOnChange(changedPath: string): string[];
52
+ /**
53
+ * Invalidate all receipts for a project root.
54
+ */
55
+ invalidateProject(projectRoot: string): void;
56
+ /**
57
+ * Invalidate all receipts (e.g., after compaction).
58
+ */
59
+ invalidateAll(): void;
60
+ /**
61
+ * Clear receipts for a specific session.
62
+ */
63
+ clearSession(sessionId: string): void;
64
+ /**
65
+ * Get all receipts for a session.
66
+ */
67
+ getSessionReceipts(sessionId: string): PolicyReceipt[];
68
+ /**
69
+ * Get statistics about stored receipts.
70
+ */
71
+ getStats(): {
72
+ totalReceipts: number;
73
+ sessionsTracked: number;
74
+ projectsTracked: number;
75
+ oldestReceipt: number | null;
76
+ newestReceipt: number | null;
77
+ };
78
+ /**
79
+ * Generate receipt key for storage.
80
+ */
81
+ private getReceiptKey;
82
+ /**
83
+ * Extract scope from manifest.
84
+ */
85
+ private getScopeFromManifest;
86
+ /**
87
+ * Cleanup old receipts to prevent memory leaks.
88
+ */
89
+ private cleanupOldReceipts;
90
+ }
91
+ /**
92
+ * Get the global policy store instance.
93
+ */
94
+ export declare function getPolicyStore(): PolicyStore;
95
+ /**
96
+ * Reset the global policy store (for testing).
97
+ */
98
+ export declare function resetPolicyStore(): void;
99
+ //# sourceMappingURL=policy-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-store.d.ts","sourceRoot":"","sources":["../src/policy-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAMhE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,mEAAmE;IACnE,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAyC;IACzD,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,kBAAkB,CAA0C;IACpE,OAAO,CAAC,MAAM,CAA8B;IAE5C,YAAY,MAAM,GAAE,iBAAsB,EAKzC;IAED;;OAEG;IACH,aAAa,CACX,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,cAAc,EACxB,cAAc,GAAE,eAAe,GAAG,MAAwB,EAC1D,iBAAiB,GAAE,MAAM,EAAU,GAClC,aAAa,CA8Bf;IAED;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAaxF;IAED;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAkBpE;IAED;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG;QAC5D,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAmBA;IAED;;OAEG;IACH,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAkBhD;IAED;;OAEG;IACH,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAa3C;IAED;;OAEG;IACH,aAAa,IAAI,IAAI,CAGpB;IAED;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAOpC;IAED;;OAEG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,EAAE,CAQrD;IAED;;OAEG;IACH,QAAQ,IAAI;QACV,aAAa,EAAE,MAAM,CAAC;QACtB,eAAe,EAAE,MAAM,CAAC;QACxB,eAAe,EAAE,MAAM,CAAC;QACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;KAC9B,CAsBA;IAED;;OAEG;IACH,OAAO,CAAC,aAAa;IAIrB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAS5B;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAgB3B;AAQD;;GAEG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAK5C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC"}
@@ -0,0 +1,244 @@
1
+ /**
2
+ * PolicyStore - Session receipt tracking and validation.
3
+ *
4
+ * Responsibilities:
5
+ * - Record when a policy revision was delivered to a session
6
+ * - Validate receipts against current manifest
7
+ * - Invalidate receipts when rules change
8
+ * - Track delivery method (system_prompt vs tool)
9
+ */
10
+ /**
11
+ * Stores policy receipts and validates delivery.
12
+ */
13
+ export class PolicyStore {
14
+ receipts = new Map();
15
+ sessionScopes = new Map();
16
+ lastKnownManifests = new Map();
17
+ config;
18
+ constructor(config = {}) {
19
+ this.config = {
20
+ maxReceiptsPerSession: config.maxReceiptsPerSession ?? 100,
21
+ receiptTtlMs: config.receiptTtlMs ?? 24 * 60 * 60 * 1000, // 24 hours
22
+ };
23
+ }
24
+ /**
25
+ * Record a policy delivery for a session.
26
+ */
27
+ noteDelivered(sessionId, manifest, deliveryMethod = "system_prompt", sectionsDelivered = ["*"]) {
28
+ // Invalidate any existing receipt for this session+scope
29
+ const existingKey = this.getReceiptKey(sessionId, manifest.projectRoot, "");
30
+ this.receipts.delete(existingKey);
31
+ const receipt = {
32
+ sessionId,
33
+ projectRoot: manifest.projectRoot,
34
+ revision: manifest.revision,
35
+ scope: this.getScopeFromManifest(manifest),
36
+ deliveredAt: Date.now(),
37
+ sectionsDelivered,
38
+ deliveryMethod,
39
+ };
40
+ this.receipts.set(existingKey, receipt);
41
+ // Track scope for this session
42
+ if (!this.sessionScopes.has(sessionId)) {
43
+ this.sessionScopes.set(sessionId, new Set());
44
+ }
45
+ this.sessionScopes.get(sessionId).add(manifest.projectRoot);
46
+ // Store manifest for later validation
47
+ this.lastKnownManifests.set(existingKey, manifest);
48
+ // Cleanup old receipts if needed
49
+ this.cleanupOldReceipts();
50
+ return receipt;
51
+ }
52
+ /**
53
+ * Get receipt for a session, if it exists.
54
+ */
55
+ getReceipt(sessionId, projectRoot, scope) {
56
+ const key = this.getReceiptKey(sessionId, projectRoot ?? "", scope ?? "");
57
+ const receipt = this.receipts.get(key);
58
+ if (!receipt)
59
+ return null;
60
+ // Check TTL
61
+ if (Date.now() - receipt.deliveredAt > this.config.receiptTtlMs) {
62
+ this.receipts.delete(key);
63
+ return null;
64
+ }
65
+ return receipt;
66
+ }
67
+ /**
68
+ * Check if a session has a valid receipt for the given manifest.
69
+ */
70
+ hasValidReceipt(sessionId, manifest) {
71
+ const receipt = this.getReceipt(sessionId, manifest.projectRoot);
72
+ if (!receipt)
73
+ return false;
74
+ // Check revision match
75
+ if (receipt.revision !== manifest.revision) {
76
+ return false;
77
+ }
78
+ // Check scope coverage
79
+ const receiptScope = receipt.scope;
80
+ const manifestScope = this.getScopeFromManifest(manifest);
81
+ if (receiptScope && manifestScope && !receiptScope.startsWith(manifestScope)) {
82
+ return false;
83
+ }
84
+ return true;
85
+ }
86
+ /**
87
+ * Validate a receipt against the current manifest.
88
+ */
89
+ validateReceipt(sessionId, manifest) {
90
+ const receipt = this.getReceipt(sessionId, manifest.projectRoot);
91
+ if (!receipt) {
92
+ return { valid: false, reason: "No receipt found for this session" };
93
+ }
94
+ if (receipt.revision !== manifest.revision) {
95
+ return {
96
+ valid: false,
97
+ reason: `Receipt revision ${receipt.revision} does not match current ${manifest.revision}`,
98
+ };
99
+ }
100
+ if (Date.now() - receipt.deliveredAt > this.config.receiptTtlMs) {
101
+ return { valid: false, reason: "Receipt has expired" };
102
+ }
103
+ return { valid: true };
104
+ }
105
+ /**
106
+ * Invalidate receipts when a rule file changes.
107
+ */
108
+ invalidateOnChange(changedPath) {
109
+ const invalidatedSessions = [];
110
+ for (const [key, manifest] of this.lastKnownManifests) {
111
+ // Check if the changed path affects any of our sources
112
+ const affectedSource = manifest.sources.find(s => s.path === changedPath || s.path.includes(changedPath));
113
+ if (affectedSource) {
114
+ // Extract session ID from key
115
+ const sessionId = key.split("|")[0];
116
+ this.receipts.delete(key);
117
+ invalidatedSessions.push(sessionId);
118
+ }
119
+ }
120
+ return invalidatedSessions;
121
+ }
122
+ /**
123
+ * Invalidate all receipts for a project root.
124
+ */
125
+ invalidateProject(projectRoot) {
126
+ for (const [key, receipt] of this.receipts) {
127
+ if (receipt.projectRoot === projectRoot) {
128
+ this.receipts.delete(key);
129
+ }
130
+ }
131
+ // Also clean up last known manifests for this project
132
+ for (const [key, manifest] of this.lastKnownManifests) {
133
+ if (manifest.projectRoot === projectRoot) {
134
+ this.lastKnownManifests.delete(key);
135
+ }
136
+ }
137
+ }
138
+ /**
139
+ * Invalidate all receipts (e.g., after compaction).
140
+ */
141
+ invalidateAll() {
142
+ this.receipts.clear();
143
+ this.sessionScopes.clear();
144
+ }
145
+ /**
146
+ * Clear receipts for a specific session.
147
+ */
148
+ clearSession(sessionId) {
149
+ for (const [key, receipt] of this.receipts) {
150
+ if (receipt.sessionId === sessionId) {
151
+ this.receipts.delete(key);
152
+ }
153
+ }
154
+ this.sessionScopes.delete(sessionId);
155
+ }
156
+ /**
157
+ * Get all receipts for a session.
158
+ */
159
+ getSessionReceipts(sessionId) {
160
+ const receipts = [];
161
+ for (const receipt of this.receipts.values()) {
162
+ if (receipt.sessionId === sessionId) {
163
+ receipts.push(receipt);
164
+ }
165
+ }
166
+ return receipts;
167
+ }
168
+ /**
169
+ * Get statistics about stored receipts.
170
+ */
171
+ getStats() {
172
+ let oldest = null;
173
+ let newest = null;
174
+ const projects = new Set();
175
+ for (const receipt of this.receipts.values()) {
176
+ if (oldest === null || receipt.deliveredAt < oldest) {
177
+ oldest = receipt.deliveredAt;
178
+ }
179
+ if (newest === null || receipt.deliveredAt > newest) {
180
+ newest = receipt.deliveredAt;
181
+ }
182
+ projects.add(receipt.projectRoot);
183
+ }
184
+ return {
185
+ totalReceipts: this.receipts.size,
186
+ sessionsTracked: this.sessionScopes.size,
187
+ projectsTracked: projects.size,
188
+ oldestReceipt: oldest,
189
+ newestReceipt: newest,
190
+ };
191
+ }
192
+ /**
193
+ * Generate receipt key for storage.
194
+ */
195
+ getReceiptKey(sessionId, projectRoot, scope) {
196
+ return `${sessionId}|${projectRoot}|${scope}`;
197
+ }
198
+ /**
199
+ * Extract scope from manifest.
200
+ */
201
+ getScopeFromManifest(manifest) {
202
+ const mandatorySources = manifest.sources.filter(s => s.priority === "mandatory");
203
+ if (mandatorySources.length === 0)
204
+ return "";
205
+ // Get the most specific (longest) scope
206
+ mandatorySources.sort((a, b) => b.scope.length - a.scope.length);
207
+ return mandatorySources[0]?.scope ?? "";
208
+ }
209
+ /**
210
+ * Cleanup old receipts to prevent memory leaks.
211
+ */
212
+ cleanupOldReceipts() {
213
+ if (this.receipts.size <= this.config.maxReceiptsPerSession) {
214
+ return;
215
+ }
216
+ // Sort by delivery time, oldest first
217
+ const sorted = [...this.receipts.entries()].sort((a, b) => a[1].deliveredAt - b[1].deliveredAt);
218
+ // Remove oldest entries until under limit
219
+ const toRemove = sorted.slice(0, sorted.length - this.config.maxReceiptsPerSession);
220
+ for (const [key] of toRemove) {
221
+ this.receipts.delete(key);
222
+ }
223
+ }
224
+ }
225
+ // ---------------------------------------------------------------------------
226
+ // Singleton instance (for use in extension)
227
+ // ---------------------------------------------------------------------------
228
+ let globalPolicyStore = null;
229
+ /**
230
+ * Get the global policy store instance.
231
+ */
232
+ export function getPolicyStore() {
233
+ if (!globalPolicyStore) {
234
+ globalPolicyStore = new PolicyStore();
235
+ }
236
+ return globalPolicyStore;
237
+ }
238
+ /**
239
+ * Reset the global policy store (for testing).
240
+ */
241
+ export function resetPolicyStore() {
242
+ globalPolicyStore = null;
243
+ }
244
+ //# sourceMappingURL=policy-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-store.js","sourceRoot":"","sources":["../src/policy-store.ts"],"names":[],"mappings":"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"}