instar 1.3.861 → 1.3.863

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.
@@ -0,0 +1,40 @@
1
+ /**
2
+ * queuedNotice — the user-facing "your message was queued" text the lifeline
3
+ * sends when it cannot forward a message to the server right now.
4
+ *
5
+ * Why this is its own module (bug fix, reported by peer agent Luna/Sagemind
6
+ * 2026-07-17): the lifeline has TWO distinct "couldn't deliver right now"
7
+ * states, and they must never be conflated in the user-facing text:
8
+ *
9
+ * - serverHealthy === false → the server is genuinely down / unreachable.
10
+ * Historical wording: "Server is temporarily down. …" (accurate).
11
+ *
12
+ * - serverHealthy === true → the server is confirmed UP, but THIS forward
13
+ * failed (a transient 10s timeout / 5xx / 503-boot / connection blip).
14
+ * The old code told the user "Server is restarting." — which is false
15
+ * and alarming: nothing restarted. This branch is a reconnect, not a
16
+ * restart, so the notice must say so.
17
+ *
18
+ * Centralizing the wording here (instead of three inline if/else blocks in
19
+ * TelegramLifeline) makes the healthy-vs-down distinction a single, tested
20
+ * decision — the message and photo/file handlers all route through it.
21
+ */
22
+ /**
23
+ * Build the user-facing queued-notice text.
24
+ *
25
+ * @param kind which noun to use ("message" | "photo" | "file")
26
+ * @param queueLength current number of items in the durable queue
27
+ * @param serverHealthy the supervisor's live health verdict at send time
28
+ */
29
+ export function buildQueuedNotice(kind, queueLength, serverHealthy) {
30
+ const noun = kind; // 'message' | 'photo' | 'file' are already the display nouns
31
+ if (serverHealthy) {
32
+ // Healthy server + failed forward → reconnecting, NOT restarting.
33
+ return (`I'm having trouble reaching my server right now — your ${noun} is queued ` +
34
+ `(${queueLength} in queue) and I'll deliver it as soon as I reconnect.`);
35
+ }
36
+ // Genuinely-down server (unchanged wording — preserves the accurate message).
37
+ return (`Server is temporarily down. Your ${noun} has been queued (${queueLength} in queue). ` +
38
+ `It will be delivered when the server recovers.`);
39
+ }
40
+ //# sourceMappingURL=queuedNotice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queuedNotice.js","sourceRoot":"","sources":["../../src/lifeline/queuedNotice.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAoB,EACpB,WAAmB,EACnB,aAAsB;IAEtB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,6DAA6D;IAChF,IAAI,aAAa,EAAE,CAAC;QAClB,kEAAkE;QAClE,OAAO,CACL,0DAA0D,IAAI,aAAa;YAC3E,IAAI,WAAW,wDAAwD,CACxE,CAAC;IACJ,CAAC;IACD,8EAA8E;IAC9E,OAAO,CACL,oCAAoC,IAAI,qBAAqB,WAAW,cAAc;QACtF,gDAAgD,CACjD,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.3.861",
3
+ "version": "1.3.863",
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-07-17T08:25:10.761Z",
5
- "instarVersion": "1.3.861",
4
+ "generatedAt": "2026-07-17T20:16:29.908Z",
5
+ "instarVersion": "1.3.863",
6
6
  "entryCount": 202,
7
7
  "entries": {
8
8
  "hook:session-start": {
@@ -1594,7 +1594,7 @@
1594
1594
  "type": "subsystem",
1595
1595
  "domain": "communication",
1596
1596
  "sourcePath": "src/lifeline/TelegramLifeline.ts",
1597
- "contentHash": "6087c3cab4cf30a3bb11d43df640d8338b6cf45a6c26cf4d16063f7858f6a4b1",
1597
+ "contentHash": "a7a7255d17ab19f681b96dc5334ce44d86ea07a1f285b2bf8f9e19e9a35e19ab",
1598
1598
  "since": "2025-01-01"
1599
1599
  },
1600
1600
  "subsystem:orphan-process-reaper": {
@@ -0,0 +1,27 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ When the session pool chooses the current machine for a new conversation, its
9
+ ownership row now advances from `placing` to `active` after the established
10
+ local injection or spawn path succeeds.
11
+
12
+ ## What to Tell Your User
13
+
14
+ A conversation started on the machine that receives it no longer remains
15
+ stuck in a “starting” ownership state after it is already running.
16
+
17
+ ## Summary of New Capabilities
18
+
19
+ No new setting. This repairs the existing session-pool placement lifecycle.
20
+
21
+ ## Evidence
22
+
23
+ - Unit and integration coverage verifies the guarded transition, idempotence,
24
+ and the no-confirm-on-failed-spawn ordering.
25
+ - A live single-agent CROSS-MACHINE laptop/Mini test advanced a fresh Mini
26
+ placement from `placing` to `active` at epoch 2.
27
+ - Focused tests and TypeScript build pass.
@@ -0,0 +1,65 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ When the lifeline can't hand a message off to the server but the server is
9
+ confirmed **healthy** (a transient timeout / 5xx / connection blip on a single
10
+ forward), the queued-message notice no longer says the false, alarming
11
+ "Server is restarting." It now reflects the real state: "I'm having trouble
12
+ reaching my server right now — your message is queued (N in queue) and I'll
13
+ deliver it as soon as I reconnect." The genuinely-down message
14
+ ("Server is temporarily down…") is unchanged. The message, photo, and file
15
+ handlers all route through one shared helper (`buildQueuedNotice`) so the two
16
+ states can't drift apart again.
17
+
18
+ ## What to Tell Your User
19
+
20
+ If a message of yours briefly can't be delivered while my server is actually
21
+ up, you'll now see an honest "reconnecting, your message is queued" note
22
+ instead of a scary "Server is restarting" alarm. Nothing about delivery
23
+ changed — your message was never lost; it queues and delivers as before. This
24
+ only fixes the wording so it stops claiming a restart that never happened.
25
+
26
+ ## Summary of New Capabilities
27
+
28
+ No new setting. This is a bug fix to an existing user-facing notice.
29
+
30
+ ## Evidence
31
+
32
+ - New unit test (`tests/unit/lifeline/queuedNotice.test.ts`, 8 cases) proves the
33
+ healthy-but-forward-failed branch never says "restart" or "temporarily down"
34
+ and always says "reconnect", and that the genuinely-down wording is preserved
35
+ byte-for-byte.
36
+ - Full lifeline unit suite passes (18 files / 160 tests); TypeScript build and
37
+ `pnpm build` are clean; exactly one "Server is restarting" string remains in
38
+ the compiled lifeline (the separate callback-query server-down case, out of
39
+ scope).
40
+
41
+ ## The problem in one breath
42
+
43
+ The lifeline is the small always-on process that watches Telegram and hands your messages to my main server. When it can't hand a message off right now, it queues the message and sends you a heads-up. There are two very different reasons a hand-off can fail — the server is genuinely down, OR the server is perfectly healthy and just one hand-off blipped (a brief network timeout). The old code sent the SAME scary "Server is restarting. Your message has been queued…" text for BOTH cases. So when the server was confirmed up and running, you could still get told it was restarting — which never happened. It's harmless (your message is never lost — it queues and delivers) but it erodes trust, because the agent cried "restart" when nothing restarted.
44
+
45
+ ## What already exists
46
+
47
+ - **The lifeline** — the tiny watchdog process that forwards your Telegram messages to the server and queues them if it can't. Already durable: queued messages survive and replay.
48
+ - **The server health check** — the lifeline always knows whether the server is up (`supervisor.healthy`). That verdict was already available at the exact spot where the wrong message was sent; the code just wasn't using it to pick the right words.
49
+ - **The genuinely-down message** — for a truly-down server the lifeline already said the accurate "Server is temporarily down…", and that wording is unchanged.
50
+
51
+ ## What this adds
52
+
53
+ One small, tested helper (`buildQueuedNotice`) now decides the notice wording from the live health verdict. When the server is healthy but the hand-off failed, you get: "I'm having trouble reaching my server right now — your message is queued (N in queue) and I'll deliver it as soon as I reconnect." When the server is genuinely down, you get the exact same accurate "temporarily down" message as before. The three places that send this notice (text, photo, file) all route through the one helper, so they can never drift apart again.
54
+
55
+ ## The new pieces
56
+
57
+ - **`buildQueuedNotice(kind, queueLength, serverHealthy)`** — a pure, side-effect-free function that returns the right notice text. It is NOT allowed to make any decision about delivery or restarts; it only chooses words from a health verdict it is handed. That line matters: the authority to restart still lives entirely in the existing restart machinery — this helper just describes the current state honestly.
58
+
59
+ ## The safeguards
60
+
61
+ The genuinely-down wording is byte-for-byte identical to before (a test locks that in, so no downstream dedup behavior shifts). A unit test proves the healthy-but-failed branch never contains the words "restart" or "temporarily down", and always mentions "reconnect"; and that the two states always produce different text. Scope is deliberately tight: the drift-promoter threshold question and the callback-query down-message are explicitly out of scope and were left untouched.
62
+
63
+ ## What you actually need to decide
64
+
65
+ Nothing risky. This is a wording/logic bug fix with no new capability, no config, no state, and no schema change. The only judgment call is the exact replacement wording, which reads in plain language and is honest about what's happening. If it turns out wrong, the back-out is a one-line revert.
@@ -0,0 +1,121 @@
1
+ # Side-Effects Review — Lifeline "reconnecting" notice (fix false "Server is restarting")
2
+
3
+ **Version / slug:** `lifeline-reconnect-notice`
4
+ **Date:** `2026-07-17`
5
+ **Author:** `Echo (instar-dev agent)`
6
+ **Second-pass reviewer:** `Echo (Phase-5 self-review — see below)`
7
+
8
+ ## Summary of the change
9
+
10
+ The lifeline forwards inbound Telegram messages to the server and, when it cannot forward right now, queues the message and sends the user a heads-up. There are two distinct "couldn't deliver right now" states — the server is genuinely **down** (`supervisor.healthy === false`) versus the server is **healthy but this one forward failed** (transient 10s timeout / 5xx / 503-boot / connection blip, `supervisor.healthy === true` and `forwardToServer()` returned non-`ok`). The healthy-but-failed branch was sending the user the false, alarming `Server is restarting. Your message has been queued…` even though the server was confirmed up. Reported by peer agent Luna (Sagemind) 2026-07-17, verified against source; it also hit operator Justin directly.
11
+
12
+ Files touched:
13
+ - `src/lifeline/queuedNotice.ts` (new) — a pure helper `buildQueuedNotice(kind, queueLength, serverHealthy)` that centralizes the notice wording.
14
+ - `src/lifeline/TelegramLifeline.ts` — the four queue-ack call sites (text healthy-fail, text down, photo, file/document) now route through the helper; the two photo/file inline `if/else` blocks collapse to one call each.
15
+ - `tests/unit/lifeline/queuedNotice.test.ts` (new) — unit coverage.
16
+
17
+ ## Decision-point inventory
18
+
19
+ - `TelegramLifeline` queue-ack wording (text/photo/file handlers) — **modified (wording/logic only)** — picks the user-facing notice string from the live `supervisor.healthy` verdict. This is a message-*wording* decision, not a message *block/allow* or delivery decision. No gating authority added, removed, or changed.
20
+
21
+ ---
22
+
23
+ ## 1. Over-block
24
+
25
+ No block/allow surface — over-block not applicable. The change never suppresses, delays, or rejects a message; it only chooses the text of a heads-up that is already being sent (still gated by the unchanged `shouldSendQueueAck` rate-limiter). Message queueing/delivery is entirely unchanged.
26
+
27
+ ---
28
+
29
+ ## 2. Under-block
30
+
31
+ No block/allow surface — under-block not applicable. The queued message still enqueues and replays exactly as before; the only behavioral delta is the words in the notice.
32
+
33
+ ---
34
+
35
+ ## 3. Level-of-abstraction fit
36
+
37
+ Correct layer. The wording decision belongs precisely where the send happens — the lifeline handler that already holds the `supervisor.healthy` verdict and the queue length. The new helper is a pure string builder (lowest sensible level: no I/O, no decision authority). It does not re-implement or run parallel to any existing gate; it consumes a health verdict the caller already computed. Centralizing the three previously-duplicated sites into one tested function is a strict simplification (DRY), not a new abstraction competing with an existing one.
38
+
39
+ ---
40
+
41
+ ## 4. Signal vs authority compliance
42
+
43
+ **Required reference:** docs/signal-vs-authority.md
44
+
45
+ - [x] No — this change has no block/allow surface.
46
+
47
+ `buildQueuedNotice` holds ZERO authority: it neither restarts anything, nor decides whether to send, nor gates delivery. It is handed a health SIGNAL (`supervisor.healthy`, computed by the existing supervisor) and returns descriptive text. The authority to restart the lifeline remains entirely with the existing `RestartOrchestrator` / `LifelineDriftPromoter`; this change deliberately stops the notice from *asserting* a restart the system did not perform — i.e. it makes the user-facing text HONEST about the current state rather than claiming an action. No brittle logic gains blocking authority.
48
+
49
+ ---
50
+
51
+ ## 4b. Judgment-point check (Judgment Within Floors standard)
52
+
53
+ No new static heuristic at a competing-signals decision point. The wording is chosen from a single, enumerable boolean (`serverHealthy` true/false) — an invariant two-state fork, not a point where multiple live signals conflict. There is no arbiter needed and none added.
54
+
55
+ ---
56
+
57
+ ## 5. Interactions
58
+
59
+ - **Shadowing:** none. The notice send sits after `shouldSendQueueAck` (unchanged) and does not run before/after any gate whose outcome it could mask.
60
+ - **Double-fire:** none introduced. The version-skew path (`handleVersionSkew`, fired on a 426) is a separate code path and is untouched; this change does not add a second notice.
61
+ - **Races:** none new. `this.queue.length` is read at send time exactly as before; no new shared state is introduced (the helper is stateless/pure).
62
+ - **Feedback loops:** none. The text is terminal output to the user; it feeds nothing back into the forward/queue machinery.
63
+ - **Down-branch wording preserved byte-for-byte:** the `serverHealthy === false` output is identical to the previous inline strings (locked by a test), so any downstream that keys on that exact text (e.g. the duplicate-message dedup window) sees no change.
64
+
65
+ ---
66
+
67
+ ## 6. External surfaces
68
+
69
+ - **Other agents / install base:** ships in the instar package `dist/`; every agent gets the corrected wording when it updates and its lifeline restarts onto the new version. No migration needed — the lifeline is compiled package code, not an agent-installed file (`.claude/settings.json`, config defaults, CLAUDE.md template, hook scripts, or built-in skills), so `PostUpdateMigrator` is not involved.
70
+ - **Telegram:** the only external-visible change is the improved notice text a user reads when a forward transiently fails. No API shape, topic, or delivery-path change.
71
+ - **Persistent state:** none. No schema, ledger, or state-file change.
72
+ - **Timing/runtime:** the branch is selected from the live `supervisor.healthy` at send time — same input the old code had at the same spot.
73
+ - **Operator surface (Mobile-Complete):** no operator-facing actions added or touched. This is a USER-facing message, not an operator action/approval/grant surface.
74
+
75
+ ---
76
+
77
+ ## 6b. Operator-surface quality (Operator-Surface Quality standard)
78
+
79
+ No operator surface — not applicable. This change touches a **user-facing** Telegram notice, not a dashboard renderer, approval page, or grant/revoke/secret-drop form. (For completeness on the user-facing text quality: the new notice leads with the real state in plain language — "I'm having trouble reaching my server right now — your message is queued (N in queue) and I'll deliver it as soon as I reconnect." — exposes no raw internals, and is honest rather than alarming.)
80
+
81
+ ---
82
+
83
+ ## 7. Multi-machine posture (Cross-Machine Coherence)
84
+
85
+ **machine-local BY DESIGN.** The lifeline is a per-machine process: each machine's lifeline forwards to that machine's own server and its `supervisor.healthy` verdict is about the local server. The notice is emitted by whichever machine actually received and tried to forward the user's message, so there is no cross-machine state to replicate or proxy. It emits a user-facing notice, but one-voice gating is not newly needed: the send is already governed by the existing per-topic `shouldSendQueueAck` rate-limiter and the pre-existing duplicate-message suppression window — this change alters only the words, not the send cadence or the number of voices. No durable state (nothing to strand on topic transfer) and no generated URLs.
86
+
87
+ ---
88
+
89
+ ## 8. Rollback cost
90
+
91
+ Pure code change — revert the two source files (and the new helper/test) and ship as the next patch. No persistent state, no data migration, no agent-state repair, no user-visible regression during the rollback window (worst case is the old wording returns). One-line-scale back-out.
92
+
93
+ ---
94
+
95
+ ## Conclusion
96
+
97
+ The review confirms a tightly-scoped, low-risk wording/logic fix with no decision-point authority, no block/allow surface, no persistent state, and no multi-machine coherence hazard. The design change made during review was to extract the wording into a single pure helper (rather than edit three inline strings), which both makes the fix unit-testable in isolation and removes the duplicated photo/file `if/else` — closing the "three copies drift apart" failure mode structurally. The genuinely-down wording is preserved byte-for-byte to avoid any downstream dedup/text-matching side effect. Scope was deliberately held to the three reported sites; the drift-promoter threshold question and the callback-query down-message were left untouched (flagged to the reporter as separate items). Clear to ship.
98
+
99
+ ---
100
+
101
+ ## Second-pass review (if required)
102
+
103
+ **Reviewer:** Echo (self, Phase-5 — the change touches the messaging/lifeline path)
104
+ **Independent read of the artifact: concur**
105
+
106
+ Concur with the review. Re-verified independently: (1) the only remaining `Server is restarting` string in `TelegramLifeline.ts` is the callback-query genuine-`!supervisor.healthy` branch (out of scope, and at least plausibly-true in a down state); (2) all four queue-ack sites now route through `buildQueuedNotice`; (3) the down-branch bytes are unchanged (test-locked); (4) no self-triggered action is added — the notice is a one-shot response to an inbound user message, not a self-firing loop. No concern raised.
107
+
108
+ ---
109
+
110
+ ## Evidence pointers
111
+
112
+ - `npx tsc --noEmit` — clean (exit 0).
113
+ - `npx vitest run tests/unit/lifeline/queuedNotice.test.ts` — 8/8 pass.
114
+ - `npx vitest run tests/unit/lifeline/` — 18 files / 160 tests pass (no regression).
115
+ - `pnpm build` — dist compiles; `dist/lifeline/queuedNotice.js` present; exactly 1 `Server is restarting` remains in `dist/lifeline/TelegramLifeline.js` (the intentional callback-down site).
116
+
117
+ ---
118
+
119
+ ## Class-Closure Declaration (display-only mirror)
120
+
121
+ Not a self-triggered controller and not a fix to an agent-authored artifact (prompt/hook/config/skill/standards text). This is a fix to compiled TypeScript runtime behavior — a one-shot, user-message-driven notice, not a loop/monitor/sentinel/reaper/scheduler/recovery path. `unbounded-self-action` class: `n/a` — one-shot user-driven action, not a self-triggered loop.
@@ -0,0 +1,99 @@
1
+ # Side-Effects Review — Session-pool self-placement confirmation
2
+
3
+ **Version / slug:** `session-pool-self-placement-confirmation`
4
+ **Date:** `2026-07-17`
5
+ **Author:** `Instar Agent (instar-codey)`
6
+ **Second-pass reviewer:** `continuation_impl_review` (independent Codex reviewer) — CONCUR after two correction rounds
7
+
8
+ ## Summary
9
+
10
+ Successful local session delivery now confirms a self-owned `placing` row as
11
+ `active`. Confirmation remains outside `SessionRouter`, after the real local
12
+ inject/spawn seam. Failed spawns do not confirm.
13
+
14
+ ## Decision-point inventory
15
+
16
+ - Post-local-delivery ownership transition — **modified** — a successful local
17
+ tail may confirm only its own still-placing row.
18
+
19
+ ## 1. Over-block
20
+
21
+ No message is newly blocked. Missing, active, or remotely-owned rows are no-ops.
22
+
23
+ ## 2. Under-block
24
+
25
+ The transition cannot run before delivery because every callsite is after a
26
+ synchronous injection that returned true or inside a spawn/respawn success
27
+ continuation. A rejected injection or spawn does not confirm.
28
+ Registry confirmation failure is diagnostic-only after delivery and cannot fall
29
+ into the delivery-failure handler. If the transition commits but observer
30
+ emission fails, the committed outcome remains true and diagnostics avoid
31
+ claiming an unknowable row state.
32
+
33
+ ## 3. Level-of-abstraction fit
34
+
35
+ The state predicate is a small pure core. Server wiring owns the timing because
36
+ it alone knows when the legacy local delivery tail has actually succeeded.
37
+
38
+ ## 4. Signal vs authority compliance
39
+
40
+ The ownership registry remains the sole transition authority. Local delivery
41
+ success is evidence supplied to that authority, not a parallel ownership store.
42
+
43
+ ## 4b. Judgment-point check
44
+
45
+ No heuristic is introduced. The enumerable rule is `status=placing AND
46
+ owner=self AND local delivery succeeded`.
47
+
48
+ ## 5. Interactions
49
+
50
+ Ordinary traffic to an active local session calls the helper but performs no
51
+ write. Remote placement confirmation remains unchanged. SpawnAdmission still
52
+ runs before every local spawn and a refusal cannot reach confirmation.
53
+
54
+ ## 6. External surfaces
55
+
56
+ `GET /pool/ownership-view` now reports `active` after a successful self-placement.
57
+ No schema, authentication, configuration, or user command changes.
58
+
59
+ ## 7. Multi-machine posture (Cross-Machine Coherence)
60
+
61
+ **Replicated.** The transition is written to the existing ownership registry
62
+ and propagated by its existing replication path. A live laptop/Mini test proved
63
+ the receiving Mini's row reached `active`.
64
+
65
+ ## 8. Rollback cost
66
+
67
+ Pure code rollback with no migration. Rollback restores stuck `placing` rows
68
+ for new self-placements.
69
+
70
+ ## Evidence
71
+
72
+ - `tests/unit/SessionPoolLocalClaim.test.ts`
73
+ - `tests/unit/session-pool-activation-wiring.test.ts`
74
+ - `tests/integration/session-pool-local-claim.integration.test.ts`
75
+ - `tests/unit/no-silent-fallbacks.test.ts` (both contained error paths are
76
+ explicitly annotated and continue to report through `onError`)
77
+ - Live single-agent CROSS-MACHINE topic 3462 placement: owner Mini, epoch 2,
78
+ status `active`.
79
+
80
+ ## Conclusion
81
+
82
+ The change is narrow and preserves honest failure semantics. It should ship
83
+ with the independent session-lifecycle second pass concurred.
84
+
85
+ ## Second-pass review
86
+
87
+ The first pass found that live injection's boolean result was ignored and that
88
+ confirmation exceptions could falsely enter delivery-failure handling. Both
89
+ were fixed and regression-tested. The second pass found a post-commit honesty
90
+ edge: observer emission could throw after CAS committed while diagnostics
91
+ claimed the row remained placing. The authoritative CAS result is now separate
92
+ from best-effort observation; committed confirmation stays true, diagnostics
93
+ make no unverified state claim, and the observer-failure regression is pinned.
94
+ The reviewer then concurred with no remaining findings.
95
+
96
+ ## Class-Closure Declaration (display-only mirror)
97
+
98
+ No agent-authored-artifact defect or self-triggered controller is added or
99
+ modified — not applicable.