instar 1.3.930 → 1.3.932
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/dashboard/subscriptions.js +60 -6
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +41 -10
- package/dist/commands/server.js.map +1 -1
- package/dist/coordination/FollowMeConsumerBackoffStore.d.ts +36 -0
- package/dist/coordination/FollowMeConsumerBackoffStore.d.ts.map +1 -0
- package/dist/coordination/FollowMeConsumerBackoffStore.js +96 -0
- package/dist/coordination/FollowMeConsumerBackoffStore.js.map +1 -0
- package/dist/core/QuotaPoller.d.ts.map +1 -1
- package/dist/core/QuotaPoller.js +3 -14
- package/dist/core/QuotaPoller.js.map +1 -1
- package/dist/core/SubscriptionAccountEmailRepair.d.ts +19 -0
- package/dist/core/SubscriptionAccountEmailRepair.d.ts.map +1 -0
- package/dist/core/SubscriptionAccountEmailRepair.js +58 -0
- package/dist/core/SubscriptionAccountEmailRepair.js.map +1 -0
- package/dist/core/SubscriptionPool.d.ts +80 -6
- package/dist/core/SubscriptionPool.d.ts.map +1 -1
- package/dist/core/SubscriptionPool.js +201 -29
- package/dist/core/SubscriptionPool.js.map +1 -1
- package/dist/core/WriteDomainRegistry.d.ts.map +1 -1
- package/dist/core/WriteDomainRegistry.js +4 -0
- package/dist/core/WriteDomainRegistry.js.map +1 -1
- package/dist/core/resolveFollowMeEnrollTarget.d.ts +1 -0
- package/dist/core/resolveFollowMeEnrollTarget.d.ts.map +1 -1
- package/dist/core/resolveFollowMeEnrollTarget.js +37 -19
- package/dist/core/resolveFollowMeEnrollTarget.js.map +1 -1
- package/dist/messaging/slack/SlackApiClient.d.ts +8 -0
- package/dist/messaging/slack/SlackApiClient.d.ts.map +1 -1
- package/dist/messaging/slack/SlackApiClient.js +44 -2
- package/dist/messaging/slack/SlackApiClient.js.map +1 -1
- package/dist/server/AgentServer.d.ts +5 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +74 -24
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/routes.d.ts +17 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +202 -29
- package/dist/server/routes.js.map +1 -1
- package/dist/testing/selfActionRegistry.d.ts.map +1 -1
- package/dist/testing/selfActionRegistry.js +28 -0
- package/dist/testing/selfActionRegistry.js.map +1 -1
- package/package.json +2 -1
- package/src/data/builtin-manifest.json +47 -47
- package/upgrades/1.3.931.md +46 -0
- package/upgrades/1.3.932.md +29 -0
- package/upgrades/side-effects/slack-outbound-transport-recovery.md +14 -0
- package/upgrades/side-effects/subscription-account-email-invariant.md +169 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Side-effects Review — Slack outbound transport recovery
|
|
2
|
+
|
|
3
|
+
## Class review
|
|
4
|
+
|
|
5
|
+
The missing standard was transport recovery after interface changes: retrying the same undici pool was not evidence of a fresh network path. The process gap was no focused fault-injection check for repeated `fetch failed` across a Wi-Fi transition.
|
|
6
|
+
|
|
7
|
+
## Decision
|
|
8
|
+
|
|
9
|
+
The client keeps normal API retry behavior. On three consecutive network fetch failures it destroys and replaces a Slack-client-owned undici dispatcher supplied per request; unrelated HTTP clients are not affected. Successful calls clear the streak.
|
|
10
|
+
|
|
11
|
+
## Evidence
|
|
12
|
+
|
|
13
|
+
- Tier 1 focused Socket Mode reconnect suite: 17/17 passing.
|
|
14
|
+
- ELI16: stale sockets are thrown away after three failed tries; the next try gets a fresh network path.
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Side-Effects Review — Subscription account email invariant
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `subscription-account-email-invariant`
|
|
4
|
+
**Date:** `2026-07-23`
|
|
5
|
+
**Author:** `Instar Agent (instar-codey)`
|
|
6
|
+
**Second-pass reviewer:** `updater_deferral_review (independent, CONCUR)`
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
New subscription registrations prove their provider email from the credential
|
|
11
|
+
slot; old email-less rows receive one bounded boot repair and otherwise appear
|
|
12
|
+
as explicit gaps. Follow-me resolution returns honest missing/conflict/not-found
|
|
13
|
+
codes. Its autonomous consumer now uses durable pair-scoped finite backoff.
|
|
14
|
+
|
|
15
|
+
## Decision-point inventory
|
|
16
|
+
|
|
17
|
+
- `POST /subscription-pool` — modify — provider proof, not caller input, admits identity.
|
|
18
|
+
- `resolveFollowMeEnrollTarget` — modify — unanimous holder identity or typed refusal.
|
|
19
|
+
- `driveDeliveredFollowMeEnrollments` — modify — persisted eligibility schedule bounds retries.
|
|
20
|
+
|
|
21
|
+
## 1. Over-block
|
|
22
|
+
|
|
23
|
+
A non-Anthropic registration is refused until that provider has a real identity
|
|
24
|
+
adapter. This is intentional: accepting an unproved email would recreate the
|
|
25
|
+
incident class. A temporarily unavailable Anthropic profile endpoint also
|
|
26
|
+
refuses registration; an already complete account remains usable.
|
|
27
|
+
|
|
28
|
+
## 2. Under-block
|
|
29
|
+
|
|
30
|
+
Production account creation and identity repair are both module-private
|
|
31
|
+
symbol commits held by `SubscriptionAccountEmailRegistrar`; generic `update()`
|
|
32
|
+
has no email field. The only direct fixture seam throws outside `NODE_ENV=test`.
|
|
33
|
+
Legacy
|
|
34
|
+
email-less rows remain readable only through `listEmailGaps()` and never enter
|
|
35
|
+
selectors or normal account reads.
|
|
36
|
+
|
|
37
|
+
The finite retry row persists a semantic holder-email/gap/mandate evidence key.
|
|
38
|
+
An unchanged pair parks after four attempts; changed identity or authority
|
|
39
|
+
evidence deletes that episode and permits one new bounded episode. The live
|
|
40
|
+
sweep also deduplicates all applicable mandates to one attempt per pair.
|
|
41
|
+
|
|
42
|
+
## 3. Level-of-abstraction fit
|
|
43
|
+
|
|
44
|
+
Provider truth is resolved at the registration boundary using the existing
|
|
45
|
+
credential identity oracle. The pool owns validation/persistence, the resolver
|
|
46
|
+
owns holder agreement, and the consumer store owns retry eligibility. No
|
|
47
|
+
parallel enrollment authority was introduced.
|
|
48
|
+
|
|
49
|
+
## 4. Signal vs authority compliance
|
|
50
|
+
|
|
51
|
+
**Required reference:** [docs/signal-vs-authority.md](../../docs/signal-vs-authority.md)
|
|
52
|
+
|
|
53
|
+
- [x] No — this change produces a signal consumed by an existing smart gate.
|
|
54
|
+
|
|
55
|
+
The identity oracle supplies evidence; the existing enrollment expected-email
|
|
56
|
+
gate remains the authority. Retry scheduling is an enumerable finite-state
|
|
57
|
+
invariant, not a language heuristic.
|
|
58
|
+
|
|
59
|
+
## 4b. Judgment-point check
|
|
60
|
+
|
|
61
|
+
No static heuristic is added at a competing-signals decision point. Email
|
|
62
|
+
presence, canonical equality, mandate expiry, and attempt number are enumerable
|
|
63
|
+
invariants.
|
|
64
|
+
|
|
65
|
+
## 5. Interactions
|
|
66
|
+
|
|
67
|
+
- **Shadowing:** direct registration validates shape and credential-field
|
|
68
|
+
smuggling before the network oracle so malformed requests keep their existing
|
|
69
|
+
deterministic 400 response.
|
|
70
|
+
- **Double-fire:** one `AgentServer` sweep remains the only live delivered-
|
|
71
|
+
mandate caller; the backoff store does not start its own timer.
|
|
72
|
+
- **Races:** the existing sweep single-flight encloses store reads and writes;
|
|
73
|
+
persistence uses tmp+rename. Legacy repair CAS-checks the independent
|
|
74
|
+
credential-ledger epoch before and after the provider probe.
|
|
75
|
+
- **Feedback loops:** failure advances monotonically through three delays to
|
|
76
|
+
parked. Success clears the pair. Identity failures wake only when holder
|
|
77
|
+
evidence becomes unanimous; authority failures wake only when the applicable
|
|
78
|
+
mandate set changes.
|
|
79
|
+
|
|
80
|
+
## 6. External surfaces
|
|
81
|
+
|
|
82
|
+
The pool GET adds `emailGaps`; complete `accounts` remains the normal list.
|
|
83
|
+
Follow-me 409 bodies add `code` and `accountId` while keeping `error`. The
|
|
84
|
+
dashboard shows the exact actionable error, and the PIN-gated repair route
|
|
85
|
+
provides the phone-complete remediation. A machine-local JSON backoff file is
|
|
86
|
+
added. No credential, token, config-home content, or raw provider response is
|
|
87
|
+
replicated or displayed.
|
|
88
|
+
|
|
89
|
+
Boot reconciliation shares one oracle instance with the ledger, enrollment,
|
|
90
|
+
and HTTP routes. When legacy gaps exist, repair runs against the preserved
|
|
91
|
+
independent binding and destructive ledger seeding is skipped; complete pools
|
|
92
|
+
may seed normally. The server starts without waiting, while inventory-tagged
|
|
93
|
+
identity mutation routes return a stable temporary 503 until the bounded
|
|
94
|
+
reconciliation finishes.
|
|
95
|
+
|
|
96
|
+
The touched operator action stays phone-completable in the existing account
|
|
97
|
+
matrix; no new laptop-only action was added.
|
|
98
|
+
|
|
99
|
+
## 6b. Operator-surface quality
|
|
100
|
+
|
|
101
|
+
1. **Leads with the primary action:** yes; the existing matrix action remains in-place.
|
|
102
|
+
2. **Zero raw internals as primary content:** yes; the server code is not rendered, only plain corrective text.
|
|
103
|
+
3. **Destructive actions de-emphasized:** yes; no destructive action was added.
|
|
104
|
+
4. **Plain language + phone width:** yes; the change replaces one status string in the existing responsive cell without adding layout width.
|
|
105
|
+
|
|
106
|
+
## 7. Multi-machine posture
|
|
107
|
+
|
|
108
|
+
**Machine-local BY DESIGN:** credential proof and retry act on the credential
|
|
109
|
+
slot and delivered mandate held by that target machine. Non-credential account
|
|
110
|
+
metadata remains replicated through `subscription-account-meta`, and pool reads
|
|
111
|
+
remain proxied/merged through `?scope=pool`. No new user-facing notice or URL is
|
|
112
|
+
generated. The durable retry row does not follow topic transfer because it is
|
|
113
|
+
bound to a physical account-machine pair.
|
|
114
|
+
|
|
115
|
+
## 8. Rollback cost
|
|
116
|
+
|
|
117
|
+
Revert and ship a patch. The additive `emailGaps` field is harmless to old
|
|
118
|
+
clients. The backoff JSON may be left on disk; old code ignores it. Repaired
|
|
119
|
+
emails are truthful provider-attested metadata and do not require reversal.
|
|
120
|
+
|
|
121
|
+
## Conclusion
|
|
122
|
+
|
|
123
|
+
The change closes the incident at its three recurring seams: incomplete
|
|
124
|
+
registration, misleading refusal, and unbounded retry. Identity writes are
|
|
125
|
+
registrar-owned, legacy repair requires independent stable binding evidence,
|
|
126
|
+
and the live hammering loop is structurally bounded with causal wake.
|
|
127
|
+
|
|
128
|
+
## Second-pass review (if required)
|
|
129
|
+
|
|
130
|
+
**Reviewer:** updater_deferral_review
|
|
131
|
+
**Independent read of the artifact:** CONCUR after three blocking passes. The
|
|
132
|
+
final pass independently verified the real route-capability inventory, bounded
|
|
133
|
+
deadline repair, and pool-scope gap aggregation (18 focused tests green).
|
|
134
|
+
|
|
135
|
+
## Evidence pointers
|
|
136
|
+
|
|
137
|
+
The invariant-focused slices are green: 157 unit tests, 87 integration tests,
|
|
138
|
+
and 23 E2E tests. The production build and the full lint chain are green.
|
|
139
|
+
|
|
140
|
+
The full integration configuration is green: 453 files passed, 2 skipped;
|
|
141
|
+
3,714 tests passed and 12 skipped. The full E2E configuration completed after
|
|
142
|
+
disabling pnpm's dependency auto-repair for the nested preflight harness:
|
|
143
|
+
314 files passed, 1 skipped; 2,981 tests passed, 8 skipped, and 3 todo. Two
|
|
144
|
+
pre-existing host-timing scenarios remained red: the ultracode argv delivery
|
|
145
|
+
probe and the Telegram respawn readiness probe. The exact nested dev-preflight
|
|
146
|
+
E2E is green when run against the stable dependency tree.
|
|
147
|
+
|
|
148
|
+
The default configuration was also exercised end-to-end. Its invariant-owned
|
|
149
|
+
tests stayed green; unrelated headless-spawn and host-timing failures remained,
|
|
150
|
+
and the first run exposed the same nested pnpm auto-repair harness issue before
|
|
151
|
+
the stable rerun of the dedicated integration and E2E configurations.
|
|
152
|
+
|
|
153
|
+
## Class-Closure Declaration (display-only mirror)
|
|
154
|
+
|
|
155
|
+
`defectClass: unbounded-self-action`, `closure: guard`,
|
|
156
|
+
`guardEvidence: { enforcementType: ratchet, citation:
|
|
157
|
+
tests/unit/follow-me-consumer-backoff-store.test.ts, howCaught: a permanently
|
|
158
|
+
failing account-machine pair advances through three bounded delays and reaches
|
|
159
|
+
a durable parked steady state after its fourth attempt, so an every-minute
|
|
160
|
+
failure edge cannot remain eligible }`. Repository-wide self-action convergence
|
|
161
|
+
coverage remains in `tests/unit/self-action-convergence.test.ts`.
|
|
162
|
+
|
|
163
|
+
## Mini-node continuation checkpoint
|
|
164
|
+
|
|
165
|
+
The email-invariant lane was resumed on the Mini, its stale fixtures were
|
|
166
|
+
updated for provider-attested email identity, and the full ceremony/test pass
|
|
167
|
+
above was completed. The Claude subscription-pinning E2E now explicitly pins
|
|
168
|
+
its claimed framework, so a Codex-hosted runner cannot turn the resolver into
|
|
169
|
+
the correct non-Claude no-op.
|