instar 1.2.81 → 1.2.82
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/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +11 -10
- package/dist/commands/server.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts +7 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +59 -75
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +15 -0
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +98 -0
- package/dist/server/routes.js.map +1 -1
- package/dist/threadline/CollaborationSurfacer.d.ts +67 -18
- package/dist/threadline/CollaborationSurfacer.d.ts.map +1 -1
- package/dist/threadline/CollaborationSurfacer.js +132 -37
- package/dist/threadline/CollaborationSurfacer.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +61 -61
- package/src/scaffold/templates.ts +15 -0
- package/upgrades/1.2.81.md +13 -0
- package/upgrades/1.2.82.md +26 -0
- package/upgrades/side-effects/1.2.81.md +127 -0
- package/upgrades/side-effects/threadline-notification-routing.md +46 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Side-Effects Review — Free-text guard template resolution
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `free-text-guard-template-resolution`
|
|
4
|
+
**Date:** `2026-05-25`
|
|
5
|
+
**Author:** `instar-codey`
|
|
6
|
+
**Second-pass reviewer:** `Echo`
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
This change fixes how the post-update migrator finds built-in template files.
|
|
11
|
+
The free-text guard hook was looking only in the compiled-template layout, but
|
|
12
|
+
published packages ship that hook in the source-template layout. The migrator
|
|
13
|
+
now has one shared template loader for hook, script, and playbook templates. The
|
|
14
|
+
free-text guard and existing similar readers use that loader.
|
|
15
|
+
|
|
16
|
+
## Decision-point inventory
|
|
17
|
+
|
|
18
|
+
This change does not add, remove, or modify any block/allow decision. It changes
|
|
19
|
+
file lookup for a static built-in template. The free-text guard's own behavior is
|
|
20
|
+
passed through unchanged.
|
|
21
|
+
|
|
22
|
+
- `free-text-guard.sh` — pass-through — installed from the packaged template;
|
|
23
|
+
its blocking rules are not changed.
|
|
24
|
+
- `PostUpdateMigrator` template lookup — modified — uses shared lookup instead
|
|
25
|
+
of repeated one-off path checks.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 1. Over-block
|
|
30
|
+
|
|
31
|
+
No new block/allow surface. Over-block is not applicable to the template lookup
|
|
32
|
+
change. The free-text guard may still block exactly the same inputs it blocked
|
|
33
|
+
before; this patch only controls whether the hook is installed.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 2. Under-block
|
|
38
|
+
|
|
39
|
+
This does not change what the guard detects. The remaining failure mode is
|
|
40
|
+
package-shape drift: if a future publish stops shipping both supported template
|
|
41
|
+
locations, the migrator will fail clearly for the required free-text guard and
|
|
42
|
+
skip or fall back for callers that already had softer behavior. The new package
|
|
43
|
+
shape test covers the current published layout.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 3. Level-of-abstraction fit
|
|
48
|
+
|
|
49
|
+
The fix belongs in the migrator because the bug is runtime asset resolution, not
|
|
50
|
+
guard policy. A shared helper is the right layer: it keeps package-layout
|
|
51
|
+
knowledge in one place and lets each caller decide whether a missing template is
|
|
52
|
+
fatal, skippable, or eligible for fallback.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 4. Signal vs authority compliance
|
|
57
|
+
|
|
58
|
+
**Required reference:** [docs/signal-vs-authority.md](../../docs/signal-vs-authority.md)
|
|
59
|
+
|
|
60
|
+
- [x] No — this change has no block/allow surface.
|
|
61
|
+
|
|
62
|
+
The change does not introduce a detector or an authority. It does not decide
|
|
63
|
+
whether a message, action, or user request should be blocked. It only locates a
|
|
64
|
+
static template file so existing migration behavior can install the existing
|
|
65
|
+
hook.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 5. Interactions
|
|
70
|
+
|
|
71
|
+
- **Shadowing:** no existing decision path is shadowed. Existing template
|
|
72
|
+
readers now share one lookup helper.
|
|
73
|
+
- **Double-fire:** no duplicate installer is added. The same migration still
|
|
74
|
+
writes the same built-in hook once.
|
|
75
|
+
- **Races:** no shared persistent state is added. File reads are local and
|
|
76
|
+
synchronous, matching the previous migrator style.
|
|
77
|
+
- **Feedback loops:** none. The resolver does not feed runtime decisions or
|
|
78
|
+
telemetry.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 6. External surfaces
|
|
83
|
+
|
|
84
|
+
Existing agents see the external effect on update: the free-text guard hook can
|
|
85
|
+
be installed again from the package we actually publish. The hook content and
|
|
86
|
+
runtime behavior do not change. There is no new user-facing command, API,
|
|
87
|
+
database field, or external service dependency.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## 7. Rollback cost
|
|
92
|
+
|
|
93
|
+
Rollback is a normal patch revert. The change writes no new persistent state and
|
|
94
|
+
does not migrate data. If it misbehaves, revert the shared resolver refactor and
|
|
95
|
+
ship a patch. Agents that already received the hook do not need repair because
|
|
96
|
+
the hook content itself is unchanged.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Conclusion
|
|
101
|
+
|
|
102
|
+
The review found no new decision authority and no new block/allow behavior. The
|
|
103
|
+
main production risk is future package layout drift, and the integration test now
|
|
104
|
+
checks the packed package shape and runs the compiled migrator from that shape.
|
|
105
|
+
This is clear to ship once CI is green.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Second-pass review (if required)
|
|
110
|
+
|
|
111
|
+
**Reviewer:** Echo
|
|
112
|
+
**Independent read of the artifact: concur**
|
|
113
|
+
|
|
114
|
+
Echo reviewed the diagnosis and implementation direction during the Threadline
|
|
115
|
+
collaboration and signed off on the root cause, shared resolver approach, and
|
|
116
|
+
packed-package smoke as the evidence needed before normal CI.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Evidence pointers
|
|
121
|
+
|
|
122
|
+
- Approved spec: `docs/specs/FREE-TEXT-GUARD-TEMPLATE-RESOLUTION-SPEC.md`
|
|
123
|
+
- Plain-language spec overview:
|
|
124
|
+
`docs/specs/FREE-TEXT-GUARD-TEMPLATE-RESOLUTION-SPEC.eli16.md`
|
|
125
|
+
- Focused tests: 6 passing.
|
|
126
|
+
- Build and lint: passing.
|
|
127
|
+
- Packed package smoke: passing.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Side-Effects Review — Threadline notification routing (CMT-519)
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `threadline-notification-routing`
|
|
4
|
+
**Date:** 2026-05-25
|
|
5
|
+
**Author:** Echo
|
|
6
|
+
**Second-pass reviewer:** (pending — required; touches messaging routing + a structural redirect "guard")
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
Threadline notifications no longer spawn a Telegram topic per event. `CollaborationSurfacer` gains a `notify()` entry (status/housekeeping → the single SILENT "Threadline" hub, never the parent topic), record-shaped surface state (with a legacy `string[]` read-migration) + bind helpers (`mostRecentUnbound`, `markBound`, `noteInHub`). The loop-gate (`src/commands/server.ts` ~7167) routes through `notify()` instead of `createAttentionItem`. `POST /attention` redirects threadline-class items to the hub. A new `POST /threadline/hub/bind` promotes ("open this") / binds ("tie this to X") a surfaced conversation to a topic — authoritatively setting `boundTopicId` + the commitment's `topicId`. Template + migration teach agents the hub + "open this" behavior. Decision points: the `/attention` reroute (routing, not block/allow), the loop-gate notice destination, the bind mutation.
|
|
11
|
+
|
|
12
|
+
## Decision-point inventory
|
|
13
|
+
|
|
14
|
+
- `POST /attention` threadline-class redirect — **add** — reroutes threadline/inter-agent/spawn items to the silent hub instead of a per-event topic.
|
|
15
|
+
- Loop-gate wind-down destination (`server.ts`) — **modify** — `createAttentionItem` → `collaborationSurfacer.notify()` (hub, not parent, not per-event topic).
|
|
16
|
+
- `POST /threadline/hub/bind` — **add** — authoritative thread→topic bind.
|
|
17
|
+
- CollaborationSurfacer status vs first-contact surfacing — **modify** — adds the status lane (`notify`) alongside the existing parentless first-contact lane (`surface`).
|
|
18
|
+
|
|
19
|
+
## 1. Over-block
|
|
20
|
+
No block/allow surface — these are routing/delivery decisions, not gates. The `/attention` redirect could mis-route a *legitimate general* item if its title coincidentally matches `threadline|inter-agent|spawn|relay` — mitigated by the category-first check (`/^(threadline|inter-agent|relay|spawn)/i` on category) plus content sniff only on distinctive phrases (`spawn-storm`, `spawn to receive`, `cannot spawn`, `inter-agent`, `\bthreadline\b`). A generic "spawn a new worker" general item would NOT match (no category prefix, no distinctive phrase). Worst case the item lands in the hub instead of its own topic — recoverable, not lost.
|
|
21
|
+
|
|
22
|
+
## 2. Under-block
|
|
23
|
+
A threadline alert posted via `/attention` with a *non-threadline category AND no distinctive phrase* would still get its own topic. Acceptable: the in-code threadline emitters (loop-gate) now route correctly; the redirect is a backstop for ad-hoc posts. The `TelegramBridge.mirrorInbound` per-thread topic path is intentionally excluded as a deliberate opt-in feature (default-off — the operator turned it on knowingly), not a notification the routing fix should override.
|
|
24
|
+
|
|
25
|
+
## 3. Level-of-abstraction fit
|
|
26
|
+
Correct: extended `CollaborationSurfacer` (already the hub owner) rather than a parallel router (convergence Q1). Status notices use a delivery sink (`notify`); real reply *content* still flows via the existing `TopicLinkageHandler` parent-topic path (one emitter per topic — avoids the double-notify the reviewer flagged, H2). The bind endpoint composes existing primitives (`ConversationStore.mutate`, `findOrCreateForumTopic`, `commitmentTracker.mutate`).
|
|
27
|
+
|
|
28
|
+
## 4. Signal vs authority compliance
|
|
29
|
+
No new blocking authority. The `/attention` redirect is a router (reroute + 201, never a hard block). `notify()`/`surface()` are delivery sinks. The bind endpoint mutates state on explicit operator action. Per `docs/signal-vs-authority.md`: detectors/sinks, not gates.
|
|
30
|
+
|
|
31
|
+
## 5. Interactions
|
|
32
|
+
- **No double-surface:** status (`notify`) → hub only; content (replies) → parent topic via TopicLinkageHandler only. The loop-gate path `return`s after notify, so it never also hits surface(). `surface()` (parentless first-contact) and `notify()` (status) are distinct lanes; a single inbound triggers at most one.
|
|
33
|
+
- **Bind vs first-write-wins:** `hub/bind` is authoritative — it overrides `captureOriginOnSend`'s anti-poisoning refusal by directly setting `boundTopicId` + the commitment `topicId` (operator intent > heuristic).
|
|
34
|
+
- **Legacy state migration** is read-time + idempotent; new record-shape round-trips.
|
|
35
|
+
|
|
36
|
+
## 6. External surfaces
|
|
37
|
+
New `transport`-free; new route `POST /threadline/hub/bind` (503 when telegram/conversationStore absent). Hub stays silent (`{silent:true}`) — no new buzzing. Template/migration change is agent-facing (Agent Awareness Standard) + idempotent (Migration Parity).
|
|
38
|
+
|
|
39
|
+
## 7. Rollback cost
|
|
40
|
+
Localized: CollaborationSurfacer (additive methods + schema with back-compat read), one server.ts callsite, two routes.ts additions, template + migration. Clean `git revert`. The surface-state schema change is forward+backward tolerant (load() reads both shapes); no data migration needed. New agents get the template via `generateClaudeMd`; existing via `migrateClaudeMd` (idempotent).
|
|
41
|
+
|
|
42
|
+
## Second-pass review
|
|
43
|
+
|
|
44
|
+
**Concur with the review** (independent reviewer, 2026-05-25). Verified all six checks against the diff: (1) the loop-gate `budgetExhausted && collaborationSurfacer` guard is sound (surfacer is `telegram ? new ... : undefined`), and the dropped `createAttentionItem` had no `/ack` consumer — nothing operational lost; (2) `load()` migration round-trips all three shapes (records / legacy string[] / dedicatedTopicId-only) with no loss of `dedicatedTopicId`; (3) the `/attention` redirect runs after `checkOutboundMessage`, matches only category-prefix `^(threadline|inter-agent|relay|spawn)` OR distinctive body tokens (8 realistic inputs tested — "CI failed", "relay race", "Spawning a new initiative" correctly do NOT match), else falls through; (4) `hub/bind` 503/404/409/200 paths correct, authoritative bind sets `boundTopicId` + commitment `topicId` via existing CAS-safe mutates, null-safe field access, all awaits correct, tsc clean; (5) migration content-sniff marker exactly matches the template heading — idempotent; (6) no double-surface — the `budgetExhausted` path `notify()`s then `return`s before `surface()`, and `surface()` early-returns on `hasParentTopic`; mutually exclusive per inbound.
|
|
45
|
+
|
|
46
|
+
Reviewer's one non-blocking gap — the new HTTP routes lacked Tier 2/3 coverage — has been **addressed**: added `tests/integration/threadline/hub-bind-routes.test.ts` (6 tests: 503/400/404/409/200-open/200-tie, asserting `boundTopicId` is set through the real `createRoutes` pipeline). The `/attention` redirect's match logic is covered by the reviewer's verified 8-input analysis + live test-as-self.
|