instar 1.3.1102 → 1.3.1103

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.
@@ -2,7 +2,7 @@
2
2
  "schemaVersion": 1,
3
3
  "generatedFrom": "source-tree",
4
4
  "registrySha256": "5413a0c6ef9ba2bda876b509d1c0bfebe450da3708cd5a5d627d6cb836012d58",
5
- "packageVersion": "1.3.1102",
5
+ "packageVersion": "1.3.1103",
6
6
  "guards": [
7
7
  {
8
8
  "ref": "docs/canonical-migration-contracts.json",
@@ -1,5 +1,5 @@
1
1
  {
2
- "sha256": "1b5940b8aeaf30dd2928ddcf2d53334edef2f9ed5c84e1a95eee32885bde51ec",
2
+ "sha256": "134f316424c9c178f1e9512d39504d10c88e6fad36e013596f2e25cff658488f",
3
3
  "registrySha256": "5413a0c6ef9ba2bda876b509d1c0bfebe450da3708cd5a5d627d6cb836012d58",
4
- "packageVersion": "1.3.1102"
4
+ "packageVersion": "1.3.1103"
5
5
  }
@@ -2,5 +2,5 @@
2
2
  "sha256": "5413a0c6ef9ba2bda876b509d1c0bfebe450da3708cd5a5d627d6cb836012d58",
3
3
  "articleCount": 82,
4
4
  "generatedFrom": "docs/STANDARDS-REGISTRY.md",
5
- "packageVersion": "1.3.1102"
5
+ "packageVersion": "1.3.1103"
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.3.1102",
3
+ "version": "1.3.1103",
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",
@@ -22,12 +22,12 @@ try {
22
22
  const report = { version: 1, base, head, authorInScope, scope, allowlistedPaths: [], exempt: false, internalError: false };
23
23
  const writeReport = () => { if (reportPath) writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`); };
24
24
  if (!authorInScope) { report.outOfScopeAuthor = true; await writeReport(); console.log('UX lint: out-of-scope author'); process.exit(0); }
25
- const allowlisted = names.filter((p) => p === 'src/server/routes.ts' || p === 'src/commands/server.ts' || p.startsWith('src/messaging/') || p.startsWith('src/dashboard/') || p.startsWith('src/templates/'));
25
+ const allowlisted = names.filter((p) => p === 'src/server/routes.ts' || p === 'src/commands/server.ts' || p === 'src/scaffold/templates.ts' || p.startsWith('src/messaging/') || p.startsWith('src/dashboard/') || p.startsWith('src/templates/'));
26
26
  report.allowlistedPaths = allowlisted;
27
27
  if (allowlisted.length === 0) { await writeReport(); console.log('UX lint: out of scope'); process.exit(0); }
28
28
  const diff = execFileSync('git', ['diff', '--unified=0', `${base}...${head}`, '--', ...allowlisted], { encoding: 'utf8' });
29
29
  const added = diff.split('\n').filter((line) => line.startsWith('+') && !line.startsWith('+++')).join('\n');
30
- const refactorOnly = !allowlisted.some((p) => p.startsWith('src/templates/') || p === 'src/server/routes.ts' || p === 'src/commands/server.ts')
30
+ const refactorOnly = !allowlisted.some((p) => p.startsWith('src/templates/') || p === 'src/server/routes.ts' || p === 'src/commands/server.ts' || p === 'src/scaffold/templates.ts')
31
31
  && !/(?:^|\s)[`'\"](?:[^`'\"]+)[`'\"]/.test(added);
32
32
  const section = body.match(/^## UX Impact\s*\n([\s\S]*?)(?=^##\s|(?![\s\S]))/im)?.[1]?.trim() || '';
33
33
  if (/UX-Impact:\s*refactor-only/i.test(section) && refactorOnly) { report.exempt = true; report.exemption = 'refactor-only'; await writeReport(); console.log('UX lint PASS: deterministic refactor-only exemption'); process.exit(0); }
@@ -38,7 +38,7 @@ try {
38
38
  }
39
39
  const quoted = [...section.matchAll(/[`'"“]([^`'"”]+)[`'"”]/g)].map((m) => m[1]);
40
40
  if (!quoted.some((q) => q.length > 2 && diff.includes(q))) {
41
- console.error('::error::UX Impact must quote a concrete string from the diff'); process.exit(1);
41
+ console.error(`::error::UX Impact must quote a concrete string from the USER-FACING paths this PR touches (${allowlisted.join(', ')}). Quotes from other changed files are not checked.`); process.exit(1);
42
42
  }
43
43
  await writeReport();
44
44
  console.log(`UX lint PASS: ${allowlisted.length} allowlisted path(s)`);
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "./builtin-manifest.schema.json",
3
3
  "schemaVersion": 1,
4
- "generatedAt": "2026-08-01T12:49:08.286Z",
5
- "instarVersion": "1.3.1102",
4
+ "generatedAt": "2026-08-01T18:24:40.491Z",
5
+ "instarVersion": "1.3.1103",
6
6
  "entryCount": 202,
7
7
  "entries": {
8
8
  "hook:session-start": {
@@ -2,7 +2,7 @@
2
2
  "schemaVersion": 1,
3
3
  "generatedFrom": "source-tree",
4
4
  "registrySha256": "5413a0c6ef9ba2bda876b509d1c0bfebe450da3708cd5a5d627d6cb836012d58",
5
- "packageVersion": "1.3.1102",
5
+ "packageVersion": "1.3.1103",
6
6
  "guards": [
7
7
  {
8
8
  "ref": "docs/canonical-migration-contracts.json",
@@ -1,5 +1,5 @@
1
1
  {
2
- "sha256": "1b5940b8aeaf30dd2928ddcf2d53334edef2f9ed5c84e1a95eee32885bde51ec",
2
+ "sha256": "134f316424c9c178f1e9512d39504d10c88e6fad36e013596f2e25cff658488f",
3
3
  "registrySha256": "5413a0c6ef9ba2bda876b509d1c0bfebe450da3708cd5a5d627d6cb836012d58",
4
- "packageVersion": "1.3.1102"
4
+ "packageVersion": "1.3.1103"
5
5
  }
@@ -2,5 +2,5 @@
2
2
  "sha256": "5413a0c6ef9ba2bda876b509d1c0bfebe450da3708cd5a5d627d6cb836012d58",
3
3
  "articleCount": 82,
4
4
  "generatedFrom": "docs/STANDARDS-REGISTRY.md",
5
- "packageVersion": "1.3.1102"
5
+ "packageVersion": "1.3.1103"
6
6
  }
@@ -0,0 +1,63 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ `scripts/ux-impact-lint.mjs` decides whether a PR counts as user-facing by matching
9
+ changed files against a hard-coded allowlist. That allowlist omitted
10
+ `src/scaffold/templates.ts` — the file the Agent Awareness Standard names as THE
11
+ user-awareness surface ("An agent that doesn't know about a capability effectively
12
+ doesn't have it"). A PR touching only that file matched nothing, hit
13
+ `allowlisted.length === 0`, and exited 0. The change that alters what every agent tells
14
+ its users required no UX declaration at all. `src/templates/` (hook and helper scripts)
15
+ was allowlisted; `src/scaffold/` was not.
16
+
17
+ Three edits, one defect:
18
+
19
+ 1. The `:25` allowlist gains `p === 'src/scaffold/templates.ts'` — the exact file the
20
+ standard names, in the exact exact-match style already used for two other files.
21
+ Deliberately **not** `startsWith('src/scaffold/')`: widening a gate beyond what a
22
+ standard names is a policy change nobody approved.
23
+ 2. The `:30` refactor-only exemption excludes that path too — rewriting agent-visible
24
+ text is never a pure refactor.
25
+ 3. The `:41` failure message now names the concept and lists the paths actually
26
+ searched. It previously read "UX Impact must quote a concrete string from the diff"
27
+ while searching only the allowlisted subset of the diff, so an author who correctly
28
+ quoted a real added line from an unlisted file was told something untrue about why
29
+ they failed.
30
+
31
+ The gating predicate at `:40` is untouched. `scripts/` is CI-only, is not bundled into
32
+ `dist/`, and is executed by no deployed agent, so no running agent's behaviour changes.
33
+
34
+ ## What to Tell Your User
35
+
36
+ None — internal change (no user-facing surface).
37
+
38
+ ## Summary of New Capabilities
39
+
40
+ None — internal change (no user-facing surface).
41
+
42
+ ## Evidence
43
+
44
+ Verified against real commit `e29259c49`, which touches `src/scaffold/templates.ts` and
45
+ zero allowlisted paths (both confirmed by control counts):
46
+
47
+ | lint | result |
48
+ |---|---|
49
+ | shipping (`origin/main`) | `UX lint: out of scope`, exit 0 — gate skipped entirely |
50
+ | patched | engages, exit 1 on `UX-Impact: none` |
51
+ | patched, replaying PR #1813 | exit 0 — no regression on a real passing PR |
52
+
53
+ The static contradiction, with a control: `CLAUDE.md` names `src/scaffold/templates.ts`
54
+ as the user-awareness surface, while `ux-impact-lint.mjs` contained `scaffold` zero
55
+ times (control: `templates` = 2, so the search works and this is a true negative).
56
+
57
+ New test `tests/unit/ux-impact-lint-scaffold-scope.test.ts` covers both sides of the
58
+ boundary and was trip-tested by reverting the lint to `origin/main`: 3/3 pass with the
59
+ fix, 2 fail without it, and the internal-path control passes either way.
60
+
61
+ Known residual, not claimed as fixed: the allowlist remains a proxy for "user-facing"
62
+ and still omits `PostUpdateMigrator.ts`, skill bodies, and hook templates. This closes
63
+ one hole in one list; the list still has no owner and no review trigger.
@@ -0,0 +1,152 @@
1
+ # Side-Effects Review — UX-impact gate: recognise `src/scaffold/templates.ts` as a user-facing path
2
+
3
+ **Version / slug:** `ux-gate-scaffold-scope`
4
+ **Date:** `2026-08-01`
5
+ **Author:** `Echo (instar-dev)`
6
+ **Second-pass reviewer:** `REQUIRED — this change modifies a gate` (see §Second pass)
7
+
8
+ ## Summary of the change
9
+
10
+ `scripts/ux-impact-lint.mjs` decides whether a PR is "user-facing" by matching changed
11
+ files against a hard-coded allowlist (`:25`). That allowlist omitted
12
+ `src/scaffold/templates.ts` — the file the Agent Awareness Standard names as THE
13
+ user-awareness surface ("An agent that doesn't know about a capability effectively
14
+ doesn't have it"). A PR touching only that file therefore hit `allowlisted.length === 0`
15
+ (`:27`) and exited 0, requiring no UX declaration for the change that alters what every
16
+ agent tells its users. Three edits, one defect: the path joins the allowlist (`:25`), it
17
+ also disqualifies the refactor-only exemption (`:30`), and the quote-check failure message
18
+ (`:41`) now names the concept and lists the paths actually searched. Adds
19
+ `tests/unit/ux-impact-lint-scaffold-scope.test.ts`.
20
+
21
+ ## Decision-point inventory
22
+
23
+ - `ux-impact-lint.mjs:25` — **modify** — allowlist membership; adds one exact-match path.
24
+ - `ux-impact-lint.mjs:27` — **pass-through** — the in-scope/out-of-scope exit. Unchanged
25
+ logic; a strictly smaller set of PRs now reaches the `exit(0)` skip.
26
+ - `ux-impact-lint.mjs:30` — **modify** — refactor-only exemption eligibility.
27
+ - `ux-impact-lint.mjs:41` — **modify** — failure MESSAGE only. The predicate at `:40` is
28
+ untouched.
29
+
30
+ ---
31
+
32
+ ## 1. Over-block
33
+
34
+ **What legitimate inputs does this change reject that it shouldn't?**
35
+
36
+ A PR that touches `src/scaffold/templates.ts` for a genuinely non-user-visible reason —
37
+ e.g. renaming a local variable inside `generateClaudeMd()`, or reflowing a comment — now
38
+ requires a UX Impact section where previously it required none. That is a real new cost
39
+ imposed on a legitimate input.
40
+
41
+ Two mitigations, both pre-existing: the `refactor-only` exemption still applies when the
42
+ change adds no quoted strings (`:31`), and the author can satisfy the gate by quoting any
43
+ concrete added string. It is a friction increase, not a wall. Concretely: a
44
+ whitespace-only change to that file will now demand a declaration, which is mildly
45
+ annoying and is the price of the file being in scope at all.
46
+
47
+ ## 2. Under-block
48
+
49
+ **What failure modes does this still miss?**
50
+
51
+ Substantially more than it catches, and this must not be oversold:
52
+
53
+ - The allowlist remains a **proxy** for "user-facing" and still omits every other path
54
+ that can reach a user — `src/core/PostUpdateMigrator.ts` (which writes agent-visible
55
+ guidance on upgrade), skill `SKILL.md` bodies, `src/data/http-hook-templates.ts`, and
56
+ any future file that renders text a human reads.
57
+ - The gate only fires on **PR paths**, so a user-visible change delivered by a config
58
+ default or a runtime string has no coverage here at all.
59
+ - A PR touching `src/scaffold/templates.ts` **and** an already-allowlisted file was
60
+ already in scope, so for that (common) shape this change alters nothing.
61
+ - The quote check is satisfied by ANY quoted substring present in the allowlisted diff.
62
+ An author can still quote something trivially true and unrelated to the actual user
63
+ impact. This change does not make declarations honest; it makes them required.
64
+
65
+ ## 3. Level-of-abstraction fit
66
+
67
+ The fix operates at the same level as the defect: a path missing from a path list is
68
+ repaired by adding the path. No new abstraction, no new config surface, no new file.
69
+ The alternative — deriving "user-facing" from something semantic rather than a path list
70
+ — would be a genuinely better design and is deliberately NOT attempted here; it is a
71
+ redesign, not a fix, and would ship as its own spec.
72
+
73
+ ## 4. Signal vs authority compliance
74
+
75
+ The gate is an **authority** (it exits non-zero and blocks a PR), and it stays exactly as
76
+ authoritative as it was — the change alters WHICH files it considers, never WHETHER it
77
+ may block. No new authority is created. The message change at `:41` is pure signal
78
+ improvement and carries no gating weight.
79
+
80
+ Notably this change does not grant the gate any new power over anything outside the repo,
81
+ and it cannot affect a running agent: `scripts/` is CI-only and ships in no runtime path.
82
+
83
+ ## 4b. Judgment-point check (Judgment Within Floors standard)
84
+
85
+ No judgment point is added. Every predicate is deterministic string matching; there is no
86
+ LLM call, no heuristic, and no scoring. The one judgment exercised was authorial and is
87
+ recorded here: **exact-match `src/scaffold/templates.ts` rather than
88
+ `startsWith('src/scaffold/')`**, because the standard names one file and widening a gate
89
+ beyond what a standard names is a policy change no one approved.
90
+
91
+ ## 5. Interactions
92
+
93
+ - **`.github/workflows/ux-impact-pr-gate.yml`** — unchanged. Its `paths:` trigger already
94
+ includes `scripts/ux-impact-lint.mjs`, so the workflow's own trigger set needs no edit.
95
+ - **Agent Awareness Standard (CLAUDE.md)** — this change makes the gate agree with the
96
+ standard rather than contradict it. Nothing else consumes the allowlist.
97
+ - **`report.allowlistedPaths`** (`:26`) — the emitted JSON report may now contain one more
98
+ path. Any downstream consumer reading that array sees a longer list; no consumer in this
99
+ repo branches on its contents.
100
+ - **No interaction with the release pipeline, migrations, or PostUpdateMigrator.**
101
+
102
+ ## 6. External surfaces
103
+
104
+ None. `scripts/ux-impact-lint.mjs` runs only in CI, is not bundled into `dist/`, is not
105
+ served by any route, and is never executed by a deployed agent. No API, no dashboard, no
106
+ Telegram surface, no config key. The only humans who observe a behaviour change are
107
+ contributors opening PRs against this repo.
108
+
109
+ ## 6b. Operator-surface quality (Operator-Surface Quality standard)
110
+
111
+ The operator-visible surface is the CI failure message, and this change exists partly to
112
+ improve it. Before: `UX Impact must quote a concrete string from the diff` — which is
113
+ misleading, because the script searches only the allowlisted subset of the diff, so an
114
+ author quoting a genuine added line from an unlisted file is told something false about
115
+ why they failed. After: the message names the concept ("the USER-FACING paths this PR
116
+ touches"), enumerates those paths, and states plainly that quotes from other changed files
117
+ are not checked. An author can now self-diagnose in one read.
118
+
119
+ ## 7. Multi-machine posture (Cross-Machine Coherence)
120
+
121
+ Not applicable. CI-only script with no state, no lease interaction, no replication, and no
122
+ per-machine behaviour. It executes once per workflow run on a GitHub runner.
123
+
124
+ ---
125
+
126
+ ## Risks accepted
127
+
128
+ 1. **Friction on incidental edits** to `src/scaffold/templates.ts` (§1). Accepted: the
129
+ file's whole purpose is agent-visible text, so incidental edits are rare and a
130
+ declaration is cheap.
131
+ 2. **The proxy remains a proxy** (§2). Accepted for this change and explicitly NOT claimed
132
+ as fixed. The allowlist still has no owner and no review trigger; that is a real
133
+ residual and is stated in the ELI16 rather than hidden.
134
+
135
+ ## Evidence
136
+
137
+ Verified against real commit `e29259c49` (touches `src/scaffold/templates.ts`, zero
138
+ allowlisted paths — both confirmed by control counts):
139
+
140
+ | lint | result |
141
+ |---|---|
142
+ | shipping (`origin/main`) | `UX lint: out of scope`, **exit 0** — gate skipped |
143
+ | patched | engages, **exit 1** on `UX-Impact: none` |
144
+ | patched, replaying PR #1813 | **exit 0** — no regression on a real passing PR |
145
+
146
+ Tests trip-tested in both directions: **3/3 pass** with the fix; **2 fail** without it;
147
+ the internal-path control passes either way (as a control must).
148
+
149
+ ## Second pass
150
+
151
+ This change modifies a **gate**, which mandates second-pass review. Requested from Codey
152
+ on the PR. Not self-certified: the reviewer's response will be appended here.