instar 0.28.73 → 0.28.75

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 (62) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +51 -23
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/core/BranchManager.d.ts.map +1 -1
  5. package/dist/core/BranchManager.js +2 -0
  6. package/dist/core/BranchManager.js.map +1 -1
  7. package/dist/core/GitSync.d.ts.map +1 -1
  8. package/dist/core/GitSync.js +2 -0
  9. package/dist/core/GitSync.js.map +1 -1
  10. package/dist/core/HandoffManager.d.ts.map +1 -1
  11. package/dist/core/HandoffManager.js +2 -0
  12. package/dist/core/HandoffManager.js.map +1 -1
  13. package/dist/core/SessionManager.d.ts +4 -0
  14. package/dist/core/SessionManager.d.ts.map +1 -1
  15. package/dist/core/SessionManager.js +15 -4
  16. package/dist/core/SessionManager.js.map +1 -1
  17. package/dist/core/SourceTreeGuard.d.ts +69 -0
  18. package/dist/core/SourceTreeGuard.d.ts.map +1 -0
  19. package/dist/core/SourceTreeGuard.js +378 -0
  20. package/dist/core/SourceTreeGuard.js.map +1 -0
  21. package/dist/core/StateManager.d.ts.map +1 -1
  22. package/dist/core/StateManager.js +46 -9
  23. package/dist/core/StateManager.js.map +1 -1
  24. package/dist/core/types.d.ts +15 -0
  25. package/dist/core/types.d.ts.map +1 -1
  26. package/dist/core/types.js.map +1 -1
  27. package/dist/lifeline/TelegramLifeline.d.ts +8 -0
  28. package/dist/lifeline/TelegramLifeline.d.ts.map +1 -1
  29. package/dist/lifeline/TelegramLifeline.js +31 -1
  30. package/dist/lifeline/TelegramLifeline.js.map +1 -1
  31. package/dist/messaging/TelegramAdapter.d.ts +28 -0
  32. package/dist/messaging/TelegramAdapter.d.ts.map +1 -1
  33. package/dist/messaging/TelegramAdapter.js +79 -1
  34. package/dist/messaging/TelegramAdapter.js.map +1 -1
  35. package/dist/messaging/TelegramMarkdownFormatter.d.ts +76 -0
  36. package/dist/messaging/TelegramMarkdownFormatter.d.ts.map +1 -0
  37. package/dist/messaging/TelegramMarkdownFormatter.js +493 -0
  38. package/dist/messaging/TelegramMarkdownFormatter.js.map +1 -0
  39. package/dist/messaging/imessage/IMessageAdapter.d.ts +3 -6
  40. package/dist/messaging/imessage/IMessageAdapter.d.ts.map +1 -1
  41. package/dist/messaging/imessage/IMessageAdapter.js +20 -21
  42. package/dist/messaging/imessage/IMessageAdapter.js.map +1 -1
  43. package/dist/messaging/imessage/NativeBackend.d.ts +26 -0
  44. package/dist/messaging/imessage/NativeBackend.d.ts.map +1 -1
  45. package/dist/messaging/imessage/NativeBackend.js +133 -0
  46. package/dist/messaging/imessage/NativeBackend.js.map +1 -1
  47. package/dist/messaging/telegramFormatMetrics.d.ts +22 -0
  48. package/dist/messaging/telegramFormatMetrics.d.ts.map +1 -0
  49. package/dist/messaging/telegramFormatMetrics.js +38 -0
  50. package/dist/messaging/telegramFormatMetrics.js.map +1 -0
  51. package/dist/messaging/types.d.ts +7 -0
  52. package/dist/messaging/types.d.ts.map +1 -1
  53. package/dist/messaging/types.js.map +1 -1
  54. package/package.json +1 -1
  55. package/src/data/builtin-manifest.json +5 -5
  56. package/src/templates/scripts/telegram-reply.sh +52 -8
  57. package/upgrades/0.28.74.md +48 -0
  58. package/upgrades/0.28.75.md +29 -0
  59. package/upgrades/side-effects/0.28.75.md +53 -0
  60. package/upgrades/side-effects/source-tree-guard.md +340 -0
  61. package/upgrades/side-effects/telegram-markdown-renderer-pr1.md +124 -0
  62. /package/upgrades/side-effects/{capability-map-user-provenance-fallback.md → 0.28.73.md} +0 -0
@@ -0,0 +1,124 @@
1
+ # Side-Effects Review — Telegram markdown renderer (PR1: formatter module, disabled)
2
+
3
+ **Version / slug:** `telegram-markdown-renderer-pr1`
4
+ **Date:** `2026-04-24`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `not required (no block/allow surface, no wiring into send paths, shipped disabled)`
7
+
8
+ ## Summary of the change
9
+
10
+ PR1 of the two-PR plan in `docs/specs/TELEGRAM-MARKDOWN-RENDERER-SPEC.md` (approved 2026-04-24 by Justin via Telegram topic 8183). Adds a new pure-function module `src/messaging/TelegramMarkdownFormatter.ts` that ports Dawn's `telegram_format.py` (the-portal) to TypeScript, plus a Vitest test suite `tests/unit/telegram-markdown-formatter.test.ts` with 105 passing tests.
11
+
12
+ The module exports `formatForTelegram(text, mode)`, `format(text, mode)`, `lintTelegramMarkdown(text)`, and primitives (`escapeHtmlText`, `escapeHtmlAttribute`, `isSafeUrl`). It implements the spec's full 12-step markdown→Telegram-HTML pipeline, a balanced-paren URL scanner (Wikipedia-style parens), WHATWG URL scheme allowlist, distinct HTML-text vs HTML-attribute escapers, NUL + Supplementary-PUA-B stripping for sentinel-collision safety, a 32KB input guard that falls back to plain mode without byte loss (`conversionSkipped: true`), and a `legacy-passthrough` mode that returns input byte-for-byte unchanged with `parseMode: undefined` so callers retain their historical `parse_mode`.
13
+
14
+ **Critically, no send path is wired to this module.** `TelegramAdapter.ts` and `TelegramLifeline.ts` are untouched. The module is dead code at runtime until PR2 wires `apiCall()` behind the `telegramFormatMode` config accessor. PR2 ships with `legacy-passthrough` as the default, so PR1 has zero behavioral effect on any agent even after PR2 merges.
15
+
16
+ ## Decision-point inventory
17
+
18
+ This PR contains no runtime decision points — the module is not called by anything. The future decision points it enables (documented here for completeness; all are PR2 scope):
19
+
20
+ - `TelegramAdapter.apiCall` — formatter invocation conditional on `method === 'sendMessage' || method === 'editMessageText'`. **Not in this PR.**
21
+ - `TelegramLifeline.apiCall` — same. **Not in this PR.**
22
+ - Trusted-internal-caller allowlist for `html` mode. **Not in this PR.**
23
+
24
+ Decision points inside the module itself (pure functions, no runtime authority):
25
+
26
+ - `isSafeUrl(raw)` — scheme allowlist (http/https/tg/mailto). Pure function; refuses unsafe schemes by returning `null`. Caller decides what to do with the rejection (emit literal text).
27
+ - `lintTelegramMarkdown(text)` — pure detector returning string array. Advisory-only; no blocking authority in this PR.
28
+ - 32KB length guard in `formatForTelegram` — falls back to plain mode on oversized input. Pure transformation; no network/storage side effect.
29
+
30
+ ---
31
+
32
+ ## 1. Over-block
33
+
34
+ **What legitimate inputs does this change reject that it shouldn't?**
35
+
36
+ No block/allow surface in PR1 — module is not wired. Future-facing concerns the module itself introduces:
37
+
38
+ - `legacy-passthrough` mode emits no lint issues (by design — it's the rollback target and must be behaviorally identical to pre-cutover). A future operator might want lint-as-observation in passthrough mode; noted as open question for PR2.
39
+ - `isSafeUrl` rejects `javascript:`, `data:`, `file:`, `vbscript:`, and any non-allowlisted scheme. Rejected links become literal text (`[click](javascript:...)` rendered verbatim) — a legitimate agent-authored `tg://resolve?domain=foo` link is permitted (mode allowed). Wikipedia-style `https://...wiki/X_(y)` URLs parse correctly via the balanced-paren scanner (covered by fixture test).
40
+
41
+ ---
42
+
43
+ ## 2. Under-block
44
+
45
+ **What failure modes does this still miss?**
46
+
47
+ No block/allow surface in PR1. Module-internal known gaps (documented in spec, accepted as v1):
48
+
49
+ - Italic between emoji (`🎉*bold*🎉`) renders literal asterisks because the punctuation-class lookaround doesn't include emoji — accepted v1 per spec iteration-2 L4.
50
+ - `tg://` deep links are permitted (spec allowlists them); future spec may tighten.
51
+ - PUA-B range is stripped from input before sentinels are inserted — this means a user message legitimately containing PUA-B codepoints will lose those bytes. Near-zero real-world usage; accepted trade-off per spec. Not flagged as `truncated` because "byte loss" in the spec is reserved for the oversized-`<pre>` fallback.
52
+
53
+ ---
54
+
55
+ ## 3. Level-of-abstraction fit
56
+
57
+ **Is this at the right layer?**
58
+
59
+ Yes. The module is a pure string-transform library at the same layer as `MessageFormatter.ts`. It owns no I/O, no config reading, no network, no logging. It does not hold blocking authority. The decision "should this send happen at all?" stays with the adapter/lifeline chokepoints; the formatter only answers "given this text and mode, what bytes go on the wire?"
60
+
61
+ This is consistent with the spec's architectural intent: the formatter is a detector+transformer producing `{ text, parseMode, lintIssues }`, consumed downstream by the adapter which holds the authoritative send/no-send decision.
62
+
63
+ ---
64
+
65
+ ## 4. Signal vs authority compliance
66
+
67
+ Per `docs/signal-vs-authority.md`:
68
+
69
+ - **Lint is a signal, not an authority.** `lintTelegramMarkdown` returns canonical prose-string issues. It does not reject a send. The spec specifies lint-strict mode (which a downstream authority can consume to return 422) as PR2 scope; PR1's lint is purely observational.
70
+ - **Scheme allowlist is a deterministic transform, not a policy decision.** `isSafeUrl` is brittle-by-design (WHATWG URL + scheme set). It does not block a send — it causes a link to render as literal text. The outbound send still happens. This satisfies the "brittle logic must not hold blocking authority" rule: brittle logic (regex/parse) produces a transformation, not a decision to refuse a user action.
71
+ - **No sentinel, gate, watchdog, or sentinel-class name is introduced by this PR.**
72
+
73
+ Compliance: PASS.
74
+
75
+ ---
76
+
77
+ ## 5. Interactions
78
+
79
+ - No shadow/shadowed interactions in PR1 — module is not called by anything. Search confirms no existing import site.
80
+ - Module name collision check: `src/messaging/` contains `MessageFormatter.ts` (different purpose: envelope formatting) and no `TelegramMarkdownFormatter.ts` prior to this PR. No collision.
81
+ - Test file name: `tests/unit/telegram-markdown-formatter.test.ts`. No existing test file of that name.
82
+ - PR2 will introduce interactions with `TelegramAdapter.apiCall`, `TelegramLifeline.apiCall`, `MessageStore` (raw/sent fields), and `GitSyncTransport` (envelope flag). Those interactions get their own artifact at PR2 time.
83
+
84
+ ---
85
+
86
+ ## 6. External surfaces
87
+
88
+ **Does it change anything visible to other agents, other users, other systems?**
89
+
90
+ No. PR1 ships dead code. No route changes, no message format changes on the wire, no config schema changes applied (config fields `telegramFormatMode` / `telegramLintStrict` are spec'd but deliberately not added in PR1 — they land in PR2 alongside the wiring), no database changes, no envelope changes.
91
+
92
+ - Bot API: untouched — adapter still sends exactly the bytes it sends today with exactly the `parse_mode` it uses today.
93
+ - MessageStore: untouched.
94
+ - GitSyncTransport: untouched.
95
+ - Shell-script `.claude/scripts/telegram-reply.sh`: untouched.
96
+ - Agent dashboards / self-knowledge: untouched.
97
+
98
+ No timing dependencies, no conversation state dependencies.
99
+
100
+ ---
101
+
102
+ ## 7. Rollback cost
103
+
104
+ **If this turns out wrong in production, what's the back-out?**
105
+
106
+ Trivial. PR1 is a code-only addition with no runtime invocation. Rollback options in order of cost:
107
+
108
+ 1. **Do nothing.** The module is not on any call path; a latent bug is invisible until PR2.
109
+ 2. **Revert the merge commit.** Standard `git revert` — affects only two new files. No data migration, no agent state repair, no config flip.
110
+ 3. **Fix forward.** The module is pure functions with 105 unit tests; most fixes ship as deltas.
111
+
112
+ PR2 itself is governed by the spec's staged-rollout (ships with `legacy-passthrough` default; canary via config flip). That's PR2's rollback story — out of scope for this artifact.
113
+
114
+ ---
115
+
116
+ ## Second-pass review
117
+
118
+ Not required. PR1 has no block/allow surface, no session-lifecycle surface, no sentinel/gate/watchdog, no coherence/idempotency/trust change, and is shipped disabled. High-risk criteria from Phase 5 are not met.
119
+
120
+ ## Spec linkage
121
+
122
+ - Approved spec: `docs/specs/TELEGRAM-MARKDOWN-RENDERER-SPEC.md` (approved 2026-04-24T20:53:47Z by Justin via Telegram topic 8183).
123
+ - Convergence report: `docs/specs/reports/telegram-markdown-renderer-convergence.md`.
124
+ - Dawn reference impl: `the-portal/.claude/scripts/telegram_format.py` (merged 2026-04-24T17:57Z).