instar 1.3.560 → 1.3.561
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/init.d.ts.map +1 -1
- package/dist/commands/init.js +3 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/core/Config.d.ts.map +1 -1
- package/dist/core/Config.js +2 -1
- package/dist/core/Config.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +17 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/canonicalFeedback.d.ts +28 -0
- package/dist/core/canonicalFeedback.d.ts.map +1 -0
- package/dist/core/canonicalFeedback.js +30 -0
- package/dist/core/canonicalFeedback.js.map +1 -0
- package/dist/core/types.d.ts +1 -1
- package/dist/core/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +19 -19
- package/upgrades/1.3.561.md +31 -0
- package/upgrades/side-effects/feedback-sender-repoint.md +61 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./builtin-manifest.schema.json",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
|
-
"generatedAt": "2026-06-
|
|
5
|
-
"instarVersion": "1.3.
|
|
4
|
+
"generatedAt": "2026-06-14T10:35:51.901Z",
|
|
5
|
+
"instarVersion": "1.3.561",
|
|
6
6
|
"entryCount": 201,
|
|
7
7
|
"entries": {
|
|
8
8
|
"hook:session-start": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"domain": "identity",
|
|
12
12
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
13
13
|
"installedPath": ".instar/hooks/instar/session-start.sh",
|
|
14
|
-
"contentHash": "
|
|
14
|
+
"contentHash": "e0ddbc39521447ae1bfecddfc98b2bd579400889d5fac37cf7df7d380e6a2fb7",
|
|
15
15
|
"since": "2025-01-01"
|
|
16
16
|
},
|
|
17
17
|
"hook:dangerous-command-guard": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"domain": "safety",
|
|
21
21
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
22
22
|
"installedPath": ".instar/hooks/instar/dangerous-command-guard.sh",
|
|
23
|
-
"contentHash": "
|
|
23
|
+
"contentHash": "e0ddbc39521447ae1bfecddfc98b2bd579400889d5fac37cf7df7d380e6a2fb7",
|
|
24
24
|
"since": "2025-01-01"
|
|
25
25
|
},
|
|
26
26
|
"hook:grounding-before-messaging": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"domain": "safety",
|
|
30
30
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
31
31
|
"installedPath": ".instar/hooks/instar/grounding-before-messaging.sh",
|
|
32
|
-
"contentHash": "
|
|
32
|
+
"contentHash": "e0ddbc39521447ae1bfecddfc98b2bd579400889d5fac37cf7df7d380e6a2fb7",
|
|
33
33
|
"since": "2025-01-01"
|
|
34
34
|
},
|
|
35
35
|
"hook:compaction-recovery": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"domain": "identity",
|
|
39
39
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
40
40
|
"installedPath": ".instar/hooks/instar/compaction-recovery.sh",
|
|
41
|
-
"contentHash": "
|
|
41
|
+
"contentHash": "e0ddbc39521447ae1bfecddfc98b2bd579400889d5fac37cf7df7d380e6a2fb7",
|
|
42
42
|
"since": "2025-01-01"
|
|
43
43
|
},
|
|
44
44
|
"hook:external-operation-gate": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"domain": "safety",
|
|
48
48
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
49
49
|
"installedPath": ".instar/hooks/instar/external-operation-gate.js",
|
|
50
|
-
"contentHash": "
|
|
50
|
+
"contentHash": "e0ddbc39521447ae1bfecddfc98b2bd579400889d5fac37cf7df7d380e6a2fb7",
|
|
51
51
|
"since": "2025-01-01"
|
|
52
52
|
},
|
|
53
53
|
"hook:deferral-detector": {
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"domain": "safety",
|
|
57
57
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
58
58
|
"installedPath": ".instar/hooks/instar/deferral-detector.js",
|
|
59
|
-
"contentHash": "
|
|
59
|
+
"contentHash": "e0ddbc39521447ae1bfecddfc98b2bd579400889d5fac37cf7df7d380e6a2fb7",
|
|
60
60
|
"since": "2025-01-01"
|
|
61
61
|
},
|
|
62
62
|
"hook:self-stop-guard": {
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"domain": "coherence",
|
|
66
66
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
67
67
|
"installedPath": ".instar/hooks/instar/self-stop-guard.js",
|
|
68
|
-
"contentHash": "
|
|
68
|
+
"contentHash": "e0ddbc39521447ae1bfecddfc98b2bd579400889d5fac37cf7df7d380e6a2fb7",
|
|
69
69
|
"since": "2025-01-01"
|
|
70
70
|
},
|
|
71
71
|
"hook:post-action-reflection": {
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"domain": "evolution",
|
|
75
75
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
76
76
|
"installedPath": ".instar/hooks/instar/post-action-reflection.js",
|
|
77
|
-
"contentHash": "
|
|
77
|
+
"contentHash": "e0ddbc39521447ae1bfecddfc98b2bd579400889d5fac37cf7df7d380e6a2fb7",
|
|
78
78
|
"since": "2025-01-01"
|
|
79
79
|
},
|
|
80
80
|
"hook:external-communication-guard": {
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"domain": "safety",
|
|
84
84
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
85
85
|
"installedPath": ".instar/hooks/instar/external-communication-guard.js",
|
|
86
|
-
"contentHash": "
|
|
86
|
+
"contentHash": "e0ddbc39521447ae1bfecddfc98b2bd579400889d5fac37cf7df7d380e6a2fb7",
|
|
87
87
|
"since": "2025-01-01"
|
|
88
88
|
},
|
|
89
89
|
"hook:scope-coherence-collector": {
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"domain": "coherence",
|
|
93
93
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
94
94
|
"installedPath": ".instar/hooks/instar/scope-coherence-collector.js",
|
|
95
|
-
"contentHash": "
|
|
95
|
+
"contentHash": "e0ddbc39521447ae1bfecddfc98b2bd579400889d5fac37cf7df7d380e6a2fb7",
|
|
96
96
|
"since": "2025-01-01"
|
|
97
97
|
},
|
|
98
98
|
"hook:scope-coherence-checkpoint": {
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"domain": "coherence",
|
|
102
102
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
103
103
|
"installedPath": ".instar/hooks/instar/scope-coherence-checkpoint.js",
|
|
104
|
-
"contentHash": "
|
|
104
|
+
"contentHash": "e0ddbc39521447ae1bfecddfc98b2bd579400889d5fac37cf7df7d380e6a2fb7",
|
|
105
105
|
"since": "2025-01-01"
|
|
106
106
|
},
|
|
107
107
|
"hook:free-text-guard": {
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
"domain": "safety",
|
|
111
111
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
112
112
|
"installedPath": ".instar/hooks/instar/free-text-guard.sh",
|
|
113
|
-
"contentHash": "
|
|
113
|
+
"contentHash": "e0ddbc39521447ae1bfecddfc98b2bd579400889d5fac37cf7df7d380e6a2fb7",
|
|
114
114
|
"since": "2025-01-01"
|
|
115
115
|
},
|
|
116
116
|
"hook:claim-intercept": {
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
"domain": "coherence",
|
|
120
120
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
121
121
|
"installedPath": ".instar/hooks/instar/claim-intercept.js",
|
|
122
|
-
"contentHash": "
|
|
122
|
+
"contentHash": "e0ddbc39521447ae1bfecddfc98b2bd579400889d5fac37cf7df7d380e6a2fb7",
|
|
123
123
|
"since": "2025-01-01"
|
|
124
124
|
},
|
|
125
125
|
"hook:claim-intercept-response": {
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
"domain": "coherence",
|
|
129
129
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
130
130
|
"installedPath": ".instar/hooks/instar/claim-intercept-response.js",
|
|
131
|
-
"contentHash": "
|
|
131
|
+
"contentHash": "e0ddbc39521447ae1bfecddfc98b2bd579400889d5fac37cf7df7d380e6a2fb7",
|
|
132
132
|
"since": "2025-01-01"
|
|
133
133
|
},
|
|
134
134
|
"hook:stop-gate-router": {
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
"domain": "safety",
|
|
138
138
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
139
139
|
"installedPath": ".instar/hooks/instar/stop-gate-router.js",
|
|
140
|
-
"contentHash": "
|
|
140
|
+
"contentHash": "e0ddbc39521447ae1bfecddfc98b2bd579400889d5fac37cf7df7d380e6a2fb7",
|
|
141
141
|
"since": "2025-01-01"
|
|
142
142
|
},
|
|
143
143
|
"hook:auto-approve-permissions": {
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
"domain": "safety",
|
|
147
147
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
148
148
|
"installedPath": ".instar/hooks/instar/auto-approve-permissions.js",
|
|
149
|
-
"contentHash": "
|
|
149
|
+
"contentHash": "e0ddbc39521447ae1bfecddfc98b2bd579400889d5fac37cf7df7d380e6a2fb7",
|
|
150
150
|
"since": "2025-01-01"
|
|
151
151
|
},
|
|
152
152
|
"job:health-check": {
|
|
@@ -1554,7 +1554,7 @@
|
|
|
1554
1554
|
"type": "subsystem",
|
|
1555
1555
|
"domain": "updates",
|
|
1556
1556
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
1557
|
-
"contentHash": "
|
|
1557
|
+
"contentHash": "e0ddbc39521447ae1bfecddfc98b2bd579400889d5fac37cf7df7d380e6a2fb7",
|
|
1558
1558
|
"since": "2025-01-01"
|
|
1559
1559
|
},
|
|
1560
1560
|
"subsystem:scheduler": {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: minor -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
**This release is the feedback-factory sender repoint** (docs/specs/feedback-factory-migration.md §2.5 Phase 4): the fleet's canonical feedback endpoint moves from Portal's receiver (`dawn.bot-me.ai/api/instar/feedback`) to the Instar operated instance's canonical front (`feedback.dawn-tunnel.dev/api/feedback`) — a live, verified Vercel receiver whose DNS zone is operator-controlled. (`feedback.instar.sh` is the intended long-term name; its DNS was not reachable at repoint time, so the operated endpoint went live on `feedback.dawn-tunnel.dev` first. A later re-point to instar.sh, if that becomes serviceable, is a one-line constant change + an idempotent migration.)
|
|
9
|
+
|
|
10
|
+
- **Single-source constant.** `src/core/canonicalFeedback.ts` now defines `CANONICAL_FEEDBACK_URL` + `LEGACY_FEEDBACK_URLS`; the Config loader default and both init shapes consume it (the literal URL can never drift across call sites again — pinned by test).
|
|
11
|
+
- **Migration Parity (the actual fleet repoint).** An idempotent `PostUpdateMigrator.migrateConfig` block rewrites a deployed agent's `feedback.webhookUrl` to the canonical front **only when it exactly equals a known legacy canonical default**. A custom operator webhook URL is structurally untouched (exact-match allowlist). Variant spellings that miss the match keep working through the old receiver's 301/proxy-forward (spec Phase 5) — the long tail loses nothing.
|
|
12
|
+
- **Unchanged:** the HMAC signing model and shared secret (same key through cutover, spec §2.9), the sender code itself, and `dispatches.dispatchUrl` (the dispatch move is sequenced separately).
|
|
13
|
+
|
|
14
|
+
## What to Tell Your User
|
|
15
|
+
|
|
16
|
+
- "The address I send Instar bug reports and feedback to has moved to its new home (run by the Instar maintainer). This happened automatically with this update — nothing for you to do, and no reports were lost: the old address keeps forwarding while the fleet rolls over."
|
|
17
|
+
- "If you ever configured a CUSTOM feedback webhook of your own, it was not touched."
|
|
18
|
+
|
|
19
|
+
## Summary of New Capabilities
|
|
20
|
+
|
|
21
|
+
| Capability | How to Use |
|
|
22
|
+
|-----------|-----------|
|
|
23
|
+
| Canonical feedback endpoint (stable) | Automatic — `feedback.webhookUrl` repoints on update; new installs get it via `init` |
|
|
24
|
+
| Single-source endpoint constant | `src/core/canonicalFeedback.ts` (`CANONICAL_FEEDBACK_URL`) |
|
|
25
|
+
|
|
26
|
+
## Evidence
|
|
27
|
+
|
|
28
|
+
- `tests/unit/PostUpdateMigrator-feedbackUrlRepoint.test.ts`: both sides of the rewrite decision boundary (legacy URL repointed / custom URL untouched), idempotency (second run = no change), no-invention on absent config, legacy-list regression pin, and the canonical URL passing the sender's own `validateWebhookUrl` gate.
|
|
29
|
+
- `tests/unit/feedback-webhook.test.ts` updated: Config loader resolves through the constant; the legacy literal is banned from the loader source.
|
|
30
|
+
- Full unit suite green; side-effects artifact `upgrades/side-effects/feedback-sender-repoint.md` with independent second-pass review.
|
|
31
|
+
- Live pre-merge gate (operational): a signed HMAC round-trip against `https://feedback.dawn-tunnel.dev/api/feedback` was verified green before this repoint — `200 {received:true}` with the report landing durably in the operated instance's Blob inbox marked `verified:true`.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Side-Effects Review — Canonical feedback URL repoint (Phase-4 cutover flip)
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `feedback-sender-repoint`
|
|
4
|
+
**Date:** `2026-06-11`
|
|
5
|
+
**Author:** `Echo (instar-dev agent)`
|
|
6
|
+
**Second-pass reviewer:** `required (fleet-wide sender repoint — the one-way door) — see appended response`
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
The migration spec's Phase-4 sender repoint (docs/specs/feedback-factory-migration.md §2.5): **merging this PR repoints the entire fleet's feedback sender** to the Echo-operated canonical front, an operator-authorized fleet-wide change. Introduces `src/core/canonicalFeedback.ts` (the single source for the fleet's canonical feedback endpoint: `CANONICAL_FEEDBACK_URL = https://feedback.dawn-tunnel.dev/api/feedback` — the live operated receiver, its DNS zone operator-controlled; `feedback.instar.sh` is the intended long-term name, not DNS-reachable at repoint time — plus the `LEGACY_FEEDBACK_URLS` rewrite allowlist), repoints the three in-code default sites (`src/core/Config.ts` loader default, `src/commands/init.ts` ×2 new-install shapes), and adds the **Migration Parity** arm: an idempotent `PostUpdateMigrator.migrateConfig` block that rewrites a deployed agent's `feedback.webhookUrl` to the canonical front **only when it exactly equals a known legacy canonical default** — an operator's custom URL is structurally untouchable. `dispatches.dispatchUrl` is deliberately NOT flipped (spec sequences the dispatch move separately; the old receiver's Phase-5 proxy-forward covers continuity). Tests: new `PostUpdateMigrator-feedbackUrlRepoint.test.ts` (both sides of the rewrite boundary, idempotency, no-invention, regression pins, sender-validation gate) and the updated `feedback-webhook.test.ts` (single-source + legacy-literal-banned pins).
|
|
11
|
+
|
|
12
|
+
## Decision-point inventory
|
|
13
|
+
|
|
14
|
+
- `migrateConfig` webhookUrl rewrite — **add** — a string-equality membership check against `LEGACY_FEEDBACK_URLS`. Deliberately brittle-and-cheap by design: exact-match-only is the conservative direction (a non-match means NO action), and it holds no blocking authority — it rewrites a default, never gates a flow.
|
|
15
|
+
- Sender POST target (`FeedbackManager`) — **pass-through** — unchanged code; its destination value changes at config level. `validateWebhookUrl` (https + non-internal) passes the new URL (pinned by test).
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 1. Over-block
|
|
20
|
+
|
|
21
|
+
No block/allow surface — over-block not applicable. The closest analogue: the rewrite could "over-fire" on an operator who deliberately pointed at Dawn's legacy URL as a *custom* choice — indistinguishable from the shipped default by construction. Post-cutover that URL is a 301/proxy-forward to the canonical front (spec Phase 5), so even that case lands at the same place. No issue identified.
|
|
22
|
+
|
|
23
|
+
## 2. Under-block
|
|
24
|
+
|
|
25
|
+
The rewrite "under-fires" for an agent whose config carries a variant spelling (trailing slash, http://, different casing) — exact-match misses it. Those agents keep posting to the old URL, which is exactly what the Phase-5 proxy-forward exists for: they keep landing on the canonical front via the forward, losing nothing. The long tail is covered structurally, not by widening the match (widening would risk touching custom URLs — the wrong trade).
|
|
26
|
+
|
|
27
|
+
## 3. Level-of-abstraction fit
|
|
28
|
+
|
|
29
|
+
The constant lives at the core layer (one definition, three consumers + the migrator — no string drift possible again); the repoint of deployed agents lives in the migration layer (`PostUpdateMigrator`), which is the system's designated mechanism for exactly this (Migration Parity standard names this very case: "the sender's canonical feedback URL must flip for EXISTING agents via PostUpdateMigrator"). No layer inversion.
|
|
30
|
+
|
|
31
|
+
## 4. Signal vs authority compliance
|
|
32
|
+
|
|
33
|
+
Compliant — the change adds no detector and no authority. The migration is a one-shot data rewrite with an exact-match guard whose failure mode is "do nothing" (deny-safe in the conservative direction). Reference: docs/signal-vs-authority.md.
|
|
34
|
+
|
|
35
|
+
## 5. Interactions
|
|
36
|
+
|
|
37
|
+
- Composes with the receiver-persistence PR (the canonical front + inbox + drainer must be live and verified BEFORE this merges — preflight-gated in the cutover runbook/windows, not by code coupling; this PR is inert until published + agents update).
|
|
38
|
+
- The migrator block runs inside `migrateConfig` after the PIN block; it touches only `feedback.webhookUrl` and cannot race the ConfigDefaults registry (which only ADDS missing fields, never rewrites existing values — the reason a dedicated block is required at all).
|
|
39
|
+
- `QuotaTracker` (`dawn.bot-me.ai/api/instar/quota`) and `paritySubmitClient`/`integrityPassRunner` (parity tooling) deliberately keep their own URLs — different services, out of Phase-4 scope.
|
|
40
|
+
- The CLAUDE.md "API Authentication" prose in agent templates mentions the old webhook host; the canonical front uses the SAME auth model (User-Agent/X-Instar-Version + HMAC), so the prose stays accurate in mechanism; the host mention is updated by the template's normal regeneration path, not load-bearing.
|
|
41
|
+
|
|
42
|
+
## 6. External surfaces
|
|
43
|
+
|
|
44
|
+
This is the maximal external surface: every deployed agent's feedback sender repoints on its next update. Mitigations are the spec's own: (a) the merge is held to Dawn's freeze window (PR title carries `[HOLD: merge = cutover flip]`); (b) the flip is gradual by nature — agents repoint as they update; the old receiver's Phase-5 proxy-forward catches every not-yet-updated sender; (c) the new URL must pass a live signed HMAC round-trip BEFORE the window opens (preflight gate); (d) the shared `INSTAR_WEBHOOK_SECRET` is unchanged through cutover (spec §2.9), so signed reports verify identically on both receivers.
|
|
45
|
+
|
|
46
|
+
## 7. Rollback cost
|
|
47
|
+
|
|
48
|
+
The spec's own rollback path (Part-3 §5): re-pointing BACK is the same mechanism in reverse — a follow-up release moves `CANONICAL_FEEDBACK_URL` back and the legacy list gains the new URL; deployed agents re-migrate on update. During any gap, Dawn's old receiver is still warm (Phase 5 keeps it as proxy-forward, not dark), so no report is lost in either direction. No data migration, no schema, no state created at merge time beyond config rewrites that are themselves reversible.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Second-pass review response (independent reviewer subagent, 2026-06-11)
|
|
53
|
+
|
|
54
|
+
Concur with the review.
|
|
55
|
+
|
|
56
|
+
1. **The rewrite is genuinely conservative.** `PostUpdateMigrator.ts` gates the rewrite on an exact-string membership check against the one-entry allowlist (`canonicalFeedback.ts`); a custom/variant URL falls through to no action, absent `feedback`/`webhookUrl` invents nothing (ConfigDefaults has no `feedback.webhookUrl` entry — only the unrelated `feedbackPostDelayMs` — so there is no second path that could write a URL), and the write is atomic with a `.bak` backup. Idempotency holds by construction (the canonical URL is pinned out of the legacy list by test).
|
|
57
|
+
2. **No missed in-code default site.** `git grep` over `src/` returns only `paritySubmitClient.ts` (a DIFFERENT endpoint — `/api/instar/feedback-factory/parity-submit`) plus the legacy-list entry; the remaining host mentions (init dispatchUrl ×2, integrityPassRunner, QuotaTracker comment, a grounding-gate doc example) are the deliberate out-of-scope set §5 names. No agent-installed template surface carries the URL.
|
|
58
|
+
3. **Inert before merge, real rollback.** The diff is pure source + tests + docs — nothing executes from an unmerged branch; the repoint only reaches agents via a published release + their next migration run. The rollback claim matches the spec verbatim (Phase-4 repoint "itself reversible (re-migrate to old URL)"). All 9 tests in the two test files pass, covering both sides of the decision boundary, idempotency, and the `validateWebhookUrl` gate.
|
|
59
|
+
4. **Artifact and fragment honesty.** The seven sections match the code; the fragment publishes only at merge (the cutover itself), so it announces nothing as live early. One non-blocking nit: §5 attributed the stale old-host prose to "agent templates" — it actually lives in the repo's own `CLAUDE.md`; substance correct.
|
|
60
|
+
|
|
61
|
+
**Resolution (author, same session):** the nit was fixed in this PR — the repo `CLAUDE.md` webhook line now names the canonical front + the constant module. Iterated and closed.
|