instar 0.9.11 → 0.9.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/commands/init.d.ts.map +1 -1
  2. package/dist/commands/init.js +78 -0
  3. package/dist/commands/init.js.map +1 -1
  4. package/dist/commands/server.d.ts.map +1 -1
  5. package/dist/commands/server.js +86 -7
  6. package/dist/commands/server.js.map +1 -1
  7. package/dist/core/CanonicalState.d.ts +132 -0
  8. package/dist/core/CanonicalState.d.ts.map +1 -0
  9. package/dist/core/CanonicalState.js +297 -0
  10. package/dist/core/CanonicalState.js.map +1 -0
  11. package/dist/core/CoherenceGate.d.ts +122 -0
  12. package/dist/core/CoherenceGate.d.ts.map +1 -0
  13. package/dist/core/CoherenceGate.js +347 -0
  14. package/dist/core/CoherenceGate.js.map +1 -0
  15. package/dist/core/ContextHierarchy.d.ts +100 -0
  16. package/dist/core/ContextHierarchy.d.ts.map +1 -0
  17. package/dist/core/ContextHierarchy.js +454 -0
  18. package/dist/core/ContextHierarchy.js.map +1 -0
  19. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  20. package/dist/core/PostUpdateMigrator.js +140 -0
  21. package/dist/core/PostUpdateMigrator.js.map +1 -1
  22. package/dist/core/ProjectMapper.d.ts +97 -0
  23. package/dist/core/ProjectMapper.d.ts.map +1 -0
  24. package/dist/core/ProjectMapper.js +364 -0
  25. package/dist/core/ProjectMapper.js.map +1 -0
  26. package/dist/index.d.ts +8 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +4 -0
  29. package/dist/index.js.map +1 -1
  30. package/dist/messaging/TelegramAdapter.d.ts +5 -0
  31. package/dist/messaging/TelegramAdapter.d.ts.map +1 -1
  32. package/dist/messaging/TelegramAdapter.js +7 -0
  33. package/dist/messaging/TelegramAdapter.js.map +1 -1
  34. package/dist/monitoring/StallTriageNurse.d.ts.map +1 -1
  35. package/dist/monitoring/StallTriageNurse.js +77 -13
  36. package/dist/monitoring/StallTriageNurse.js.map +1 -1
  37. package/dist/scaffold/templates.d.ts.map +1 -1
  38. package/dist/scaffold/templates.js +10 -0
  39. package/dist/scaffold/templates.js.map +1 -1
  40. package/dist/scheduler/JobLoader.d.ts.map +1 -1
  41. package/dist/scheduler/JobLoader.js +1 -0
  42. package/dist/scheduler/JobLoader.js.map +1 -1
  43. package/dist/server/AgentServer.d.ts +4 -0
  44. package/dist/server/AgentServer.d.ts.map +1 -1
  45. package/dist/server/AgentServer.js +4 -0
  46. package/dist/server/AgentServer.js.map +1 -1
  47. package/dist/server/routes.d.ts +8 -0
  48. package/dist/server/routes.d.ts.map +1 -1
  49. package/dist/server/routes.js +228 -0
  50. package/dist/server/routes.js.map +1 -1
  51. package/package.json +1 -1
  52. package/upgrades/0.9.12.md +42 -0
  53. package/upgrades/0.9.13.md +55 -0
@@ -0,0 +1,297 @@
1
+ /**
2
+ * Canonical State — Registry-first state management for agents.
3
+ *
4
+ * Inspired by Dawn's 223rd Lesson: "For ANY question about current state,
5
+ * check the canonical state file BEFORE dispatching broad searches."
6
+ *
7
+ * Three canonical registries every agent maintains:
8
+ * 1. quick-facts.json — Fast answers to common questions
9
+ * 2. anti-patterns.json — Things NOT to do (learned from mistakes)
10
+ * 3. project-registry.json — All projects this agent knows about
11
+ *
12
+ * These are the "one file designed to answer the question" pattern.
13
+ * Agents check these FIRST, then explore only if the answer isn't there.
14
+ *
15
+ * Born from the Luna incident (2026-02-25): The agent had no fast way
16
+ * to answer "what project is this topic for?" — it had to search broadly
17
+ * through config and session history, and got it wrong.
18
+ */
19
+ import fs from 'node:fs';
20
+ import path from 'node:path';
21
+ export class CanonicalState {
22
+ stateDir;
23
+ constructor(config) {
24
+ this.stateDir = config.stateDir;
25
+ }
26
+ // ── Quick Facts ─────────────────────────────────────────────────
27
+ /**
28
+ * Get all quick facts.
29
+ */
30
+ getQuickFacts() {
31
+ return this.loadJson('quick-facts.json', []);
32
+ }
33
+ /**
34
+ * Find a quick fact by searching question text.
35
+ */
36
+ findFact(query) {
37
+ const facts = this.getQuickFacts();
38
+ const lower = query.toLowerCase();
39
+ return facts.find(f => f.question.toLowerCase().includes(lower) ||
40
+ f.answer.toLowerCase().includes(lower)) ?? null;
41
+ }
42
+ /**
43
+ * Add or update a quick fact.
44
+ */
45
+ setFact(question, answer, source) {
46
+ const facts = this.getQuickFacts();
47
+ const existing = facts.findIndex(f => f.question === question);
48
+ const fact = {
49
+ question,
50
+ answer,
51
+ lastVerified: new Date().toISOString(),
52
+ source,
53
+ };
54
+ if (existing >= 0) {
55
+ facts[existing] = fact;
56
+ }
57
+ else {
58
+ facts.push(fact);
59
+ }
60
+ this.saveJson('quick-facts.json', facts);
61
+ }
62
+ /**
63
+ * Remove a quick fact by question text.
64
+ */
65
+ removeFact(question) {
66
+ const facts = this.getQuickFacts();
67
+ const filtered = facts.filter(f => f.question !== question);
68
+ if (filtered.length === facts.length)
69
+ return false;
70
+ this.saveJson('quick-facts.json', filtered);
71
+ return true;
72
+ }
73
+ // ── Anti-Patterns ───────────────────────────────────────────────
74
+ /**
75
+ * Get all anti-patterns.
76
+ */
77
+ getAntiPatterns() {
78
+ return this.loadJson('anti-patterns.json', []);
79
+ }
80
+ /**
81
+ * Add a new anti-pattern.
82
+ */
83
+ addAntiPattern(pattern) {
84
+ const patterns = this.getAntiPatterns();
85
+ const id = `AP-${String(patterns.length + 1).padStart(3, '0')}`;
86
+ const entry = {
87
+ ...pattern,
88
+ id,
89
+ learnedAt: new Date().toISOString(),
90
+ };
91
+ patterns.push(entry);
92
+ this.saveJson('anti-patterns.json', patterns);
93
+ return entry;
94
+ }
95
+ /**
96
+ * Search anti-patterns for relevant warnings.
97
+ */
98
+ findAntiPatterns(query) {
99
+ const patterns = this.getAntiPatterns();
100
+ const lower = query.toLowerCase();
101
+ return patterns.filter(p => p.pattern.toLowerCase().includes(lower) ||
102
+ p.consequence.toLowerCase().includes(lower) ||
103
+ p.alternative.toLowerCase().includes(lower));
104
+ }
105
+ // ── Project Registry ────────────────────────────────────────────
106
+ /**
107
+ * Get all registered projects.
108
+ */
109
+ getProjects() {
110
+ return this.loadJson('project-registry.json', []);
111
+ }
112
+ /**
113
+ * Find a project by name, directory, or topic ID.
114
+ */
115
+ findProject(query) {
116
+ const projects = this.getProjects();
117
+ if (query.topicId) {
118
+ const byTopic = projects.find(p => p.topicIds?.includes(query.topicId));
119
+ if (byTopic)
120
+ return byTopic;
121
+ }
122
+ if (query.name) {
123
+ const byName = projects.find(p => p.name.toLowerCase() === query.name.toLowerCase());
124
+ if (byName)
125
+ return byName;
126
+ }
127
+ if (query.dir) {
128
+ const byDir = projects.find(p => p.dir === query.dir);
129
+ if (byDir)
130
+ return byDir;
131
+ }
132
+ return null;
133
+ }
134
+ /**
135
+ * Register or update a project.
136
+ */
137
+ setProject(project) {
138
+ const projects = this.getProjects();
139
+ const existing = projects.findIndex(p => p.name === project.name);
140
+ const entry = {
141
+ ...project,
142
+ lastVerified: new Date().toISOString(),
143
+ };
144
+ if (existing >= 0) {
145
+ projects[existing] = entry;
146
+ }
147
+ else {
148
+ projects.push(entry);
149
+ }
150
+ this.saveJson('project-registry.json', projects);
151
+ }
152
+ /**
153
+ * Bind a topic ID to a project.
154
+ */
155
+ bindTopicToProject(topicId, projectName) {
156
+ const projects = this.getProjects();
157
+ const project = projects.find(p => p.name === projectName);
158
+ if (!project)
159
+ return false;
160
+ if (!project.topicIds)
161
+ project.topicIds = [];
162
+ if (!project.topicIds.includes(topicId)) {
163
+ project.topicIds.push(topicId);
164
+ }
165
+ this.saveJson('project-registry.json', projects);
166
+ return true;
167
+ }
168
+ // ── Initialization ──────────────────────────────────────────────
169
+ /**
170
+ * Initialize canonical state files with sensible defaults.
171
+ * Only creates files that don't exist (additive only).
172
+ */
173
+ initialize(projectName, projectDir) {
174
+ const created = [];
175
+ const skipped = [];
176
+ // Quick facts
177
+ if (!this.fileExists('quick-facts.json')) {
178
+ this.saveJson('quick-facts.json', [
179
+ {
180
+ question: 'What project am I working on?',
181
+ answer: `${projectName} at ${projectDir}`,
182
+ lastVerified: new Date().toISOString(),
183
+ source: 'instar init',
184
+ },
185
+ ]);
186
+ created.push('quick-facts.json');
187
+ }
188
+ else {
189
+ skipped.push('quick-facts.json');
190
+ }
191
+ // Anti-patterns
192
+ if (!this.fileExists('anti-patterns.json')) {
193
+ this.saveJson('anti-patterns.json', [
194
+ {
195
+ id: 'AP-001',
196
+ pattern: 'Deploying without verifying the target project matches the current topic',
197
+ consequence: 'Deploy to wrong production environment (Luna incident)',
198
+ alternative: 'Always run POST /coherence/check before deploying. Verify topic-project binding.',
199
+ learnedAt: new Date().toISOString(),
200
+ incident: 'Luna deployed SageMind code to Dental City topic',
201
+ },
202
+ {
203
+ id: 'AP-002',
204
+ pattern: 'Saying "I can\'t" without checking /capabilities first',
205
+ consequence: 'Missed opportunity to use existing infrastructure',
206
+ alternative: 'Check GET /capabilities before claiming any limitation.',
207
+ learnedAt: new Date().toISOString(),
208
+ },
209
+ {
210
+ id: 'AP-003',
211
+ pattern: 'Presenting a menu of next steps instead of doing them',
212
+ consequence: 'Forces user to project-manage the agent',
213
+ alternative: 'Do the obvious next steps. Only ask when genuinely ambiguous.',
214
+ learnedAt: new Date().toISOString(),
215
+ },
216
+ ]);
217
+ created.push('anti-patterns.json');
218
+ }
219
+ else {
220
+ skipped.push('anti-patterns.json');
221
+ }
222
+ // Project registry
223
+ if (!this.fileExists('project-registry.json')) {
224
+ this.saveJson('project-registry.json', [
225
+ {
226
+ name: projectName,
227
+ dir: projectDir,
228
+ lastVerified: new Date().toISOString(),
229
+ description: 'Primary project for this agent',
230
+ },
231
+ ]);
232
+ created.push('project-registry.json');
233
+ }
234
+ else {
235
+ skipped.push('project-registry.json');
236
+ }
237
+ return { created, skipped };
238
+ }
239
+ /**
240
+ * Generate a compact summary of canonical state for session injection.
241
+ */
242
+ getCompactSummary() {
243
+ const facts = this.getQuickFacts();
244
+ const patterns = this.getAntiPatterns();
245
+ const projects = this.getProjects();
246
+ const lines = [];
247
+ if (facts.length > 0) {
248
+ lines.push('Quick Facts:');
249
+ for (const f of facts.slice(0, 5)) {
250
+ lines.push(` Q: ${f.question}`);
251
+ lines.push(` A: ${f.answer}`);
252
+ }
253
+ if (facts.length > 5) {
254
+ lines.push(` ... and ${facts.length - 5} more (GET /state/quick-facts)`);
255
+ }
256
+ }
257
+ if (patterns.length > 0) {
258
+ lines.push('');
259
+ lines.push('Anti-Patterns (things NOT to do):');
260
+ for (const p of patterns.slice(0, 3)) {
261
+ lines.push(` - ${p.pattern}`);
262
+ }
263
+ if (patterns.length > 3) {
264
+ lines.push(` ... and ${patterns.length - 3} more (GET /state/anti-patterns)`);
265
+ }
266
+ }
267
+ if (projects.length > 1) {
268
+ lines.push('');
269
+ lines.push('Known Projects:');
270
+ for (const p of projects) {
271
+ const topics = p.topicIds?.length ? ` (topics: ${p.topicIds.join(', ')})` : '';
272
+ lines.push(` - ${p.name}: ${p.dir}${topics}`);
273
+ }
274
+ }
275
+ return lines.join('\n');
276
+ }
277
+ // ── Helpers ─────────────────────────────────────────────────────
278
+ loadJson(filename, defaultValue) {
279
+ const filePath = path.join(this.stateDir, filename);
280
+ try {
281
+ if (fs.existsSync(filePath)) {
282
+ return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
283
+ }
284
+ }
285
+ catch { /* corrupt file */ }
286
+ return defaultValue;
287
+ }
288
+ saveJson(filename, data) {
289
+ const filePath = path.join(this.stateDir, filename);
290
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
291
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
292
+ }
293
+ fileExists(filename) {
294
+ return fs.existsSync(path.join(this.stateDir, filename));
295
+ }
296
+ }
297
+ //# sourceMappingURL=CanonicalState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CanonicalState.js","sourceRoot":"","sources":["../../src/core/CanonicalState.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Coherence Gate — Pre-action verification for agent coherence.
3
+ *
4
+ * Before high-risk actions (deployment, git push, external API calls),
5
+ * the agent pauses to verify: "Am I in the right project? Does this
6
+ * action match my identity and mission?"
7
+ *
8
+ * Born from the Luna incident (2026-02-25): An agent deployed to the
9
+ * wrong production target because nothing validated that the intended
10
+ * action matched the agent's current context.
11
+ *
12
+ * Design principle: Not a dumb pattern match — an intelligent
13
+ * self-verification that gives the agent the ability to step back,
14
+ * review what it's doing, and catch incoherence before it manifests.
15
+ *
16
+ * Three verification levels:
17
+ * 1. Structural — git remote, working directory, project name match
18
+ * 2. Contextual — action aligns with current topic/conversation scope
19
+ * 3. Intent — action aligns with stated mission/boundaries in AGENT.md
20
+ */
21
+ export interface CoherenceCheckResult {
22
+ /** Whether the action passed all coherence checks */
23
+ passed: boolean;
24
+ /** Individual check results */
25
+ checks: CoherenceCheck[];
26
+ /** Human-readable summary */
27
+ summary: string;
28
+ /** Recommended action: proceed, warn, or block */
29
+ recommendation: 'proceed' | 'warn' | 'block';
30
+ /** Timestamp */
31
+ checkedAt: string;
32
+ }
33
+ export interface CoherenceCheck {
34
+ /** Check name */
35
+ name: string;
36
+ /** Whether this check passed */
37
+ passed: boolean;
38
+ /** What was expected */
39
+ expected: string;
40
+ /** What was found */
41
+ actual: string;
42
+ /** Severity if failed: error blocks, warning alerts */
43
+ severity: 'error' | 'warning' | 'info';
44
+ /** Human-readable message */
45
+ message: string;
46
+ }
47
+ export interface CoherenceGateConfig {
48
+ /** Project root directory */
49
+ projectDir: string;
50
+ /** Instar state directory */
51
+ stateDir: string;
52
+ /** Expected project name (from config) */
53
+ projectName: string;
54
+ /** Expected git remote (if known) */
55
+ expectedGitRemote?: string;
56
+ /** Topic-project bindings */
57
+ topicProjects?: Record<string, TopicProjectBinding>;
58
+ }
59
+ export interface TopicProjectBinding {
60
+ /** Human-readable project name */
61
+ projectName: string;
62
+ /** Path to the project directory */
63
+ projectDir: string;
64
+ /** Expected git remote URL */
65
+ gitRemote?: string;
66
+ /** Deployment target URLs */
67
+ deploymentTargets?: string[];
68
+ /** Description of this project */
69
+ description?: string;
70
+ }
71
+ /** Actions that trigger coherence checking */
72
+ export type HighRiskAction = 'deploy' | 'git-push' | 'external-api' | 'file-modify-outside-project' | 'production-change';
73
+ export declare class CoherenceGate {
74
+ private config;
75
+ constructor(config: CoherenceGateConfig);
76
+ /**
77
+ * Run a full coherence check for a proposed action.
78
+ */
79
+ check(action: HighRiskAction, context?: {
80
+ targetUrl?: string;
81
+ targetPath?: string;
82
+ topicId?: number;
83
+ description?: string;
84
+ }): CoherenceCheckResult;
85
+ /**
86
+ * Generate a self-verification prompt for the agent to reflect before acting.
87
+ * This is the "step back and review" mechanism.
88
+ */
89
+ generateReflectionPrompt(action: HighRiskAction, context?: {
90
+ targetUrl?: string;
91
+ targetPath?: string;
92
+ topicId?: number;
93
+ topicName?: string;
94
+ description?: string;
95
+ }): string;
96
+ /**
97
+ * Get the topic-project binding for a specific topic.
98
+ */
99
+ getTopicBinding(topicId: number): TopicProjectBinding | null;
100
+ /**
101
+ * Register a topic-to-project binding.
102
+ */
103
+ setTopicBinding(topicId: number, binding: TopicProjectBinding): void;
104
+ /**
105
+ * Load topic-project bindings from disk.
106
+ */
107
+ loadTopicBindings(): Record<string, TopicProjectBinding>;
108
+ /**
109
+ * Save topic-project bindings to disk.
110
+ */
111
+ private saveTopicBindings;
112
+ private checkWorkingDirectory;
113
+ private checkGitRemote;
114
+ private checkTopicProjectAlignment;
115
+ private checkDeploymentTarget;
116
+ private checkPathScope;
117
+ private checkAgentIdentity;
118
+ private detectGitRemote;
119
+ private normalizeGitUrl;
120
+ private normalizePath;
121
+ }
122
+ //# sourceMappingURL=CoherenceGate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CoherenceGate.d.ts","sourceRoot":"","sources":["../../src/core/CoherenceGate.ts"],"names":[],"mappings":"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"}