instar 1.3.704 → 1.3.705
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 +216 -17
- package/dist/commands/server.js.map +1 -1
- package/dist/core/DeliverMessageHandler.d.ts +16 -0
- package/dist/core/DeliverMessageHandler.d.ts.map +1 -1
- package/dist/core/DeliverMessageHandler.js +0 -0
- package/dist/core/DeliverMessageHandler.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts +15 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +108 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/QueueDrainLoop.d.ts +6 -2
- package/dist/core/QueueDrainLoop.d.ts.map +1 -1
- package/dist/core/QueueDrainLoop.js +0 -0
- package/dist/core/QueueDrainLoop.js.map +1 -1
- package/dist/core/SessionRouter.d.ts +24 -4
- package/dist/core/SessionRouter.d.ts.map +1 -1
- package/dist/core/SessionRouter.js +25 -2
- package/dist/core/SessionRouter.js.map +1 -1
- package/dist/core/meshRejectionLog.d.ts +37 -0
- package/dist/core/meshRejectionLog.d.ts.map +1 -0
- package/dist/core/meshRejectionLog.js +73 -0
- package/dist/core/meshRejectionLog.js.map +1 -0
- package/dist/core/registryHighWater.d.ts +59 -0
- package/dist/core/registryHighWater.d.ts.map +1 -0
- package/dist/core/registryHighWater.js +120 -0
- package/dist/core/registryHighWater.js.map +1 -0
- package/dist/core/senderRejectionNotice.d.ts +89 -0
- package/dist/core/senderRejectionNotice.d.ts.map +1 -0
- package/dist/core/senderRejectionNotice.js +149 -0
- package/dist/core/senderRejectionNotice.js.map +1 -0
- package/dist/core/senderValidationGate.d.ts +80 -0
- package/dist/core/senderValidationGate.d.ts.map +1 -0
- package/dist/core/senderValidationGate.js +133 -0
- package/dist/core/senderValidationGate.js.map +1 -0
- package/dist/core/types.d.ts +12 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/messaging/MessageProcessingLedger.d.ts +33 -5
- package/dist/messaging/MessageProcessingLedger.d.ts.map +1 -1
- package/dist/messaging/MessageProcessingLedger.js +50 -7
- package/dist/messaging/MessageProcessingLedger.js.map +1 -1
- package/dist/messaging/ingressDedup.d.ts.map +1 -1
- package/dist/messaging/ingressDedup.js +9 -0
- package/dist/messaging/ingressDedup.js.map +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +2 -1
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/CapabilityIndex.d.ts.map +1 -1
- package/dist/server/CapabilityIndex.js +1 -0
- package/dist/server/CapabilityIndex.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +36 -0
- package/dist/server/routes.js.map +1 -1
- package/dist/users/UserManager.d.ts +22 -1
- package/dist/users/UserManager.d.ts.map +1 -1
- package/dist/users/UserManager.js +87 -2
- package/dist/users/UserManager.js.map +1 -1
- package/dist/users/testIdentityMarkers.d.ts +94 -0
- package/dist/users/testIdentityMarkers.d.ts.map +1 -0
- package/dist/users/testIdentityMarkers.js +170 -0
- package/dist/users/testIdentityMarkers.js.map +1 -0
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +63 -63
- package/src/scaffold/templates.ts +2 -1
- package/upgrades/1.3.705.md +79 -0
- package/upgrades/side-effects/silent-loss-refusal-conservation.md +124 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Side-Effects Review — silent-loss-refusal-conservation
|
|
2
|
+
|
|
3
|
+
Spec: `docs/specs/silent-loss-refusal-conservation.md` (converged, approved, operator-preapproved topic 29836).
|
|
4
|
+
Change: 5 increments (A RouteOutcome honesty, B receiver trace, C unified loss notice, D wiring-time registry gate + fixture refusal, E agent awareness) + 2 migrations.
|
|
5
|
+
|
|
6
|
+
## Over-block (could this REFUSE a message it should deliver?)
|
|
7
|
+
|
|
8
|
+
- The wiring gate's whole design is fail-TOWARD-delivery for the incident class: a
|
|
9
|
+
degenerate / never-populated / clean-ENOENT / operator-unresolvable registry
|
|
10
|
+
DISARMS (delivers). The only paths that REJECT are (a) a HEALTHY populated
|
|
11
|
+
registry that genuinely doesn't resolve the sender (real deauthorization — the
|
|
12
|
+
existing, intended behavior) and (b) an UNKNOWN_UNSAFE (corrupt/partial/tampered)
|
|
13
|
+
store, which fails CLOSED by design — but even there the LOCALLY-bound operator
|
|
14
|
+
passes via the topic-operator binding (KYP), and the rejection is conserved
|
|
15
|
+
through the §C notice so the sender is TOLD (never silent).
|
|
16
|
+
- Risk: `classifyRegistry` reads the RAW file and counts fixture rows as
|
|
17
|
+
"populated". A fixture-clobbered store therefore classifies `populated`, and a
|
|
18
|
+
NON-operator real sender with no bound operator for that topic would be rejected
|
|
19
|
+
in the window BEFORE the §4 boot migration quarantines the fixtures. Mitigations:
|
|
20
|
+
the migration runs at boot; the operator ALWAYS passes via the operator-resolution
|
|
21
|
+
disarm; the rejection is a loud §C notice, never silent loss. Net: strictly
|
|
22
|
+
better than today (today: silent total loss for everyone).
|
|
23
|
+
- New-user first message: a genuinely fresh install (`[]`, no high-water) disarms →
|
|
24
|
+
the operator's first message is delivered. `legitimate-user-named-Olivia-registers`
|
|
25
|
+
pins that a display name is NEVER a fixture criterion.
|
|
26
|
+
|
|
27
|
+
## Under-block (could this DELIVER something it should refuse?)
|
|
28
|
+
|
|
29
|
+
- The degenerate disarm delivers WITHOUT sender re-validation. This is intentional
|
|
30
|
+
and bounded: it only applies to a registry that would otherwise reject EVERYONE
|
|
31
|
+
(protecting nothing). The mesh's outer wall is unchanged — MeshRpc is still
|
|
32
|
+
signed, recipient-bound, router-only; only the DEFENSE-IN-DEPTH sender re-check
|
|
33
|
+
is disarmed, not the transport authz.
|
|
34
|
+
- The read-only probe UserManager (no server key) KEEPS a fixture-with-allow-marker
|
|
35
|
+
it cannot verify. Only reachable by a near-impossible legit fixture-collision AND
|
|
36
|
+
a data-only forger simultaneously; the AUTHORITATIVE server load (with the key)
|
|
37
|
+
quarantines a bogus marker. A fixture uid resolving in a non-authoritative probe
|
|
38
|
+
does not authorize anything (it is not a real sender). Documented out-of-scope:
|
|
39
|
+
a fully-FS-privileged local process (§2.D honest threat model).
|
|
40
|
+
|
|
41
|
+
## Abstraction (right seams? single funnels?)
|
|
42
|
+
|
|
43
|
+
- The refusal is a FIRST-CLASS `RouteOutcome.action:'rejected'` + a distinct
|
|
44
|
+
`LedgerState:'rejected'` terminal — enumerated into EVERY consumer (router
|
|
45
|
+
consumers, forceReplace, drain escape, `decideIngress`/`beginProcessing`/`isActedOn`).
|
|
46
|
+
A ratchet test pins that no consumer maps `rejected`→success.
|
|
47
|
+
- The loss notice is ONE funnel (`SenderRejectionNoticer`) shared by the live path
|
|
48
|
+
(Telegram/Slack) AND the drain `reportLoss('sender-deauthorized')` — unified on
|
|
49
|
+
ONE canonical cause so the two paths can't emit two wordings.
|
|
50
|
+
- The fixture matcher, high-water, and allow-marker sign/verify are single-source
|
|
51
|
+
modules imported by the write path, load path, gate, AND the §4 migration — they
|
|
52
|
+
cannot drift.
|
|
53
|
+
|
|
54
|
+
## Signal-vs-authority
|
|
55
|
+
|
|
56
|
+
- The divergence signal (local-resolves + remote-rejects) is ADVISORY only — it
|
|
57
|
+
raises one deduped coherence alert, NEVER auto-remediation (it cannot distinguish
|
|
58
|
+
a degenerate registry from a lawful deauth still replicating). Auto re-place is a
|
|
59
|
+
tracked follow-up.
|
|
60
|
+
- The receiver-side trace (`onRejected` → `mesh-rejections.jsonl`) is metadata-only
|
|
61
|
+
observability — it never changes the NACK. A trace fault is swallowed.
|
|
62
|
+
- The gate's alerts are deduped/rate-limited signals; the ARM/DISARM decision is
|
|
63
|
+
the authority, driven only by verified registry STATE (never a config flag).
|
|
64
|
+
|
|
65
|
+
## Adjacent systems
|
|
66
|
+
|
|
67
|
+
- `MessageProcessingLedger` gains a `rejected` state + `rejected_at` column
|
|
68
|
+
(idempotent `ALTER TABLE ADD COLUMN`, self-initializing — no migrator step). The
|
|
69
|
+
three ledger consumers are enumerated so a redelivery is DROPPED, not resurrected
|
|
70
|
+
(closes the double-notify-on-redelivery class).
|
|
71
|
+
- `UserManager` write path now THROWS `TestIdentityRefusedError` on a fixture id.
|
|
72
|
+
Full-suite risk: suites/harnesses that legitimately write `livetest`/`g3test`/`u-*`
|
|
73
|
+
ids. Mitigation: the double-keyed escape (`INSTAR_ALLOW_TEST_IDENTITIES=1` + the
|
|
74
|
+
on-disk test-home marker) is set for legitimately-fixture-writing suites; the
|
|
75
|
+
load path refuse-and-SKIPS (never throws → never fails boot).
|
|
76
|
+
- `high-water` write on load/register is monotonic + one-time + best-effort (never
|
|
77
|
+
breaks a write). It shares users.json's FS trust boundary (no separate envelope).
|
|
78
|
+
|
|
79
|
+
## Rollback
|
|
80
|
+
|
|
81
|
+
- Single PR; `git revert` restores all CODE behavior. CARVE-OUT (§6): the §4
|
|
82
|
+
boot-remediation QUARANTINES fixture rows out of users.json to a timestamped
|
|
83
|
+
backup — a revert removes the migration code but does not (and should not)
|
|
84
|
+
restore quarantined rows; a wrongly-quarantined legitimate user is recovered from
|
|
85
|
+
that backup. The boot classification is READ-ONLY (no self-heal write), so it
|
|
86
|
+
leaves no state to unwind. Surviving inert artifacts: `logs/mesh-rejections.jsonl`,
|
|
87
|
+
`state/registry-high-water.json`, any already-sent notices/alerts.
|
|
88
|
+
- Per-increment rollback is clean (disjoint seams): router mapping / handler deps /
|
|
89
|
+
notice consumer / wiring gate + UserManager / template.
|
|
90
|
+
|
|
91
|
+
## Always-on justification
|
|
92
|
+
|
|
93
|
+
Reachability / no-silent-loss floor ("The Agent Is Always Reachable" class): the
|
|
94
|
+
constitution forbids dark-shipping the guarantee that a message is delivered or
|
|
95
|
+
loudly accounted for. A/B/E are pure honesty + hygiene (identical on every healthy
|
|
96
|
+
path). C fires only where today = silent loss. D's disarm fires only in degenerate
|
|
97
|
+
states that today reject everyone; its own failure mode (a probe throwing on a
|
|
98
|
+
transiently-locked POPULATED store) is pinned to ARM by `populated-registry-always-arms`,
|
|
99
|
+
so the new code cannot regress the existing security control.
|
|
100
|
+
|
|
101
|
+
## Follow-up: CI-surfaced test adjustments (2026-07-02)
|
|
102
|
+
|
|
103
|
+
The full sharded CI suite surfaced pre-existing tests the change interacts with.
|
|
104
|
+
Fixed WITHOUT weakening the production fixture-refusal or the no-silent-fallbacks
|
|
105
|
+
guard, via the intended escape/annotation mechanisms:
|
|
106
|
+
|
|
107
|
+
- **Fixture-writing tests** (e2e coordination-mandate + authorization-request; integration
|
|
108
|
+
permissions-routes) now use the intended DOUBLE-KEYED test escape via a shared
|
|
109
|
+
`tests/helpers/allow-test-identities.ts` (env `INSTAR_ALLOW_TEST_IDENTITIES=1` + the
|
|
110
|
+
on-disk `.instar-test-home` marker). Production behavior is unchanged — a stray env var
|
|
111
|
+
alone still cannot disable the guard.
|
|
112
|
+
- **`no-silent-fallbacks` ratchet**: my four new-file intentional fail-toward-delivery
|
|
113
|
+
catches + the four inbound-wiring construction catches in `server.ts` are annotated
|
|
114
|
+
`@silent-fallback-ok` with a per-site reason. Net flagged count returns to baseline
|
|
115
|
+
491 — NO baseline bump; the guard is not weakened.
|
|
116
|
+
- **`feature-delivery-completeness`**: the migrator "Sender-Rejection Notices" section is
|
|
117
|
+
added to `legacyMigratorSections` (template + migrator behavioral awareness, no
|
|
118
|
+
framework-shadowed route).
|
|
119
|
+
- **`capabilities-discoverability`**: the `/users` route prefix (`POST /users/allow-test-identity`)
|
|
120
|
+
is classified in `CapabilityIndex.INTERNAL_PREFIXES` (dashboard-PIN-gated, operator/support-only,
|
|
121
|
+
not an agent-invokable capability).
|
|
122
|
+
- **`session-pool-activation-wiring`**: the fail-safe scan window grew 5200→6500 to contain
|
|
123
|
+
the `rejected` short-circuit added inside the inbound interception block (documented
|
|
124
|
+
window-maintenance pattern).
|