instar 1.3.1002 → 1.3.1004
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/core/userChannels.d.ts +46 -0
- package/dist/core/userChannels.d.ts.map +1 -1
- package/dist/core/userChannels.js +122 -2
- package/dist/core/userChannels.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +11 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/scripts/lib/classify-tier.mjs +15 -1
- package/skills/spec-converge/SKILL.md +46 -2
- package/skills/spec-converge/templates/report.md +2 -2
- package/src/data/builtin-manifest.json +46 -46
- package/upgrades/1.3.1003.md +50 -0
- package/upgrades/1.3.1004.md +111 -0
- package/upgrades/side-effects/channels-wa-imessage.md +77 -0
- package/upgrades/side-effects/converge-design-class-criterion.md +74 -0
- package/upgrades/side-effects/tier-config-hint-filename.md +72 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Side-effects review — WhatsApp + iMessage join the channel registry
|
|
2
|
+
|
|
3
|
+
**Change:** `buildUserChannelDefinitions` gains `user-whatsapp` and `user-imessage` rows, with
|
|
4
|
+
exported `whatsappStateFrom` / `imessageStateFrom` mappers and route wiring from
|
|
5
|
+
`ctx.whatsapp.getStatus().state` and `ctx.imessage.getConnectionInfo().state`.
|
|
6
|
+
|
|
7
|
+
**Decision point touched?** No new gate. This is additive read-only observability on an existing
|
|
8
|
+
`advisory: true` route. It does change what a caller CONCLUDES about reachability, which is why the
|
|
9
|
+
verdict mapping is the whole of this review.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. Over-block
|
|
14
|
+
|
|
15
|
+
Nothing is blocked or rejected — the route is advisory and gates nothing. The over-claim risk runs the
|
|
16
|
+
other way and is handled: `qr-pending` is reported as `reachable-no-credential` rather than `broken`,
|
|
17
|
+
because the link is alive and needs a HUMAN to scan a code. Reporting it as broken would send an
|
|
18
|
+
operator to debug a connection behaving exactly as designed.
|
|
19
|
+
|
|
20
|
+
## 2. Under-block
|
|
21
|
+
|
|
22
|
+
The honest limit, stated in both rows' own text rather than left to assumption: `working` means the
|
|
23
|
+
link was up when probed. It does NOT prove a send to a particular chat or contact would land. Same
|
|
24
|
+
caveat the Telegram and mutual-ssh rows already carry.
|
|
25
|
+
|
|
26
|
+
Unrecognised states from either adapter map to `unknown`, never to `working`. That is the failure
|
|
27
|
+
direction that matters — a state this module has not seen must not read as healthy — and it is
|
|
28
|
+
pinned by a test.
|
|
29
|
+
|
|
30
|
+
Not addressed: neither row probes a round-trip. A true reachability proof would require sending, which
|
|
31
|
+
a status read must not do.
|
|
32
|
+
|
|
33
|
+
## 3. Level-of-abstraction fit
|
|
34
|
+
|
|
35
|
+
Correct, and it follows the pattern already established for Telegram and Slack: the STATE→VERDICT
|
|
36
|
+
mapping is an exported pure function testable without constructing an adapter, and the route supplies
|
|
37
|
+
live state through a narrow context. The mapping is where a wrong verdict would come from, so it is
|
|
38
|
+
the part that is pinned.
|
|
39
|
+
|
|
40
|
+
## 4. Signal vs authority compliance
|
|
41
|
+
|
|
42
|
+
Compliant. Pure signal on an advisory route with no blocking power. Adding rows strengthens the
|
|
43
|
+
registry's "absence is impossible" property — the invariant that a channel with no row cannot report
|
|
44
|
+
that it is missing.
|
|
45
|
+
|
|
46
|
+
## 5. Interactions
|
|
47
|
+
|
|
48
|
+
`UserChannelProbeContext` gains two required fields, so any other constructor of it must supply them
|
|
49
|
+
— there is exactly one (the `/channels` route), updated here. The `/channels` payload grows from 6
|
|
50
|
+
rows to 8; the integration test that pins the exact set and the audience partition was updated in
|
|
51
|
+
this change rather than left for CI to catch.
|
|
52
|
+
|
|
53
|
+
`WhatsAppLiveState` mirrors the adapter's own union. If the adapter adds a state, the mapper reports
|
|
54
|
+
`unknown` rather than mis-classifying — a deliberate fail-safe, not an oversight.
|
|
55
|
+
|
|
56
|
+
## 6. External surfaces
|
|
57
|
+
|
|
58
|
+
`GET /channels` returns two additional rows. Additive; existing consumers reading known ids are
|
|
59
|
+
unaffected. No endpoint added, no config key, no behaviour change to messaging itself.
|
|
60
|
+
|
|
61
|
+
## 7. Multi-machine posture
|
|
62
|
+
|
|
63
|
+
**Machine-local by design for iMessage**, and this is a real property rather than a shortcut: the
|
|
64
|
+
backend it talks to runs on this host, so the channel genuinely exists only where that backend is.
|
|
65
|
+
That is recorded in the row's own `cost` text so a caller choosing it knows the work will not survive
|
|
66
|
+
this machine going away.
|
|
67
|
+
|
|
68
|
+
WhatsApp is pairing-bound to the operator's phone through whichever host holds the session — the same
|
|
69
|
+
locality. Neither introduces replicated state; both are per-host reads of a per-host adapter, and a
|
|
70
|
+
cross-machine merged view would be actively misleading since another machine's link says nothing
|
|
71
|
+
about this one's.
|
|
72
|
+
|
|
73
|
+
## 8. Rollback cost
|
|
74
|
+
|
|
75
|
+
Trivial: remove the two rows, the two mappers, the two context fields and the route wiring, and
|
|
76
|
+
restore the integration test's expected set. No persisted state, no schema, no migration. Rolling back
|
|
77
|
+
re-opens the stated gap, so it should carry a reason.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Side-effects review — spec-converge terminates on design-class findings
|
|
2
|
+
|
|
3
|
+
**Change:** `/spec-converge`'s first convergence criterion changes from "no MATERIAL new issues"
|
|
4
|
+
(material = anything requiring a spec change) to "no DESIGN-class findings for TWO consecutive
|
|
5
|
+
rounds", with an explicit design/precision taxonomy that reviewers DECLARE per finding. The report
|
|
6
|
+
template records both counts per round.
|
|
7
|
+
|
|
8
|
+
**Decision point touched?** Yes, and it is the whole review: this is the stop criterion of the gate
|
|
9
|
+
that decides whether a spec may claim convergence — the tag `/instar-dev` requires before touching
|
|
10
|
+
instar source.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 1. Over-block
|
|
15
|
+
|
|
16
|
+
Reduced, deliberately, and that is the point. The prior criterion over-blocked absolutely: on a spec
|
|
17
|
+
that appends its own review history the surface grows each round, a reviewer always finds precision
|
|
18
|
+
to add, and every such finding counted as material — so the loop could not terminate BY CONSTRUCTION.
|
|
19
|
+
Two specs hit the 10-round cap for reasons unrelated to design soundness.
|
|
20
|
+
|
|
21
|
+
## 2. Under-block
|
|
22
|
+
|
|
23
|
+
The real risk, stated plainly: **loosening what counts as terminating could let a spec converge with
|
|
24
|
+
an unaddressed design defect misfiled as precision.**
|
|
25
|
+
|
|
26
|
+
Three things bound it, none of which is "the reviewer will be careful":
|
|
27
|
+
- The taxonomy names the dangerous case EXPLICITLY — a statement that is factually WRONG about the
|
|
28
|
+
system is design-class, never precision. That case is not hypothetical: round 10 of
|
|
29
|
+
`standards-registry-ships-with-code` caught a false rollback claim, and under a careless taxonomy
|
|
30
|
+
that would have been filed as wording.
|
|
31
|
+
- TWO consecutive quiet rounds, not one. A single quiet round is weak evidence on a growing surface.
|
|
32
|
+
- The class is DECLARED by the reviewer that raised the finding and the comparator consumes the
|
|
33
|
+
declaration rather than re-deriving it from wording — so a misclassification is an explicit act
|
|
34
|
+
recorded in the report, not an inference nobody can see.
|
|
35
|
+
|
|
36
|
+
Residual and unfixed: a reviewer that systematically under-classifies still ends the loop early. This
|
|
37
|
+
trades one judgment for a better-specified one; it does not eliminate judgment. Per-round counts in
|
|
38
|
+
the report are the detection surface, not a guarantee.
|
|
39
|
+
|
|
40
|
+
## 3. Level-of-abstraction fit
|
|
41
|
+
|
|
42
|
+
Correct. The defect is in the stop criterion's DEFINITION, which lives in the skill's prose and is
|
|
43
|
+
applied by the comparator, so the fix belongs in the prose plus the report template that makes it
|
|
44
|
+
auditable. No code enforces the classification today and none is added — an important honesty: this
|
|
45
|
+
is an instruction change, so it binds only as well as the reviewers follow it.
|
|
46
|
+
|
|
47
|
+
## 4. Signal vs authority compliance
|
|
48
|
+
|
|
49
|
+
The comparator retains exactly the authority it had (emit `converged: true|false`). What changes is
|
|
50
|
+
the definition it applies and the requirement that it consume a DECLARED class rather than infer one
|
|
51
|
+
— moving a judgment from implicit to explicit. No new blocking power anywhere.
|
|
52
|
+
|
|
53
|
+
## 5. Interactions
|
|
54
|
+
|
|
55
|
+
`write-convergence-tag.mjs` is untouched: criterion 2 (zero unresolved `## Open questions`) is still
|
|
56
|
+
enforced structurally there, so the STRUCTURAL half of convergence is unchanged and this change
|
|
57
|
+
cannot weaken it. The report template's Iteration Summary gains a column (design/precision split);
|
|
58
|
+
existing reports remain readable, and future ones carry the counts the new criterion depends on.
|
|
59
|
+
|
|
60
|
+
## 6. External surfaces
|
|
61
|
+
|
|
62
|
+
None. `/spec-converge` is an instar-development skill, not user-facing, not an endpoint, no config
|
|
63
|
+
key. The observable effect is that specs which would previously have hit the cap can now converge on
|
|
64
|
+
their merits — and that convergence reports show two counts where they showed one.
|
|
65
|
+
|
|
66
|
+
## 7. Multi-machine posture
|
|
67
|
+
|
|
68
|
+
Not applicable. This is repo-level skill prose plus a report template, identical on every checkout,
|
|
69
|
+
with no runtime state, no persistence, and nothing to replicate, proxy, or reconcile.
|
|
70
|
+
|
|
71
|
+
## 8. Rollback cost
|
|
72
|
+
|
|
73
|
+
Trivial: restore the previous criterion paragraph and the template's original column. No state, no
|
|
74
|
+
migration, no code. A rollback re-creates the unterminating loop, so it should carry a reason.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Side-effects review — tier classifier no longer treats a .config FILENAME as a config surface
|
|
2
|
+
|
|
3
|
+
**Change:** removes the `\.config\b` alternative from `CONFIG_SURFACE_HINT` in
|
|
4
|
+
`scripts/lib/classify-tier.mjs`. That alternative matched a filename REFERENCE, so a diff that merely
|
|
5
|
+
read `*.config.ts` satisfied the config-surface gate and, combined with any object literal, raised the
|
|
6
|
+
risk floor for "new config key added".
|
|
7
|
+
|
|
8
|
+
**Decision point touched?** Yes — the risk floor of the instar-dev tier gate. This LOWERS the floor in
|
|
9
|
+
one specific false-positive case, so it is a loosening and reviewed as such.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. Over-block
|
|
14
|
+
|
|
15
|
+
This change exists to remove one. The over-block was concrete: a read-only developer script that adds
|
|
16
|
+
no config key had its floor raised to 2 purely for naming `vitest.push.config.ts`.
|
|
17
|
+
|
|
18
|
+
## 2. Under-block
|
|
19
|
+
|
|
20
|
+
The real risk of the change, stated plainly: narrowing a heuristic can blind it. If a genuine
|
|
21
|
+
config-key addition mentions ONLY a `*.config.ts` filename and none of the remaining anchors
|
|
22
|
+
(`ConfigDefaults`, `config.json`, `defaultConfig`, `InstarConfig`, `configSchema`), its floor will no
|
|
23
|
+
longer rise.
|
|
24
|
+
|
|
25
|
+
Bounded two ways. The remaining anchors cover the actual config surfaces in this repo — a diff adding
|
|
26
|
+
a real key names the module, the file, or the type. And a test now iterates EVERY remaining anchor and
|
|
27
|
+
asserts the floor still rises, so a future narrowing that blinds the check fails.
|
|
28
|
+
|
|
29
|
+
Residual: this is a heuristic over diff text and always was. It deters accidental omission; it is not
|
|
30
|
+
a boundary against a determined author. Unchanged by this.
|
|
31
|
+
|
|
32
|
+
## 3. Level-of-abstraction fit
|
|
33
|
+
|
|
34
|
+
Correct — the defect is in the hint regex and the fix is in the hint regex. A broader alternative
|
|
35
|
+
(requiring the anchor on the SAME line as the key) was considered and rejected as a larger behavioural
|
|
36
|
+
change than the evidence supports: one bad alternative was identified precisely, so one alternative is
|
|
37
|
+
removed.
|
|
38
|
+
|
|
39
|
+
## 4. Signal vs authority compliance
|
|
40
|
+
|
|
41
|
+
The classifier is a SIGNAL that informs a declared tier; the agent holds the authority and the
|
|
42
|
+
declaration is audited. This change makes the signal more accurate without altering who decides. Per
|
|
43
|
+
`docs/signal-vs-authority.md` that is the intended direction.
|
|
44
|
+
|
|
45
|
+
## 5. Interactions
|
|
46
|
+
|
|
47
|
+
`CONFIG_SURFACE_HINT` is used only to gate the `key: value` pattern inside the new-capability check.
|
|
48
|
+
No other risk signal is affected; the `export class` and router patterns are untouched. All 47
|
|
49
|
+
pre-existing classifier tests pass unchanged, plus 2 new ones.
|
|
50
|
+
|
|
51
|
+
Changes to this file alter tier decisions for FUTURE commits only. Nothing recorded in past decision
|
|
52
|
+
audits is rewritten.
|
|
53
|
+
|
|
54
|
+
## 6. External surfaces
|
|
55
|
+
|
|
56
|
+
None. Development-time classifier; no endpoint, no config key, no runtime behaviour, not user-facing.
|
|
57
|
+
|
|
58
|
+
## 7. Multi-machine posture
|
|
59
|
+
|
|
60
|
+
Not applicable: a pure function over diff text, identical on every checkout, with no state, no
|
|
61
|
+
persistence, and nothing to replicate or reconcile.
|
|
62
|
+
|
|
63
|
+
## 8. Rollback cost
|
|
64
|
+
|
|
65
|
+
Trivial — restore the alternative. The regression test would then fail, which is the correct signal
|
|
66
|
+
that the rollback reintroduces the false positive rather than a silent revert.
|
|
67
|
+
|
|
68
|
+
## Disclosure
|
|
69
|
+
|
|
70
|
+
I hit this false positive myself and declared Tier 1 under the raised floor without reading it first.
|
|
71
|
+
That declaration and its deliberate re-declaration are both in the decision audit. This change fixes
|
|
72
|
+
the classifier; it does not excuse the declaration.
|