instar 1.2.61 → 1.2.62
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 +55 -0
- 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/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/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 +2 -2
- package/upgrades/1.2.62.md +75 -0
- package/upgrades/side-effects/topic-intent-capture-loop.md +100 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Side-effects review — topic-intent auto-capture loop (rung 0)
|
|
2
|
+
|
|
3
|
+
**Scope**: Wire the topic-intent capture loop so the per-topic store actually
|
|
4
|
+
fills from live conversation (closing the "shipped but asleep" gap — the store,
|
|
5
|
+
read routes, and session-start briefing all shipped, but nothing ever invoked
|
|
6
|
+
`ingest()` on a real turn). Adds the adapter-agnostic capture "clerk", broader
|
|
7
|
+
context (rolling summary + established refs) feeding the extractor, cost
|
|
8
|
+
controls, prompt-injection-hardened extraction, the live wiring on the inbound
|
|
9
|
+
message path, and whole-loop observability. Spec:
|
|
10
|
+
`docs/specs/topic-intent-capture-loop.md` (converged iter 3, approved by justin).
|
|
11
|
+
|
|
12
|
+
**Files touched**:
|
|
13
|
+
- `src/core/TopicIntent.ts` — add `CaptureCounters` to `TelemetryCounters`
|
|
14
|
+
(defaulted on read for back-compat) + `defaultCaptureCounters()` +
|
|
15
|
+
`bumpCaptureCounters()` (atomic under the existing per-topic lock). Switch the
|
|
16
|
+
two `withTopicLock` lock-dir removals to `SafeFsExecutor.safeRmdirSync`.
|
|
17
|
+
- `src/core/TopicIntentExtractor.ts` — `createLlmExtractFn` gains an optional
|
|
18
|
+
`onDegrade(reason, topicId)` observability hook; still returns `[]` on every
|
|
19
|
+
degrade path (degrade-safety unchanged).
|
|
20
|
+
- `src/core/TopicIntentCapture.ts` — NEW. The capture step: `isSubstantiveTurn`
|
|
21
|
+
pre-filter (deterministic, fail-open) + canary; `createQueuedIntelligence`
|
|
22
|
+
(queue-backed, subscription-transport); `captureTurn` + `createCaptureLoop`
|
|
23
|
+
(rate-state-owning closure).
|
|
24
|
+
- `src/server/topicIntentRoutes.ts` — NEW `GET /topic-intent/:id/capture-metrics`
|
|
25
|
+
(the whole-loop funnel); `briefing_served` metering on the briefing route;
|
|
26
|
+
`arccheck_fired`/`arccheck_signalled` metering on the arccheck route.
|
|
27
|
+
- `src/server/CapabilityIndex.ts` — add `topic-intent` to `INTERNAL_PREFIXES`
|
|
28
|
+
(operator-only; not a discoverable agent endpoint).
|
|
29
|
+
- `src/config/ConfigDefaults.ts` — `topicIntent.capture.enabled: true` in
|
|
30
|
+
`SHARED_DEFAULTS` (auto-applies on init AND migration → migration parity).
|
|
31
|
+
- `src/core/types.ts` — add optional `topicIntent` to `InstarConfig`.
|
|
32
|
+
- `src/commands/server.ts` — construct the queue-backed extractor + capture loop
|
|
33
|
+
and chain it onto `telegram.onMessageLogged` (preserving prior callbacks),
|
|
34
|
+
gated on `sharedIntelligence && config.topicIntent.capture.enabled`.
|
|
35
|
+
- Tests: `tests/unit/TopicIntentCapture.test.ts`,
|
|
36
|
+
`tests/integration/topic-intent-capture-routes.test.ts`,
|
|
37
|
+
`tests/e2e/topic-intent-capture-lifecycle.test.ts`.
|
|
38
|
+
- `docs/specs/06-state-detector-registry.md` — NEW registry; pre-filter entry.
|
|
39
|
+
|
|
40
|
+
**Under-block**: The pre-filter is fail-open — when unsure it passes the turn to
|
|
41
|
+
the LLM, so it cannot silently swallow a substantive turn on an ambiguous input.
|
|
42
|
+
Its only confident skips are empty/whitespace, whole-message bare acks, and
|
|
43
|
+
agent sentinel/heartbeat lines (agent turns only). Risk of under-block (a real
|
|
44
|
+
turn skipped) is bounded to sentinel-format drift, which the canary guards.
|
|
45
|
+
|
|
46
|
+
**Over-block**: The only "block"-shaped behavior is the pre-filter skip and the
|
|
47
|
+
QuotaTracker shed. Over-skipping costs a missed cheap extraction, never a
|
|
48
|
+
delivery failure or a user-visible block. The canary asserts known substantive
|
|
49
|
+
turns (including ack-prefixed ones) are NOT skipped.
|
|
50
|
+
|
|
51
|
+
**Level-of-abstraction fit**: The capture step is adapter-agnostic — it takes a
|
|
52
|
+
generic `CaptureTurnEntry`, not a Telegram type; Telegram is merely the first
|
|
53
|
+
wiring (other adapters tracked as `cwa-multi-adapter-capture`). The store stays
|
|
54
|
+
the single authority for persistence/projection; the extractor owns extraction;
|
|
55
|
+
the capture helper only orchestrates. Transport is delegated to the injected
|
|
56
|
+
`sharedIntelligence` provider (subscription/REPL-pool) through the shared
|
|
57
|
+
`LlmQueue` — capture never reaches for a raw API client.
|
|
58
|
+
|
|
59
|
+
**Signal vs authority**: Capture only RECORDS (append-only evidence); it has no
|
|
60
|
+
blocking authority. ArcCheck SIGNALS; neither blocks a send. The pre-filter is a
|
|
61
|
+
brittle low-context detector emitting a skip signal, never a gate. This matches
|
|
62
|
+
`[[feedback_signal_vs_authority]]`.
|
|
63
|
+
|
|
64
|
+
**Interactions**:
|
|
65
|
+
- `telegram.onMessageLogged` is a single-assignment property already chained by
|
|
66
|
+
PresenceProxy, human-as-detector, and the keep-watching detector. The capture
|
|
67
|
+
wiring preserves the prior callback (`const before = ...; cb = (e) => { before?.(e); capture(e); }`),
|
|
68
|
+
verified by the e2e chain test (prior callback still fires).
|
|
69
|
+
- Capture is fire-and-forget (`void captureLoop(...)`) so extraction latency
|
|
70
|
+
can never reach the delivery path (acceptance #4).
|
|
71
|
+
- Extraction is admitted on the LlmQueue **background** lane, so it yields to
|
|
72
|
+
interactive (PresenceProxy/PromiseBeacon) work and shares the daily cap. On
|
|
73
|
+
cap breach the queue throws → `createLlmExtractFn` catches → degrades to a
|
|
74
|
+
`degraded_cap_or_error` tick.
|
|
75
|
+
- `bumpCaptureCounters`, `bumpTurn`, and `appendEvidence` each take the per-topic
|
|
76
|
+
lock separately (multiple short acquisitions per turn). Correct under
|
|
77
|
+
concurrency (the concurrency test still passes); accepted minor lock churn for
|
|
78
|
+
v1 since capture runs off the delivery path.
|
|
79
|
+
- The briefing route now has a metering side-effect on a GET (writes
|
|
80
|
+
`briefing_served`). Intentional per spec §10; best-effort and never blocks the
|
|
81
|
+
fetch.
|
|
82
|
+
|
|
83
|
+
**External surfaces**:
|
|
84
|
+
- New endpoint: `GET /topic-intent/:topicId/capture-metrics` (operator-only).
|
|
85
|
+
- New config field: `topicIntent.capture.enabled` (default true; kill-switch).
|
|
86
|
+
- New additive `TopicIntentFile` fields (`telemetry.capture.*`), defaulted on
|
|
87
|
+
read — old files load unchanged.
|
|
88
|
+
- New exported symbols in `TopicIntentCapture.ts`; no breaking change to
|
|
89
|
+
existing exports.
|
|
90
|
+
|
|
91
|
+
**Cost (the one genuinely new ongoing cost)**: This is the product's first
|
|
92
|
+
always-on per-turn LLM path. Bounded by: the deterministic pre-filter (most
|
|
93
|
+
turns never reach the model), a per-topic rate ceiling (30/60s), the LlmQueue
|
|
94
|
+
daily cap (best-effort, per-process), and QuotaTracker load-shedding. ON by
|
|
95
|
+
default is ratified.
|
|
96
|
+
|
|
97
|
+
**Rollback cost**: Low. Config kill-switch `topicIntent.capture.enabled: false`
|
|
98
|
+
makes capture inert immediately (store + routes remain, as today). Full revert:
|
|
99
|
+
drop the server.ts wiring block + the new file; the store/routes/briefing return
|
|
100
|
+
to the inert pre-capture state. Additive store fields are harmless if left.
|