instar 1.3.1017 → 1.3.1018

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.1017",
3
+ "version": "1.3.1018",
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",
@@ -115,18 +115,39 @@ for (const file of specFiles()) {
115
115
  try { text = fs.readFileSync(file, 'utf8'); } catch { continue; }
116
116
  const fm = frontmatter(text);
117
117
  if (!fm) continue;
118
- if (field(fm, 'rollout-disposition') !== 'active') continue;
118
+ // GUARDED DISPOSITIONS — 'active' AND 'composed'.
119
+ //
120
+ // 'composed' does NOT mean exempt. It names WHO owns graduation (the rollout rides
121
+ // an owner feature via rollout-owner-feature) rather than WHETHER the evidence
122
+ // matters. A composed spec still carries a real rollout-criteria naming a
123
+ // measurement, and often rollout-metrics-json thresholds against it. If its ref
124
+ // 404s the criterion is exactly as unevaluable as an active one's, and the feature
125
+ // parks for exactly the same reason.
126
+ //
127
+ // Widening is safe BECAUSE of assertion C rather than in spite of it: a composed
128
+ // spec whose owner feature was genuinely abandoned may legitimately carry a stale
129
+ // ref, and the shrink-only baseline is where that goes — with a stated reason,
130
+ // deleted automatically the moment the ref starts resolving. So this does not force
131
+ // anyone to FIX anything; it forces them to DECLARE. Entry needs evidence.
132
+ //
133
+ // EARNED (2026-07-27): this lint shipped guarding 'active' only, and its own header
134
+ // said "a sweep of all 5 rollout-active specs" — accurate for its scope, and the
135
+ // scope was narrower than the class it names. A single-pass sweep is incomplete by
136
+ // definition (Iterative Audit to Convergence); this is that standard applied to the
137
+ // guard itself, one pass later.
138
+ const disposition = field(fm, 'rollout-disposition');
139
+ if (disposition !== 'active' && disposition !== 'composed') continue;
119
140
  if (field(fm, 'rollout-evidence-type') !== 'endpoint') continue;
120
141
  const ref = field(fm, 'rollout-evidence-ref');
121
142
  if (!ref || !ref.startsWith('/')) continue; // unparseable ⇒ skip, not fail
122
143
  const slug = field(fm, 'slug') || path.basename(file, '.md');
123
144
  const resolves = srcContains(ref);
124
- seenActive.push({ slug, ref, resolves });
145
+ seenActive.push({ slug, ref, resolves, disposition });
125
146
 
126
147
  // A — every active endpoint ref resolves, unless explicitly accepted.
127
148
  if (!resolves && !allowed.has(slug)) {
128
149
  errors.push(
129
- `${path.relative(ROOT, file)}: rollout-disposition:active names ` +
150
+ `${path.relative(ROOT, file)}: rollout-disposition:${disposition} names ` +
130
151
  `rollout-evidence-ref "${ref}" but no route with that path exists in src/. ` +
131
152
  `The graduation criterion can never be evaluated, so this rollout is parked ` +
132
153
  `indefinitely. Build the endpoint, correct the ref, or add an explicit ` +
@@ -157,6 +178,8 @@ if (errors.length) {
157
178
  process.exit(1);
158
179
  }
159
180
  console.log(
160
- `lint-rollout-evidence-resolvable: clean — ${seenActive.length} rollout-active endpoint spec(s), ` +
181
+ `lint-rollout-evidence-resolvable: clean — ${seenActive.length} guarded endpoint spec(s) ` +
182
+ `(${seenActive.filter((s) => s.disposition === 'active').length} active, ` +
183
+ `${seenActive.filter((s) => s.disposition === 'composed').length} composed), ` +
161
184
  `${seenActive.filter((s) => s.resolves).length} resolving, ${allowed.size} accepted-unresolved.`,
162
185
  );
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "./builtin-manifest.schema.json",
3
3
  "schemaVersion": 1,
4
- "generatedAt": "2026-07-27T21:51:05.954Z",
5
- "instarVersion": "1.3.1017",
4
+ "generatedAt": "2026-07-27T21:55:15.925Z",
5
+ "instarVersion": "1.3.1018",
6
6
  "entryCount": 202,
7
7
  "entries": {
8
8
  "hook:session-start": {
@@ -0,0 +1,66 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ A correction made earlier today to how design reviews decide they are finished now actually reaches
9
+ agents that are already running. It previously did not.
10
+
11
+ Tools like that review process exist both in what ships and as a copy on each running agent's disk.
12
+ The install step deliberately never overwrites an existing copy, in case an operator has customised
13
+ it, so an update reaches running agents only through a small dedicated delivery step. One already
14
+ existed for this file — but its "have I done this already?" check was keyed to an older change, so
15
+ once an agent had taken that one it quietly stopped delivering anything further to the same file.
16
+
17
+ The build guard that stops a switched-off feature from claiming a graduation condition it can
18
+ never check now covers a second kind of feature document it previously skipped.
19
+
20
+ Some features graduate alongside a bigger parent feature rather than on their own. The guard
21
+ treated those as out of scope. They are not: such a feature still states its own condition and
22
+ still names an address to read it from, so a missing address parks it for exactly the same
23
+ reason. Three feature documents sat outside the guard; all three are now covered.
24
+
25
+ ## What to Tell Your User
26
+
27
+ Nothing changes in how your agent behaves day to day. A fix that had been shipped but could not
28
+ reach already-running agents now reaches them.
29
+
30
+ Nothing changes in how your agent behaves. A safety check that runs when the project is built
31
+ now looks at a few more files than it used to.
32
+
33
+ ## Summary of New Capabilities
34
+
35
+ None. No endpoint, config key, or behaviour is added. This is a delivery step so an existing fix
36
+ arrives where it was always meant to go.
37
+
38
+ Agents that have customised the file keep their version untouched, agents that already have the
39
+ correction are unaffected, and a fresh install is unchanged.
40
+
41
+ None. No endpoint, config key, or behaviour is added. This widens the scope of an existing
42
+ build-time check and reports its two counts separately, so a future narrowing shows up as a
43
+ number dropping rather than as silence.
44
+
45
+ Widening it forces no new work on anyone. The guard already carries an escape hatch — a list
46
+ of accepted exceptions, each requiring a written reason, each deleted automatically once its
47
+ address starts working. A feature whose parent was genuinely abandoned needs a declaration,
48
+ not a fix.
49
+
50
+ ## Evidence
51
+
52
+ The gap was confirmed on a real running agent rather than reasoned about: its copy carried the older
53
+ change's marker and did not carry the correction, so the update could never have arrived.
54
+
55
+ The delivery step was proved to work by simulating exactly that agent — one that already took the
56
+ earlier change — and then deliberately breaking the fix in the way that would reintroduce the
57
+ problem, which made precisely that test fail and no other.
58
+
59
+ Nothing was broken when this was written: all eight covered addresses currently work, and the
60
+ accepted-exception list is empty. This closes a hole in the guard rather than repairing a
61
+ fault.
62
+
63
+ The guard was proved to actually bite by breaking one of the newly-covered documents on
64
+ purpose — the check refused, and named which kind of document had failed — then restoring it
65
+ byte-for-byte and confirming it passed again. The tests were proved the same way, by narrowing
66
+ the check back and watching exactly the two new tests fail.
@@ -0,0 +1,54 @@
1
+ # Side-effects review — rollout-evidence ratchet widened to `composed`
2
+
3
+ ## What this changes
4
+
5
+ `scripts/lint-rollout-evidence-resolvable.js` guarded `rollout-disposition: active` only.
6
+ It now guards `active` AND `composed`. Guarded endpoint specs go from 5 to 8.
7
+
8
+ ## Blast radius
9
+
10
+ The lint runs in the `npm run lint` chain, so it gates every commit and every CI run.
11
+ Widening it can, in principle, fail a build that previously passed.
12
+
13
+ **Measured, not assumed: it cannot do so today.** All eight guarded refs resolve; the lint
14
+ exits 0 with an EMPTY accepted-baseline. The three newly-covered specs are
15
+ `self-heal-gate.md` (`/feedback-factory/drain/status`), `context-wedge-detection-completeness.md`
16
+ (`/health`), and `slack-considered-acknowledgment-v1.md` (`/permissions/ambient-stats`).
17
+ Two were already transitively covered — one shares its ref with an active spec, one names a
18
+ path that trivially exists. Exactly one was genuinely unguarded.
19
+
20
+ ## The failure mode this could introduce, and why it does not
21
+
22
+ The obvious risk of widening a guard is forcing unrelated work on whoever trips it next: a
23
+ `composed` spec whose owner feature was abandoned may legitimately carry a stale ref, and
24
+ such a person should not be conscripted into building a route they do not want.
25
+
26
+ They are not. Assertion C's shrink-only baseline is the escape hatch, and it was designed
27
+ before this change: an accepted entry requires a written reason and is auto-deleted the
28
+ moment its ref starts resolving. So the widened guard forces a DECLARATION, never a fix.
29
+ Entry needs evidence; exit happens by itself.
30
+
31
+ ## What is NOT weakened
32
+
33
+ Assertions A (every guarded ref resolves unless accepted), B (baseline reasons must be
34
+ substantive), and C (baseline shrinks only) are unchanged. No threshold moved. The
35
+ refusal message now names which disposition fired, which is strictly more information.
36
+
37
+ ## Verification
38
+
39
+ - Live run: `clean — 8 guarded endpoint spec(s) (5 active, 3 composed), 8 resolving, 0 accepted-unresolved`, exit 0.
40
+ - Falsified against the real subject: breaking the COMPOSED spec's ref → exit 1 with a
41
+ refusal naming `rollout-disposition:composed`. Spec restored byte-identical; exit 0 again.
42
+ - Falsified against the tests: narrowing the filter back to active-only → `2 failed | 7 passed`.
43
+ Restored → `9 passed`.
44
+ - Two pre-existing tests asserted the OLD summary wording and correctly broke. Their
45
+ PROPERTY — that the guard must report its denominator, since "clean" alone cannot be told
46
+ from "scanned nothing" — is preserved, with the pattern updated rather than the assertion
47
+ dropped.
48
+
49
+ ## Reviewer's note
50
+
51
+ This is a correction to my own work from earlier the same day. The lint's header claimed a
52
+ sweep of "all 5 rollout-active specs" — accurate for its scope, and the scope was narrower
53
+ than the class it names. Recorded in the source comment rather than quietly widened, because
54
+ a guard that silently grew is indistinguishable from one that was always right.
@@ -1,37 +0,0 @@
1
- # Upgrade Guide — vNEXT
2
-
3
- <!-- assembled-by: assemble-next-md -->
4
- <!-- bump: patch -->
5
-
6
- ## What Changed
7
-
8
- A correction made earlier today to how design reviews decide they are finished now actually reaches
9
- agents that are already running. It previously did not.
10
-
11
- Tools like that review process exist both in what ships and as a copy on each running agent's disk.
12
- The install step deliberately never overwrites an existing copy, in case an operator has customised
13
- it, so an update reaches running agents only through a small dedicated delivery step. One already
14
- existed for this file — but its "have I done this already?" check was keyed to an older change, so
15
- once an agent had taken that one it quietly stopped delivering anything further to the same file.
16
-
17
- ## What to Tell Your User
18
-
19
- Nothing changes in how your agent behaves day to day. A fix that had been shipped but could not
20
- reach already-running agents now reaches them.
21
-
22
- ## Summary of New Capabilities
23
-
24
- None. No endpoint, config key, or behaviour is added. This is a delivery step so an existing fix
25
- arrives where it was always meant to go.
26
-
27
- Agents that have customised the file keep their version untouched, agents that already have the
28
- correction are unaffected, and a fresh install is unchanged.
29
-
30
- ## Evidence
31
-
32
- The gap was confirmed on a real running agent rather than reasoned about: its copy carried the older
33
- change's marker and did not carry the correction, so the update could never have arrived.
34
-
35
- The delivery step was proved to work by simulating exactly that agent — one that already took the
36
- earlier change — and then deliberately breaking the fix in the way that would reintroduce the
37
- problem, which made precisely that test fail and no other.