instar 1.2.61 → 1.2.63
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.
- package/README.md +10 -0
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +115 -24
- package/dist/commands/server.js.map +1 -1
- package/dist/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +13 -0
- package/dist/config/ConfigDefaults.js.map +1 -1
- package/dist/core/SessionManager.d.ts +18 -0
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +34 -0
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/TopicIntent.d.ts +62 -1
- package/dist/core/TopicIntent.d.ts.map +1 -1
- package/dist/core/TopicIntent.js +131 -2
- package/dist/core/TopicIntent.js.map +1 -1
- package/dist/core/TopicIntentCapture.d.ts +124 -0
- package/dist/core/TopicIntentCapture.d.ts.map +1 -0
- package/dist/core/TopicIntentCapture.js +232 -0
- package/dist/core/TopicIntentCapture.js.map +1 -0
- package/dist/core/TopicIntentExtractor.d.ts +32 -0
- package/dist/core/TopicIntentExtractor.d.ts.map +1 -1
- package/dist/core/TopicIntentExtractor.js +52 -3
- package/dist/core/TopicIntentExtractor.js.map +1 -1
- package/dist/core/types.d.ts +10 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/monitoring/sentinelWiring.d.ts +28 -0
- package/dist/monitoring/sentinelWiring.d.ts.map +1 -1
- package/dist/monitoring/sentinelWiring.js +48 -0
- package/dist/monitoring/sentinelWiring.js.map +1 -1
- package/dist/server/CapabilityIndex.d.ts.map +1 -1
- package/dist/server/CapabilityIndex.js +1 -0
- package/dist/server/CapabilityIndex.js.map +1 -1
- package/dist/server/topicIntentRoutes.d.ts.map +1 -1
- package/dist/server/topicIntentRoutes.js +61 -1
- package/dist/server/topicIntentRoutes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +3 -3
- package/upgrades/1.2.62.md +75 -0
- package/upgrades/1.2.63.md +84 -0
- package/upgrades/side-effects/rate-limit-recovery-reachability.md +116 -0
- package/upgrades/side-effects/topic-intent-capture-loop.md +100 -0
package/README.md
CHANGED
|
@@ -200,6 +200,16 @@ The AI systems we build today set precedents for how AI is treated tomorrow. **T
|
|
|
200
200
|
|
|
201
201
|
> **Deep dive:** [Philosophy](https://instar.sh/concepts/philosophy/)
|
|
202
202
|
|
|
203
|
+
## The Living Constitution
|
|
204
|
+
|
|
205
|
+
Instar's engineering principles aren't a static style guide — they're a **living constitution**. The [Standards Registry](https://instar.sh/foundations/standards-registry/) codifies each one as a rule, what it means in practice, the *failure it was earned from*, and its trace back to the one founding goal: a coherent, self-evolving agent. Nineteen articles across five families (Root, Substrate, Building, Shipping, Interaction), plus the Genesis story and the AWG positioning on the ethics of instantiating agents.
|
|
206
|
+
|
|
207
|
+
It's not decoration — it's a working part of the machine. The spec-review conformance gate checks every draft against it, and the registry grows the same way the framework was built: the agent proposes a new standard with its story, the operator ratifies it.
|
|
208
|
+
|
|
209
|
+
The registry is the first tangible artifact of a larger vision: the [North Star — Continuous Working Awareness](https://instar.sh/foundations/north-star/). The aim is an agent that never silently loses track of something that mattered — capturing relevant context automatically, keeping it warm while it matters, re-surfacing it the moment it's needed, and letting it fade when it stops — across three facets that are really one: awareness of the world, of itself, and of its own standards.
|
|
210
|
+
|
|
211
|
+
> **Read the constitution:** [Standards Registry](https://instar.sh/foundations/standards-registry/) · [North Star](https://instar.sh/foundations/north-star/)
|
|
212
|
+
|
|
203
213
|
## iMessage Setup (macOS)
|
|
204
214
|
|
|
205
215
|
iMessage support lets your agent send and receive iMessages on macOS. Messages are read directly from the native Messages database and sent via the [`imsg`](https://github.com/steipete/imsg) CLI.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAuQH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAiqDD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAuQH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAiqDD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA+6LtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
|
package/dist/commands/server.js
CHANGED
|
@@ -4750,31 +4750,67 @@ export async function startServer(options) {
|
|
|
4750
4750
|
// docs/specs/rate-limit-sentinel.md.
|
|
4751
4751
|
const { RateLimitSentinel } = await import('../monitoring/RateLimitSentinel.js');
|
|
4752
4752
|
const getClaudeSessionIdForName = (sessionName) => sessionManager.listRunningSessions().find(s => s.tmuxSession === sessionName)?.claudeSessionId;
|
|
4753
|
-
//
|
|
4754
|
-
//
|
|
4755
|
-
//
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4753
|
+
// Recovery-reachability audit trail. Both recovery paths below ALWAYS leave
|
|
4754
|
+
// a record: a recovery-reached/recovery-unreachable line in the sentinel
|
|
4755
|
+
// audit log, and — when delivery to the user fails entirely — an entry in
|
|
4756
|
+
// .instar/sentinel-alerts.json so the dashboard surfaces it even without
|
|
4757
|
+
// Telegram. The defining bug this closes: a non-topic-bound session (e.g. a
|
|
4758
|
+
// developer's interactive Claude Code window) used to make both recovery
|
|
4759
|
+
// paths silently no-op, so the throttle never recovered and nothing reached
|
|
4760
|
+
// the user. Reachability is now unconditional — see the Sentinel
|
|
4761
|
+
// Reachability spec.
|
|
4762
|
+
const rlReachLogPath = path.join(config.stateDir, '..', 'logs', 'sentinel-events.jsonl');
|
|
4763
|
+
const rlAlertsPath = path.join(config.stateDir, 'sentinel-alerts.json');
|
|
4764
|
+
const recordRecovery = (kind, sessionName, detail, fallbackTried) => {
|
|
4765
|
+
const entry = { timestamp: new Date().toISOString(), kind, sentinel: 'rate-limit', sessionName, detail, fallbackTried };
|
|
4766
|
+
console.log(`[sentinel:${kind}] rate-limit/${sessionName} — ${detail}`);
|
|
4767
|
+
try {
|
|
4768
|
+
fs.appendFileSync(rlReachLogPath, JSON.stringify(entry) + '\n');
|
|
4769
|
+
}
|
|
4770
|
+
catch { /* best-effort */ }
|
|
4771
|
+
if (kind === 'recovery-unreachable') {
|
|
4772
|
+
// Append-only alert log the dashboard reads when Telegram can't be reached.
|
|
4773
|
+
try {
|
|
4774
|
+
let alerts = [];
|
|
4775
|
+
if (fs.existsSync(rlAlertsPath)) {
|
|
4776
|
+
try {
|
|
4777
|
+
alerts = JSON.parse(fs.readFileSync(rlAlertsPath, 'utf-8'));
|
|
4778
|
+
}
|
|
4779
|
+
catch {
|
|
4780
|
+
alerts = [];
|
|
4781
|
+
}
|
|
4782
|
+
if (!Array.isArray(alerts))
|
|
4783
|
+
alerts = [];
|
|
4784
|
+
}
|
|
4785
|
+
alerts.push(entry);
|
|
4786
|
+
fs.writeFileSync(rlAlertsPath, JSON.stringify(alerts.slice(-200), null, 2));
|
|
4787
|
+
}
|
|
4788
|
+
catch { /* best-effort */ }
|
|
4789
|
+
}
|
|
4777
4790
|
};
|
|
4791
|
+
// Reachability deps (extracted to sentinelWiring.buildRateLimitRecoveryDeps
|
|
4792
|
+
// so the topic / lifeline / audit branching is unit-testable). Topic-bound
|
|
4793
|
+
// sessions get a topic-tagged nudge + topic notice; non-topic-bound sessions
|
|
4794
|
+
// (e.g. an interactive dev window) get a trusted internal nudge + a lifeline
|
|
4795
|
+
// notice; if no channel is reachable, a recovery-unreachable audit event is
|
|
4796
|
+
// recorded instead of a silent no-op.
|
|
4797
|
+
const { buildRateLimitRecoveryDeps } = await import('../monitoring/sentinelWiring.js');
|
|
4798
|
+
const { resumeFn: rateLimitResume, notifyFn: rateLimitNotify } = buildRateLimitRecoveryDeps({
|
|
4799
|
+
isSessionAlive: (name) => sessionManager.isSessionAlive(name),
|
|
4800
|
+
injectTopicNudge: (name, topicId, text) => sessionManager.injectMessage(name, `[telegram:${topicId}] ${text}`),
|
|
4801
|
+
injectInternalNudge: (name, text) => sessionManager.injectInternalMessage(name, text, 'sentinel-recovery'),
|
|
4802
|
+
getTopicForSession: (name) => telegram?.getTopicForSession(name),
|
|
4803
|
+
getLifelineTopicId: () => telegram?.getLifelineTopicId?.(),
|
|
4804
|
+
deliverNotice: async (topicId, text) => {
|
|
4805
|
+
const resp = await fetch(`http://localhost:${config.port}/telegram/reply/${topicId}`, {
|
|
4806
|
+
method: 'POST',
|
|
4807
|
+
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${config.authToken}` },
|
|
4808
|
+
body: JSON.stringify({ text }),
|
|
4809
|
+
});
|
|
4810
|
+
return resp.ok;
|
|
4811
|
+
},
|
|
4812
|
+
recordRecovery,
|
|
4813
|
+
});
|
|
4778
4814
|
const rlsCfg = config.monitoring?.rateLimitSentinel ?? { enabled: true };
|
|
4779
4815
|
const rateLimitSentinel = new RateLimitSentinel({
|
|
4780
4816
|
resumeFn: rateLimitResume,
|
|
@@ -5362,6 +5398,61 @@ export async function startServer(options) {
|
|
|
5362
5398
|
beforeHadCallback(entry);
|
|
5363
5399
|
observeInboundMessage(humanAsDetectorLog, entry);
|
|
5364
5400
|
};
|
|
5401
|
+
// ── Topic-Intent capture loop (rung 0 of continuous-working-awareness) ─
|
|
5402
|
+
// The "clerk" that fills the topic-intent store from live conversation so
|
|
5403
|
+
// the per-topic briefing + ArcCheck have real material (closes the
|
|
5404
|
+
// shipped-but-asleep gap — the store/routes/briefing all existed but
|
|
5405
|
+
// nothing ever invoked ingest()). Chains the prior callback; capture is
|
|
5406
|
+
// fire-and-forget + degrade-safe so it NEVER blocks or slows delivery.
|
|
5407
|
+
// Spec: docs/specs/topic-intent-capture-loop.md.
|
|
5408
|
+
if (sharedIntelligence && (config.topicIntent?.capture?.enabled ?? true)) {
|
|
5409
|
+
try {
|
|
5410
|
+
const { TopicIntentExtractor, createLlmExtractFn } = await import('../core/TopicIntentExtractor.js');
|
|
5411
|
+
const { createCaptureLoop, createQueuedIntelligence } = await import('../core/TopicIntentCapture.js');
|
|
5412
|
+
// Transport: route every extraction through sharedLlmQueue (background
|
|
5413
|
+
// lane → yields to interactive work, respects the daily cap), with the
|
|
5414
|
+
// call itself delegating to sharedIntelligence (subscription/REPL-pool,
|
|
5415
|
+
// never raw API — acceptance #6).
|
|
5416
|
+
const queuedIntelligence = createQueuedIntelligence(sharedIntelligence, (lane, fn, costCents) => sharedLlmQueue.enqueue(lane, fn, costCents));
|
|
5417
|
+
const captureExtractFn = createLlmExtractFn(queuedIntelligence, (reason, topicId) => {
|
|
5418
|
+
topicIntentStore.bumpCaptureCounters(topicId, reason === 'no-intelligence'
|
|
5419
|
+
? { degraded_no_intelligence: 1 }
|
|
5420
|
+
: { degraded_cap_or_error: 1 });
|
|
5421
|
+
});
|
|
5422
|
+
const captureExtractor = new TopicIntentExtractor(topicIntentStore, captureExtractFn);
|
|
5423
|
+
const captureLoop = createCaptureLoop({
|
|
5424
|
+
extractor: captureExtractor,
|
|
5425
|
+
store: topicIntentStore,
|
|
5426
|
+
topicMemory,
|
|
5427
|
+
// Skip capture under sustained quota pressure (load-shedding).
|
|
5428
|
+
shouldShed: () => {
|
|
5429
|
+
const r = quotaTracker?.getRecommendation();
|
|
5430
|
+
return r === 'critical' || r === 'stop';
|
|
5431
|
+
},
|
|
5432
|
+
// Per-topic runaway guard beyond the pre-filter.
|
|
5433
|
+
rateCeiling: { maxPerWindow: 30, windowMs: 60_000 },
|
|
5434
|
+
});
|
|
5435
|
+
const beforeCaptureCb = telegram.onMessageLogged;
|
|
5436
|
+
telegram.onMessageLogged = (entry) => {
|
|
5437
|
+
if (beforeCaptureCb)
|
|
5438
|
+
beforeCaptureCb(entry);
|
|
5439
|
+
// Fire-and-forget — capture latency must never reach the delivery path.
|
|
5440
|
+
void captureLoop({
|
|
5441
|
+
messageId: entry.messageId,
|
|
5442
|
+
topicId: entry.topicId ?? undefined,
|
|
5443
|
+
text: entry.text,
|
|
5444
|
+
fromUser: entry.fromUser,
|
|
5445
|
+
timestamp: entry.timestamp,
|
|
5446
|
+
});
|
|
5447
|
+
};
|
|
5448
|
+
// Anti-"shipped-but-asleep" marker for the wiring-integrity test.
|
|
5449
|
+
globalThis.__instarTopicIntentCaptureWired = true;
|
|
5450
|
+
console.log(pc.green(' Topic-intent capture loop wired (per-turn extraction → store)'));
|
|
5451
|
+
}
|
|
5452
|
+
catch (err) {
|
|
5453
|
+
console.warn('[TopicIntentCapture] init failed:', err.message);
|
|
5454
|
+
}
|
|
5455
|
+
}
|
|
5365
5456
|
presenceProxy.start();
|
|
5366
5457
|
// ── PromiseBeacon ────────────────────────────────────────────────
|
|
5367
5458
|
// Watches beacon-enabled commitments and emits ⏳ heartbeats so the
|