instar 1.3.428 → 1.3.430

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.3.428",
3
+ "version": "1.3.430",
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-06-08T06:00:17.512Z",
5
- "instarVersion": "1.3.428",
4
+ "generatedAt": "2026-06-08T08:01:57.520Z",
5
+ "instarVersion": "1.3.430",
6
6
  "entryCount": 199,
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": "02ef1d845e3c49eba88d81c593bc621105d7e3c2f943cccaafcb9194ab5eb4c9",
14
+ "contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
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": "02ef1d845e3c49eba88d81c593bc621105d7e3c2f943cccaafcb9194ab5eb4c9",
23
+ "contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
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": "02ef1d845e3c49eba88d81c593bc621105d7e3c2f943cccaafcb9194ab5eb4c9",
32
+ "contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
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": "02ef1d845e3c49eba88d81c593bc621105d7e3c2f943cccaafcb9194ab5eb4c9",
41
+ "contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
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": "02ef1d845e3c49eba88d81c593bc621105d7e3c2f943cccaafcb9194ab5eb4c9",
50
+ "contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
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": "02ef1d845e3c49eba88d81c593bc621105d7e3c2f943cccaafcb9194ab5eb4c9",
59
+ "contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
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": "02ef1d845e3c49eba88d81c593bc621105d7e3c2f943cccaafcb9194ab5eb4c9",
68
+ "contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
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": "02ef1d845e3c49eba88d81c593bc621105d7e3c2f943cccaafcb9194ab5eb4c9",
77
+ "contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
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": "02ef1d845e3c49eba88d81c593bc621105d7e3c2f943cccaafcb9194ab5eb4c9",
86
+ "contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
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": "02ef1d845e3c49eba88d81c593bc621105d7e3c2f943cccaafcb9194ab5eb4c9",
95
+ "contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
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": "02ef1d845e3c49eba88d81c593bc621105d7e3c2f943cccaafcb9194ab5eb4c9",
104
+ "contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
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": "02ef1d845e3c49eba88d81c593bc621105d7e3c2f943cccaafcb9194ab5eb4c9",
113
+ "contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
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": "02ef1d845e3c49eba88d81c593bc621105d7e3c2f943cccaafcb9194ab5eb4c9",
122
+ "contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
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": "02ef1d845e3c49eba88d81c593bc621105d7e3c2f943cccaafcb9194ab5eb4c9",
131
+ "contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
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": "02ef1d845e3c49eba88d81c593bc621105d7e3c2f943cccaafcb9194ab5eb4c9",
140
+ "contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
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": "02ef1d845e3c49eba88d81c593bc621105d7e3c2f943cccaafcb9194ab5eb4c9",
149
+ "contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
150
150
  "since": "2025-01-01"
151
151
  },
152
152
  "job:health-check": {
@@ -1122,7 +1122,7 @@
1122
1122
  "type": "template",
1123
1123
  "domain": "operations",
1124
1124
  "sourcePath": "src/templates/scripts/convergence-check.sh",
1125
- "contentHash": "0908e2775c497fe526b817563b6f8e29ec4d6bedaf5521a87e625857afc367c3",
1125
+ "contentHash": "4c67cf4d7dc23ac21a1b658e8acf3d3f925c1610afab9291d2cff8d48920fc33",
1126
1126
  "since": "2025-01-01"
1127
1127
  },
1128
1128
  "template:emit-session-clock.sh": {
@@ -1538,7 +1538,7 @@
1538
1538
  "type": "subsystem",
1539
1539
  "domain": "updates",
1540
1540
  "sourcePath": "src/core/PostUpdateMigrator.ts",
1541
- "contentHash": "02ef1d845e3c49eba88d81c593bc621105d7e3c2f943cccaafcb9194ab5eb4c9",
1541
+ "contentHash": "58ca88e808087ef78a28a17ac93387acfa661a4e66a152197bb043218465f85f",
1542
1542
  "since": "2025-01-01"
1543
1543
  },
1544
1544
  "subsystem:scheduler": {
@@ -132,7 +132,7 @@ PY
132
132
  continue
133
133
  fi
134
134
  # Skip well-known service domains + common agent tunnel domains.
135
- if echo "$url" | grep -qE '(github\.com|vercel\.app|vercel\.com|netlify\.app|netlify\.com|npmjs\.com|npmjs\.org|cloudflare\.com|google\.com|twitter\.com|x\.com|youtube\.com|reddit\.com|discord\.com|discord\.gg|telegram\.org|t\.me|localhost|127\.0\.0\.1|stackoverflow\.com|developer\.mozilla\.org|docs\.anthropic\.com|anthropic\.com|openai\.com|claude\.ai|notion\.so|linear\.app|fly\.io|render\.com|railway\.app|heroku\.com|amazonaws\.com|azure\.com|gitlab\.com|bitbucket\.org|docker\.com|hub\.docker\.com|pypi\.org|crates\.io|rubygems\.org|pkg\.go\.dev|wikipedia\.org|medium\.com|substack\.com|circle\.so|ghost\.io|telegraph\.ph)'; then
135
+ if echo "$url" | grep -qE '(github\.com|vercel\.app|vercel\.com|netlify\.app|netlify\.com|npmjs\.com|npmjs\.org|cloudflare\.com|google\.com|twitter\.com|x\.com|youtube\.com|reddit\.com|discord\.com|discord\.gg|telegram\.org|t\.me|localhost|127\.0\.0\.1|stackoverflow\.com|developer\.mozilla\.org|docs\.anthropic\.com|anthropic\.com|openai\.com|claude\.ai|claude\.com|notion\.so|linear\.app|fly\.io|render\.com|railway\.app|heroku\.com|amazonaws\.com|azure\.com|gitlab\.com|bitbucket\.org|docker\.com|hub\.docker\.com|pypi\.org|crates\.io|rubygems\.org|pkg\.go\.dev|wikipedia\.org|medium\.com|substack\.com|circle\.so|ghost\.io|telegraph\.ph)'; then
136
136
  continue
137
137
  fi
138
138
  UNFAMILIAR_URLS="$UNFAMILIAR_URLS $url\n"
@@ -0,0 +1,81 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ The pre-messaging convergence check's `url_provenance` allowlist now trusts
9
+ `claude.com` alongside the already-listed `claude.ai`, `anthropic.com`, and
10
+ `docs.anthropic.com`. The same domain was added to both copies that must agree:
11
+ the primary script (`src/templates/scripts/convergence-check.sh`) and the
12
+ can't-find-template fallback in `PostUpdateMigrator.getConvergenceCheckInline()`.
13
+ This stops the grounding-before-messaging hook from false-flagging Claude
14
+ subscription OAuth login links (which live on `claude.com`) as possibly-fabricated.
15
+
16
+ The enrollment wizard now attaches an operator-facing heads-up to a pending Claude
17
+ login, warning that a brand-new Claude account login asks for TWO codes in sequence
18
+ — an email-verification code first, then the sign-in code. `PendingLogin` gains an
19
+ optional `notice` field; `EnrollmentWizard.flowNotice(kind)` produces the warning
20
+ for the `url-code-paste` (Claude) flow and nothing for `device-code` (Codex); the
21
+ dashboard's Pending Logins panel renders it above the code. Codex enrollment is
22
+ unchanged.
23
+
24
+ ## What to Tell Your User
25
+
26
+ When I send you a Claude sign-in link to enroll a subscription account, it now goes
27
+ to you directly. Before, my own link-safety check mistook the official claude.com
28
+ sign-in page for a possibly-made-up address and made me wrap it in a private page
29
+ first — that false alarm is gone.
30
+
31
+ When I set up a new Claude account for you, the login card now warns you up front
32
+ that Claude will ask for two codes in a row — the email-verification code first,
33
+ then the sign-in code. No more being surprised by the second prompt.
34
+
35
+ ## Summary of New Capabilities
36
+
37
+ - **claude.com is a trusted domain** in the pre-messaging link-safety check — Claude
38
+ OAuth login links deliver directly instead of being flagged as unfamiliar.
39
+ - Existing agents get it automatically (the updater re-writes the deployed script
40
+ from the template on every update); no separate migration.
41
+
42
+ - **Two-code heads-up on Claude enrollment** — the pending-login card explains the
43
+ email-code-then-sign-in-code sequence before you start.
44
+ - **`PendingLogin.notice`** — an optional, sanitized, operator-facing flow heads-up
45
+ (extensible to other flow quirks later); Codex/device-code flows carry none.
46
+ - Ships with the normal instar update (server + dashboard); no migration needed.
47
+
48
+ ## Evidence
49
+
50
+ Found during live subscription enrollment (topic 20905): driving a fresh Claude
51
+ login produces a sign-in URL on `claude.com`, and delivering it tripped the
52
+ `URL_PROVENANCE` gate because `claude.com` was absent from the allowlist while its
53
+ sibling `claude.ai` was present.
54
+
55
+ Reproduction — pipe an outbound message containing a `claude.com` link through the
56
+ gate:
57
+ - **Before:** `echo 'Sign in: https://claude.com/oauth/authorize?code=abc' | bash
58
+ .instar/scripts/convergence-check.sh` → exit 1, output contains `URL_PROVENANCE`
59
+ (so the link had to be wrapped in a private view to be sent).
60
+ - **After:** same input → exit 0, no `URL_PROVENANCE` flag.
61
+
62
+ A sibling test still proves a genuinely fabricated domain (`fabricated-domain.xyz`)
63
+ is flagged, so only this one first-party domain was loosened. Locked in by a new
64
+ `convergence-check.test.ts` case.
65
+
66
+ Found during live enrollment (topic 20905): enrolling a fresh Claude account, the
67
+ operator was asked for an email-verification code first and then a separate sign-in
68
+ code, with nothing explaining the second prompt — reported as confusing.
69
+
70
+ Reproduction / before-after:
71
+ - **Before:** starting a `url-code-paste` enrollment produced a pending login with
72
+ only a code + URL; the two-code sequence was undocumented, so the operator hit an
73
+ unexplained second code prompt.
74
+ - **After:** the same enrollment produces a pending login whose `notice` reads
75
+ "a brand-new Claude login often asks for TWO codes in order — first an
76
+ email-verification code … then the sign-in code …", shown on the dashboard card.
77
+ A `device-code` (Codex) enrollment still carries no notice.
78
+
79
+ Locked in by new `enrollment-wizard.test.ts`, `pending-login-store.test.ts`, and
80
+ `subscriptions-render.test.ts` cases (notice present for Claude / absent for Codex;
81
+ rendered when present / element omitted when not).
@@ -0,0 +1,21 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ Added a new built-in skill, `/iterative-converging-audit`, and the constitution standard it operationalizes ("Iterative Audit to Convergence"), plus its paired safety standard ("No Silent Degradation to Brittle Fallback") in `docs/STANDARDS-REGISTRY.md`. The skill turns any "find all instances of X" task — security audit, safety audit, code review, research sweep, compliance check — into a structured loop that does not stop at one pass: frame the target, sweep, fix-or-classify each finding, then RE-sweep the full surface, repeating until a clean pass returns zero new discoveries. It ships to every agent via `installBuiltinSkills`, so any agent can invoke it.
9
+
10
+ ## What to Tell Your User
11
+
12
+ I now have a reusable "audit until it's actually done" skill. Instead of looking once and saying "looks clean," it runs a proper loop — sweep, fix what it finds, then sweep again — until a fresh pass turns up nothing new. It works for security reviews, safety audits, research, any "did we get everything?" job, and it's honest: if it has to stop early it says "incomplete," it never dresses up a half-finished sweep as thorough. I also wrote the principle behind it into my constitution so it's a standard I hold myself to, not just a tool.
13
+
14
+ ## Summary of New Capabilities
15
+
16
+ - `/iterative-converging-audit` — a built-in, user-invocable skill that runs any find-all sweep as an audit → fix → re-audit loop to convergence, with a written findings ledger and a "leave a standing ratchet" step so the converged state cannot silently regress.
17
+ - Two new constitution standards in the registry: "Iterative Audit to Convergence" (thorough means converged, not one-pass) and "No Silent Degradation to Brittle Fallback" (a gating LLM call must swap-provider or fail-closed, never silently drop to a heuristic).
18
+
19
+ ## Evidence
20
+
21
+ The skill's own worked example is the proof that one-pass audits miss things: the LLM-fallback safety audit reported "~20 sites" on its first sweep, but a re-sweep of the full surface after the fixes landed found **44** call sites — more than double. That gap between round 1 and round 2 is exactly what the convergence loop exists to catch. Verified in dev: `installBuiltinSkills` writes `iterative-converging-audit/SKILL.md` (install + idempotency test green), `pnpm build` is clean, and the skill content documents the audit→fix→re-audit loop, the honest-incompleteness rule, and the standing-ratchet step.
@@ -0,0 +1,36 @@
1
+ # Iterative Converging Audit — skill + standard — Plain-English Overview
2
+
3
+ > The one-line version: a reusable "audit until a fresh look finds nothing new" skill, plus the constitution standard that makes "thorough" mean "converged."
4
+
5
+ ## The problem in one breath
6
+
7
+ When you ask an agent to "find all the places we do X" — a security hole, an unsafe pattern, a missing check — it tends to sweep once, fix what it sees, and declare victory. But a single pass always has blind spots, and the fixes themselves move things around or reveal new instances. "I looked once and stopped finding things" usually means "I got tired," not "there is nothing left." So audits silently miss things, and nobody can tell a thorough audit from a lazy one after the fact.
8
+
9
+ ## What already exists
10
+
11
+ - **Lots of one-off audits.** Agents already run sweeps when asked, but each is ad-hoc — no defined loop, no convergence test, no honest "I stopped early" signal.
12
+ - **The `no-*` ratchet pattern.** The codebase already uses CI tests that fail when a banned pattern reappears (for example the new `no-silent-llm-fallback` test). Those are the "standing guard" that keeps an audit from silently regressing — but there was no general method that told you to leave one.
13
+ - **The constitution registry** (`docs/STANDARDS-REGISTRY.md`) — the place where earned standards live. It did not yet name the iterative-audit principle, even though the operator had asked for it more than once.
14
+
15
+ ## What this adds
16
+
17
+ A new built-in skill, `/iterative-converging-audit`, that any agent can invoke for any find-all task. It encodes the loop explicitly: FRAME the target and search surface; AUDIT (round 1) recording every finding; FIX or classify each finding with a written reason; RE-AUDIT the whole surface again — because your search surface grew and the fixes moved things; and repeat until a clean pass returns zero new discoveries. Only then may you call it converged, and you state how many rounds it took. If you stop for time or budget, you must say "incomplete" — never dress up an exhausted audit as a thorough one. The last step says: where the pattern can be expressed in CI, leave a ratchet so the converged state cannot silently un-converge on the next commit.
18
+
19
+ Alongside the skill, two constitution standards are added to the registry: "Iterative Audit to Convergence" (the principle above) and its paired "No Silent Degradation to Brittle Fallback" (a gating LLM call must swap provider or fail closed, never silently drop to a brittle heuristic) — the safety standard whose own audit is the skill's first worked example.
20
+
21
+ ## The new pieces
22
+
23
+ - **The skill** — a methodology document installed to every agent's skill set. It is process, not code: it does not call any API; it tells the agent how to run an honest, converging audit and how to leave a standing guard behind.
24
+ - **The standards** — durable entries in the constitution, each with the "earned from" story so future agents know why the rule exists.
25
+
26
+ ## The safeguards
27
+
28
+ **Prevents fake thoroughness.** The honesty rule — say "incomplete" when you stopped early — is the core guard. It makes a half-done audit legible instead of indistinguishable from a complete one.
29
+
30
+ **Prevents silent regression.** The standing-guard step turns a converged audit into a CI ratchet wherever possible, so the next commit can't quietly undo it.
31
+
32
+ **Prevents accepted findings from rotting.** An accepted (won't-fix) finding must carry a written reason, so a later reader can tell "reviewed and fine" from "missed."
33
+
34
+ ## What ships when
35
+
36
+ One PR. The skill ships to every agent through the normal built-in-skill install path; existing agents pick it up on their next update. Nothing is enabled or disabled — it is a new capability plus two documented standards.
@@ -0,0 +1,41 @@
1
+ # Side-effects review — claude.com in the URL-provenance allowlist
2
+
3
+ ## Change
4
+
5
+ Adds `claude.com` to the `url_provenance` allowlist of the pre-messaging
6
+ convergence check, in BOTH copies that must stay in sync:
7
+ - `src/templates/scripts/convergence-check.sh` (the primary script, read at runtime)
8
+ - `src/core/PostUpdateMigrator.ts` → `getConvergenceCheckInline()` (the fallback
9
+ emitted only when the template file can't be found)
10
+
11
+ It sits next to the already-present `claude.ai` and `anthropic.com` entries.
12
+
13
+ ## Why
14
+
15
+ The Claude subscription OAuth login link lives on `claude.com` (Anthropic
16
+ consolidated the sign-in surface there; `claude.ai` is the sibling already on the
17
+ list). During live enrollment testing (topic 20905) the grounding-before-messaging
18
+ hook false-flagged the login link as `URL_PROVENANCE` (a possibly-fabricated
19
+ domain), which forced wrapping every OAuth link in a private view before it could
20
+ be sent to the operator. Allowlisting `claude.com` lets enrollment links be
21
+ delivered directly.
22
+
23
+ ## Side effects considered
24
+
25
+ - **Weakens the provenance gate for claude.com?** Marginally and acceptably:
26
+ `claude.com` is Anthropic's official first-party domain (same trust class as the
27
+ already-listed `claude.ai`, `anthropic.com`, `docs.anthropic.com`). The allowlist
28
+ exists precisely to stop second-guessing well-known service domains. The gate
29
+ still flags every genuinely unfamiliar/fabricated domain — the regression test
30
+ keeps `fabricated-domain.xyz` flagged.
31
+ - **Drift between the two copies.** Both are edited identically in this change. The
32
+ template is authoritative; the inline is a can't-find-template fallback. No new
33
+ divergence introduced.
34
+ - **Migration parity.** Existing agents receive the updated allowlist because
35
+ `PostUpdateMigrator` re-writes `.instar/scripts/convergence-check.sh` from the
36
+ template on every update run (built-in script, always overwritten) — no separate
37
+ migration needed; the edit to the template IS the migration path.
38
+ - **No API, config, schema, or route surface touched.** Behavior-only change to a
39
+ heuristic gate. No new dependencies. Idempotent.
40
+ - **Blast radius:** one extra alternation in one regex, in two places. Reversible
41
+ by removing the `claude\.com` token.
@@ -0,0 +1,42 @@
1
+ # Side-effects review — enrollment two-code heads-up
2
+
3
+ ## Change
4
+
5
+ Surfaces an operator-facing heads-up on a pending login about the Claude
6
+ url-code-paste flow's two-code sequence (email-verification code first, then the
7
+ sign-in code). Three pieces:
8
+ - `PendingLoginStore`: new optional `notice?: string` on `PendingLogin` +
9
+ `IssueLoginInput`; `issue()` persists it when present (omitted otherwise).
10
+ - `EnrollmentWizard`: new `static flowNotice(kind)` returns the two-code warning
11
+ for `url-code-paste` and `undefined` for `device-code`; `start()` attaches it.
12
+ - `dashboard/subscriptions.js`: `renderPendingLogins` shows a `sub-pending-notice`
13
+ row (sanitized text) when a notice is present.
14
+
15
+ ## Why
16
+
17
+ Live enrollment testing (topic 20905): enrolling a fresh Claude account makes
18
+ Anthropic ask for TWO codes in sequence — an email-verification code, then the
19
+ sign-in code — and the operator found the unexplained second prompt confusing. The
20
+ wizard now tells them what to expect up front.
21
+
22
+ ## Side effects considered
23
+
24
+ - **Backward compatibility / persistence.** `notice` is optional and omitted when
25
+ absent, so existing pending-login JSON records (written before this change) load
26
+ unchanged — no migration. `issue()` only adds the key when a non-empty notice is
27
+ passed, matching the file's existing `...(x ? {x} : {})` style.
28
+ - **Not a secret.** The notice is static guidance text — never a credential, code,
29
+ or URL. It passes the store's `assertNoCredentialFields` (it's a fixed string set
30
+ by the wizard, not derived from login input).
31
+ - **XSS / display safety.** Rendered through the existing `sanitizeForDisplay`
32
+ (NFKC + control/bidi strip + grapheme cap) as inert text in a `div` — never an
33
+ href or innerHTML. Covered by the render tests (notice present → shown; absent →
34
+ element omitted) alongside the existing javascript:-URL inertness test.
35
+ - **device-code (Codex) flows are unchanged** — `flowNotice('device-code')` is
36
+ undefined, so no notice is attached and the row renders exactly as before.
37
+ - **Reach to existing agents.** Server code (PendingLoginStore/EnrollmentWizard)
38
+ and the dashboard asset ship with the instar package, so agents get this on the
39
+ normal package update — no `.instar/`-copied file and no PostUpdateMigrator entry
40
+ required.
41
+ - **Blast radius:** one optional field + one pure static method + one conditional
42
+ render row. Reversible by dropping the field.
@@ -0,0 +1,39 @@
1
+ # Side-Effects Review — iterative-converging-audit skill + two constitution standards
2
+
3
+ **Version / slug:** `iterative-converging-audit-skill`
4
+ **Date:** `2026-06-08`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `self-review under the Tier-1 lite lane`
7
+
8
+ ## Summary of the change
9
+
10
+ Adds a new built-in skill `iterative-converging-audit` (registered inline in `installBuiltinSkills` in `src/commands/init.ts`, with a source copy at `skills/iterative-converging-audit/SKILL.md`), an install unit test, and two entries in `docs/STANDARDS-REGISTRY.md` ("Iterative Audit to Convergence" and "No Silent Degradation to Brittle Fallback"). The skill is pure methodology — it calls no API and gates nothing; it tells an agent how to run a find-all sweep as an audit→fix→re-audit loop to convergence.
11
+
12
+ ## Decision-point inventory
13
+
14
+ - New skill registration — added — first entry in the `installBuiltinSkills` `skills` object; `installBuiltinSkills` is install-if-missing, so existing agents receive it on the next update without a migration (per Migration Parity Standard's "adding a new skill" case).
15
+ - Constitution registry — added — two `###` standard entries in the Substrate section, in the house format (Rule / In practice / Earned from / Traces to the goal).
16
+ - Test — added — `tests/unit/init-iterativeConvergingAuditSkill.test.ts` mirrors the verify-claim skill test (install + frontmatter + content assertions + idempotency).
17
+
18
+ ## 1. Direction-of-failure analysis
19
+
20
+ - **No runtime gate touched.** The skill is content installed to `.claude/skills/`; it does not run in any request path, does not classify, does not block. There is no fail-open/fail-closed surface to get wrong.
21
+ - **Install path:** `installBuiltinSkills` is non-destructive (install-if-missing) — verified by the idempotency test: a user-customized copy is NOT overwritten on re-run. So shipping this cannot clobber a customized skill.
22
+ - **No behavior change for existing flows.** Adding a key to the `skills` object cannot affect the other skills' installation; the build + the feature-delivery-completeness suite (83 tests) confirm parity is intact.
23
+
24
+ ## 2. Over-permit
25
+
26
+ None. No new capability is granted to anything — the skill is advisory text. No new route, no config, no permission.
27
+
28
+ ## 3. Scope deliberately NOT taken
29
+
30
+ - A CLI/API surface for "run an audit" — out of scope; the skill is a methodology an agent applies, not an endpoint.
31
+ - Auto-applying the iterative loop to existing audit jobs — out of scope; this PR ships the reusable skill + standards; wiring specific jobs to it is follow-up.
32
+
33
+ ## 4. Migration parity
34
+
35
+ Covered. Adding a new built-in skill needs no migration — `installBuiltinSkills` runs on every update and writes missing skill files. Existing agents get `/iterative-converging-audit` on their next update; new agents get it at init. The `skills/<name>/SKILL.md` source copy follows the established #791 (agent-readiness) pattern.
36
+
37
+ ## 5. Token/cost impact
38
+
39
+ None at rest. When invoked, the skill shapes the agent's own audit work; it adds no background LLM calls.