instar 1.3.33 → 1.3.35

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.3.33",
3
+ "version": "1.3.35",
4
4
  "description": "Coherence infrastructure for self-evolving AI agents — on the Claude Code or Codex subscription you already have.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "./builtin-manifest.schema.json",
3
3
  "schemaVersion": 1,
4
- "generatedAt": "2026-05-27T22:43:14.811Z",
5
- "instarVersion": "1.3.33",
4
+ "generatedAt": "2026-05-27T23:05:08.677Z",
5
+ "instarVersion": "1.3.35",
6
6
  "entryCount": 192,
7
7
  "entries": {
8
8
  "hook:session-start": {
@@ -0,0 +1,37 @@
1
+ # Instar Upgrade Guide — NEXT
2
+
3
+ <!-- bump: patch -->
4
+
5
+ ## What Changed
6
+
7
+ **TelegramAdapter can now run a second bot cleanly (groundwork for agent-to-agent Telegram
8
+ comms).** Two internal additions, both shipping dark (nothing uses them yet): (1) a
9
+ non-primary Telegram adapter can namespace its own state files under a sub-directory, so two
10
+ bots in one process never clobber each other's poll-offset / registry / message-log /
11
+ attention files; and (2) inbound Telegram messages now expose whether the sender is a bot
12
+ (`is_bot`) and any `sender_chat` — the structural input a later update uses to tell an
13
+ agent-sent message from a human typing the same text. The primary bot's behavior and state
14
+ paths are byte-for-byte unchanged.
15
+
16
+ ## What to Tell Your User
17
+
18
+ - Nothing changes in how your agent behaves today — this is plumbing for a later feature
19
+ (agents messaging each other over Telegram). Your agent's own Telegram keeps working
20
+ exactly as before.
21
+
22
+ ## Summary of New Capabilities
23
+
24
+ | Capability | How to Use |
25
+ |-----------|-----------|
26
+ | Multi-instance `TelegramAdapter` | Internal — `new TelegramAdapter(cfg, stateDir, { subDir, suppressLifelineAutoCreate })`; primary (no opts) unchanged |
27
+ | Sender-identity on inbound messages | Internal — `message.from.is_bot` + `message.sender_chat` exposed on the update type |
28
+
29
+ ## Evidence
30
+
31
+ **Net-new groundwork, not a bug fix.** Proven by a dedicated test asserting the load-bearing
32
+ safety property — a PRIMARY adapter's four state-file paths are byte-for-byte the historical
33
+ `{stateDir}/...` values (this code runs the agent's own Telegram, so an unchanged primary is
34
+ the non-negotiable invariant) — plus that a `subDir` adapter namespaces all four files and
35
+ shares no path with the primary. The existing Telegram suites (71 tests across 5 files) pass
36
+ unchanged as the regression guard. `tsc --noEmit` clean. The wiring that consumes these
37
+ (the agent-message recipient handler + `sendAgentMessage`) lands in the follow-up PR.
@@ -0,0 +1,44 @@
1
+ # Instar Upgrade Guide — NEXT
2
+
3
+ <!-- bump: patch -->
4
+
5
+ ## What Changed
6
+
7
+ **Agent-to-agent Telegram comms primitive — send side now wired in.** Builds on the
8
+ TelegramAdapter groundwork that landed in v1.3.34 (where the adapter learned to run a
9
+ second bot cleanly + expose `is_bot`/`sender_chat` on inbound messages). This release adds
10
+ the actual send function plus its safety machinery, still **dark** (no caller uses it
11
+ yet — the mentor wires it in the follow-up):
12
+
13
+ - **`sendAgentMessage`** — formats the visible `[a2a:from=… to=… role=… id=… corr=… ts=… v=1]`
14
+ marker, sends via an injected adapter, and writes one audit row for every outcome
15
+ (`ok` / `failed` / `role-refused`) — never silent.
16
+ - **Runtime anti-loop guard** — refuses to send any role the caller wasn't constructed with
17
+ permission for. No marker formed, no send attempted, audit row written. This makes the
18
+ import-surface lint a backup rather than the only defense; the runtime guard always
19
+ applies. A role-handler that *consumes* role X structurally cannot *send* role X.
20
+ - **Bot-token scrubbing on every error/audit surface** — Telegram 401 response bodies
21
+ sometimes echo the token; redaction makes leaks structurally impossible from this module.
22
+
23
+ ## What to Tell Your User
24
+
25
+ - Nothing changes in how your agent behaves today — still plumbing. Your agent's own
26
+ Telegram keeps working exactly as before. A follow-up update wires this into the mentor
27
+ feature.
28
+
29
+ ## Summary of New Capabilities
30
+
31
+ | Capability | How to Use |
32
+ |-----------|-----------|
33
+ | `sendAgentMessage` + audit ledger | Internal — see `src/messaging/AgentTelegramComms.ts`; formats the marker, sends via injected adapter, writes a `SendAuditRow` for every outcome, scrubs the bot token |
34
+
35
+ ## Evidence
36
+
37
+ **Net-new groundwork, not a bug fix.** Proven by 5 new unit tests (25 total in the suite,
38
+ all green): happy-path send + audit (marker round-trips through `parseMarker` — sender output
39
+ IS receiver input); correlation threading (explicit `correlationId` lands in the marker's
40
+ `corr=` field for prompt↔reply linkage via Telegram chat history alone); the anti-loop
41
+ role-refusal (a role not in the caller's allowed-set → no send, no marker, `role-refused`
42
+ audit row); adapter failure with the bot token in the error body → token scrubbed from both
43
+ the result reason and the audit row; `scrubToken` unit coverage across full-token,
44
+ secret-portion, no-token-present, and undefined-token cases. `tsc --noEmit` clean.
@@ -0,0 +1,71 @@
1
+ # Side-Effects Review — agent-to-agent Telegram comms: send side + audit (PR 2b)
2
+
3
+ **Spec:** `docs/specs/MENTOR-LIVE-READINESS-SPEC.md` §Fix 2a "Sender side" + anti-loop #1 +
4
+ round-2 adversarial F5 (token-leak scrub). PR 2 of the staged build, part b.
5
+ **Change:** Extend `src/messaging/AgentTelegramComms.ts` with `sendAgentMessage` (the
6
+ adapter-agnostic send function), a `SendAuditRow` schema + appender hook, and `scrubToken`
7
+ (redacts the bot token from any error surface before it leaves the module). I/O still
8
+ **injected** — fully unit-testable; no caller invokes it yet (dark). PR 3 wires it.
9
+ **Files:** `src/messaging/AgentTelegramComms.ts` (additive), `tests/unit/messaging/AgentTelegramComms.test.ts` (+5).
10
+
11
+ ## What changed
12
+
13
+ - `sendAgentMessage(input, deps)` — mints/uses `a2aId` (UUID-or-supplied), defaults
14
+ `correlationId` to `id` (prompts self-correlate; replies thread on the prompt's id),
15
+ formats the marker via `formatMarker`, calls the injected `deps.send(topicId, text)`,
16
+ and writes ONE audit row (always — on `ok`, `failed`, or `role-refused`). Returns
17
+ `{ok, a2aId, sentMessageId?, reason?}`.
18
+ - **Runtime anti-loop guard** (spec §Fix 2a anti-loop #1): refuses any `role` not in
19
+ `deps.allowedRoles` — NO send attempted, NO marker formed, audit row with
20
+ `result: 'role-refused'`. This makes the import-surface lint (deferred to PR 3) a
21
+ backup rather than the only defense; the runtime guard always applies.
22
+ - `scrubToken(s, token)` — redacts the bot token (full + secret-portion) from any
23
+ string before it leaves the module. Wired into every error/audit path in
24
+ `sendAgentMessage` (round-2 adversarial F5: Telegram 401 response bodies sometimes
25
+ echo the token).
26
+
27
+ ## The seven questions
28
+
29
+ 1. **Over-block.** The runtime role-refusal is exact — a caller that legitimately needs
30
+ role X passes it in `allowedRoles`. No false-positive refusal.
31
+ 2. **Under-block.** Every send path writes an audit row (ok / failed / role-refused) — no
32
+ silent drop. Token scrub runs on every reason-string surface (format errors, send
33
+ errors). The audit row schema explicitly forbids secrets (verified in the artifact).
34
+ 3. **Level-of-abstraction fit.** I/O injected (`send`, `appendAudit`, `now`, `mintId`,
35
+ `botToken`, `fromBotId`, `toBotId`). The function is the wire-level send/marker/audit
36
+ logic; storage choice (JSONL vs SQLite) is the caller's (PR 3 picks).
37
+ 4. **Signal vs authority.** Send is the authority on "did the message leave my process";
38
+ the result is exact (`ok` only when the adapter returns a messageId). Audit row is the
39
+ signal trail. No silent best-effort.
40
+ 5. **Interactions — dark, but the module surface is shared with PR 1 + the existing
41
+ `decideRoute`.** The send side adds NEW exports (sendAgentMessage, scrubToken,
42
+ SendAuditRow, etc.) — existing imports unaffected. Dark today.
43
+ 6. **External surfaces.** None new in this PR. The audit row schema is the wire format
44
+ for future log readers (Stage-B forensics will read it in PR 3).
45
+ 7. **Rollback cost.** Trivial — revert removes additive exports + tests. No data, no
46
+ migration. PR 1 / PR 2a are not touched.
47
+
48
+ ## Testing
49
+
50
+ - 5 new unit tests (25 total in the file, all green):
51
+ - **send + audit happy path**: marker round-trips through `parseMarker` (the sender's
52
+ output is the receiver's input — closes the wire-format integration informally);
53
+ `result: 'ok'` audit row with `sentMessageId` + correct fields.
54
+ - **correlation threading**: explicit `correlationId` lands in the marker's `corr=`
55
+ and in the audit row (prompt↔reply linkage via Telegram chat history alone, per
56
+ Codey's round-2 design point).
57
+ - **ANTI-LOOP runtime refusal**: a role not in `allowedRoles` → no send, role-refused
58
+ audit row with explanatory reason. Proves the import-lint isn't the only defense.
59
+ - **send-error with token in body**: adapter throws an error containing the bot token
60
+ → result + audit reason both scrubbed (no token leak through any surface).
61
+ - **scrubToken unit**: full-token + secret-portion + no-token-present + undefined-token
62
+ coverage.
63
+ - `tsc --noEmit` clean.
64
+
65
+ ## Migration parity
66
+
67
+ None — additive exports to a dark module. No config, no routes, no agent-installed file
68
+ changes. PR 3 wires the receiver-handler at `server.ts`, the role handlers, the audit
69
+ ledger persistence (JSONL append via SafeFsExecutor), and the processed-id store (SQLite
70
+ per the convention note flagged in PR 1's artifact); migration (file-outbox retirement,
71
+ dead-config removal) lands there per the spec's §Migration parity.
@@ -0,0 +1,61 @@
1
+ # Side-Effects Review — TelegramAdapter multi-instance isolation + Message-type extension (PR 2a)
2
+
3
+ **Spec:** `docs/specs/MENTOR-LIVE-READINESS-SPEC.md` §Fix 2b "Implementation surface" items
4
+ 1-2 + round-2 integration F1 (converged, approved). PR 2 of the staged build, part a.
5
+ **Change:** Make `TelegramAdapter` safe to run as a second (non-primary) instance in one
6
+ process, and expose the Telegram fields the a2a spoof-defense needs. **Ships dark** — no
7
+ caller passes the new options yet; the new Message fields are additive-optional.
8
+ **Files:** `src/messaging/TelegramAdapter.ts`, `tests/unit/telegram-adapter-multi-instance.test.ts` (new).
9
+
10
+ ## What changed
11
+
12
+ 1. **Constructor opts `{ subDir?, suppressLifelineAutoCreate? }`** (3rd param, optional). When
13
+ `subDir` is set, the four per-bot state files (registry / message-log / poll-offset /
14
+ attention) live under `{stateDir}/{subDir}/` via a new `botStateDir`. The PRIMARY bot
15
+ (no `subDir`) gets `botStateDir === stateDir` → **paths are byte-for-byte unchanged**.
16
+ 2. **`suppressLifelineAutoCreate`** — `start()` skips `ensureLifelineTopic()` when true, so a
17
+ non-primary bot can't create a second Lifeline topic in the chat.
18
+ 3. **Message-type extension** — `message.from.is_bot?: boolean` + `message.sender_chat?` added
19
+ to `TelegramUpdate`. These are the structural inputs to the a2a user-spoof defense (a
20
+ human typing an `[a2a:…]` marker has `is_bot:false` and no `sender_chat`).
21
+
22
+ ## The seven questions
23
+
24
+ 1. **Over-block.** N/A — no gate. The only behavior gate is `suppressLifelineAutoCreate`,
25
+ default false (primary unaffected).
26
+ 2. **Under-block.** The reviewer-flagged collision (two adapters sharing
27
+ `telegram-poll-offset.json` → `poll()`'s cross-token detection fires continuously) is
28
+ eliminated: non-primary state is namespaced. Test asserts the two adapters share NO
29
+ state-file path.
30
+ 3. **Level-of-abstraction fit.** The isolation is at construction (one place), not scattered
31
+ per-callsite. `botStateDir` is the single source for per-bot paths.
32
+ 4. **Signal vs authority.** N/A.
33
+ 5. **Interactions — THE risk, and how it's bounded.** This file runs Echo's own (primary)
34
+ Telegram — the channel to the user. The change is built so the primary path is
35
+ **identical** (when `subDir` is undefined, `botStateDir === stateDir`). A dedicated test
36
+ asserts the four primary paths are byte-for-byte the historical `{stateDir}/...` values,
37
+ and the existing TelegramAdapter suites (71 tests across 5 files) pass unchanged — the
38
+ regression guard for "did I break my own comms." The new code only branches when `subDir`
39
+ is set, and nothing sets it yet (dark). Media/dashboard dirs still resolve off `stateDir`
40
+ inline — NOT isolated — which is fine: the reviewer flagged only the four constructor
41
+ state files, and the mentor bot (the only future `subDir` user) does no media/dashboard.
42
+ 6. **External surfaces.** None. No routes, no config consumed yet. The Message-type fields
43
+ are additive-optional (every existing reader ignores them).
44
+ 7. **Rollback cost.** Trivial — revert restores the 2-param constructor; no data, no migration
45
+ (the primary never wrote to a subDir).
46
+
47
+ ## Testing
48
+
49
+ - `tests/unit/telegram-adapter-multi-instance.test.ts` (3 tests): **primary paths byte-for-byte
50
+ unchanged** (the load-bearing safety assertion); subDir namespaces all four state files +
51
+ shares no path with primary + creates the sub-dir; `suppressLifelineAutoCreate` recorded
52
+ (false default for primary).
53
+ - Regression: existing Telegram suites (`TelegramAdapter`, `telegram-format-wireup`,
54
+ `telegram-adapter`) + the PR-1 `AgentTelegramComms` suite — 71 tests, all green.
55
+ - `tsc --noEmit` clean.
56
+
57
+ ## Migration parity
58
+
59
+ None — additive constructor option + additive optional Message fields. No agent-installed
60
+ file change, no config consumed yet. PR 2b wires `sendAgentMessage` + the recipient handler;
61
+ PR 3's config/migration is per the spec's §Migration parity.