instar 1.3.1185 → 1.3.1186

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": "81b53363a440e832672618965540b3e507ae0d93adcc67ec2b93daf7933b3ab4",
5
- "packageVersion": "1.3.1185",
5
+ "packageVersion": "1.3.1186",
6
6
  "guards": [
7
7
  {
8
8
  "ref": "docs/audits/phase-b/f10-triage.md",
@@ -1,5 +1,5 @@
1
1
  {
2
- "sha256": "3eb1bd07851f19c2b7daa4f5bcf5b38a58e611750b8edfbe5f4836b7ee919418",
2
+ "sha256": "ca8ad50250d4cc3b15e4fcde9bfd6777098006bed213db40dd4a183d731de145",
3
3
  "registrySha256": "81b53363a440e832672618965540b3e507ae0d93adcc67ec2b93daf7933b3ab4",
4
- "packageVersion": "1.3.1185"
4
+ "packageVersion": "1.3.1186"
5
5
  }
@@ -2,5 +2,5 @@
2
2
  "sha256": "81b53363a440e832672618965540b3e507ae0d93adcc67ec2b93daf7933b3ab4",
3
3
  "articleCount": 88,
4
4
  "generatedFrom": "docs/STANDARDS-REGISTRY.md",
5
- "packageVersion": "1.3.1185"
5
+ "packageVersion": "1.3.1186"
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.3.1185",
3
+ "version": "1.3.1186",
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",
@@ -72,7 +72,37 @@ export const TAXONOMY_KEYS = new Set([
72
72
  'operator-ratified-exception',
73
73
  ]);
74
74
 
75
- const POSTURE_SECTION_RE = /^#{1,6}\s+Multi-machine posture\b.*$/im;
75
+ // ── Finding the posture section (widened 2026-08-21) ──────────────────────
76
+ // This gate located its section by matching the heading text EXACTLY. Real spec
77
+ // headings carry ordinals and qualifiers, and every such section was INVISIBLE:
78
+ // the spec then read as "no posture section", A1/A3 never fired, and it passed
79
+ // CLEAN without ever being checked. Measured on this corpus, an exact match saw
80
+ // 91 of 149 posture-carrying specs and silently skipped the rest — including the
81
+ // replicated-store foundation, the mesh self-heal spec, the secure-pairing spec
82
+ // and the standards-registry spec itself. Nobody had to make a mistake; you just
83
+ // had to number your heading.
84
+ //
85
+ // The shapes actually in the corpus, all of which must be seen:
86
+ // `## Multi-machine posture` (bare)
87
+ // `## 8. Multi-machine posture` / `## 8.2 …` (numeric ordinal)
88
+ // `## §4. Multi-machine posture (Phase A)` (section-mark ordinal)
89
+ // `#### D. Multi-machine posture — released-no-placement` (letter ordinal)
90
+ // `## 4. State and multi-machine posture` (phrase not leading)
91
+ // `## Cross-Machine Coherence (multi-machine posture)` (phrase parenthesised)
92
+ //
93
+ // So the matcher is CONTAINMENT, not a prefix. Over-matching a heading errs
94
+ // toward CHECKING a section that may not be the posture one; under-matching
95
+ // silently skips the check entirely. For a gate whose whole purpose is to be
96
+ // unskippable, and which is report-first (non-blocking without --strict), the
97
+ // containment direction is the correct asymmetry.
98
+ const POSTURE_HEADING_RE = /^#{1,6}[ \t]+.*multi-machine posture.*$/gim;
99
+
100
+ // Among containing headings, the CANONICAL one — the phrase leading the title
101
+ // after an optional ordinal — is preferred, so a spec carrying both a real
102
+ // posture section and an incidental prose heading picks the real one
103
+ // deterministically rather than by document order.
104
+ const POSTURE_CANONICAL_RE =
105
+ /^#{1,6}[ \t]+(?:(?:§[ \t]*)?(?:[0-9]+(?:\.[0-9]+)*|[A-Z])\.?[ \t]+)?multi-machine posture\b/i;
76
106
 
77
107
  // A standalone marker line: start-of-line (optional bullet / backtick), the
78
108
  // label, a colon, then `key rest`. Anchored so a mid-sentence backticked prose
@@ -81,6 +111,22 @@ const POSTURE_SECTION_RE = /^#{1,6}\s+Multi-machine posture\b.*$/im;
81
111
  const MARKER_LINE_RE =
82
112
  /^[ \t]*(?:[-*+][ \t]+)?`?machine-local-justification`?[ \t]*:[ \t]*`?([^\s`]+)`?[ \t]*(.*?)`?[ \t]*$/gim;
83
113
 
114
+ // ── Prose QUOTATION of a marker, not a declaration (2026-08-21) ────────────
115
+ // The anchoring claim above holds only while the prose mention is mid-line. A
116
+ // correction-heavy spec quotes markers constantly ("an earlier draft declared it
117
+ // `machine-local-justification: hardware-bound-resource`. A JSONL audit file is
118
+ // not…"), and ordinary paragraph wrapping puts that quotation at line-start,
119
+ // where it reads as a live declaration sitting outside the posture section — a
120
+ // false A3. Found by running the widened gate on a real 196KB spec; no fixture
121
+ // had ever contained a spec that TALKS ABOUT markers.
122
+ //
123
+ // The discriminator is the closing backtick: a real declaration is the line's
124
+ // content (bare label, optional trailing ref — see the corpus fixtures), whereas
125
+ // a quotation closes its backtick span and then CONTINUES with sentence prose.
126
+ // A fully-backticked marker alone on its line is still a declaration, because
127
+ // nothing follows the span.
128
+ const MARKER_QUOTATION_RE = /`[^`]*machine-local-justification[^`]*`[ \t]*\S/i;
129
+
84
130
  // A machine-verifiable, existence-checkable ref for operator-ratified-exception
85
131
  // (§155-162): a commit SHA (7-40 hex), a URL, or a dotted registry key.
86
132
  const REF_SHA_RE = /\b[0-9a-f]{7,40}\b/i;
@@ -94,11 +140,18 @@ const REF_REGISTRY_KEY_RE = /\b[a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z0-9_]+){1,}\b/;
94
140
  * (or EOF).
95
141
  */
96
142
  export function findPostureSection(text) {
97
- const m = POSTURE_SECTION_RE.exec(text);
143
+ POSTURE_HEADING_RE.lastIndex = 0;
144
+ const matches = [];
145
+ let hit;
146
+ while ((hit = POSTURE_HEADING_RE.exec(text)) !== null) {
147
+ matches.push({ text: hit[0], index: hit.index });
148
+ }
149
+ if (matches.length === 0) return null;
150
+ const m = matches.find((c) => POSTURE_CANONICAL_RE.test(c.text)) ?? matches[0];
98
151
  if (!m) return null;
99
- const headingLevel = (m[0].match(/^#+/) || ['#'])[0].length;
152
+ const headingLevel = (m.text.match(/^#+/) || ['#'])[0].length;
100
153
  const start = m.index;
101
- const afterHeading = start + m[0].length;
154
+ const afterHeading = start + m.text.length;
102
155
  // Find the next heading at <= headingLevel after the section starts.
103
156
  const rest = text.slice(afterHeading);
104
157
  const nextHeadingRe = new RegExp(`^#{1,${headingLevel}}\\s+\\S`, 'im');
@@ -117,6 +170,8 @@ export function parseMarkers(text) {
117
170
  MARKER_LINE_RE.lastIndex = 0;
118
171
  let m;
119
172
  while ((m = MARKER_LINE_RE.exec(text)) !== null) {
173
+ // A prose quotation of a marker is not a declaration of one.
174
+ if (MARKER_QUOTATION_RE.test(m[0])) continue;
120
175
  const key = m[1];
121
176
  const rest = (m[2] || '').trim();
122
177
  // Skip template placeholders like `<taxonomy-key>` / `<key>` — documentation,
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "./builtin-manifest.schema.json",
3
3
  "schemaVersion": 1,
4
- "generatedAt": "2026-08-21T16:44:51.648Z",
5
- "instarVersion": "1.3.1185",
4
+ "generatedAt": "2026-08-22T18:21:13.815Z",
5
+ "instarVersion": "1.3.1186",
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": "81b53363a440e832672618965540b3e507ae0d93adcc67ec2b93daf7933b3ab4",
5
- "packageVersion": "1.3.1185",
5
+ "packageVersion": "1.3.1186",
6
6
  "guards": [
7
7
  {
8
8
  "ref": "docs/audits/phase-b/f10-triage.md",
@@ -1,5 +1,5 @@
1
1
  {
2
- "sha256": "3eb1bd07851f19c2b7daa4f5bcf5b38a58e611750b8edfbe5f4836b7ee919418",
2
+ "sha256": "ca8ad50250d4cc3b15e4fcde9bfd6777098006bed213db40dd4a183d731de145",
3
3
  "registrySha256": "81b53363a440e832672618965540b3e507ae0d93adcc67ec2b93daf7933b3ab4",
4
- "packageVersion": "1.3.1185"
4
+ "packageVersion": "1.3.1186"
5
5
  }
@@ -2,5 +2,5 @@
2
2
  "sha256": "81b53363a440e832672618965540b3e507ae0d93adcc67ec2b93daf7933b3ab4",
3
3
  "articleCount": 88,
4
4
  "generatedFrom": "docs/STANDARDS-REGISTRY.md",
5
- "packageVersion": "1.3.1185"
5
+ "packageVersion": "1.3.1186"
6
6
  }
@@ -0,0 +1,36 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ `scripts/lint-machine-local-justification.js` — the deterministic marker floor for the multi-machine posture standard — located its section with an EXACT heading match, so any spec whose heading carried an ordinal or qualifier had no locatable section at all. The spec read as "no posture section", rules A1/A3 never fired, and it passed CLEAN without ever being checked.
9
+
10
+ Measured on this corpus: 91 of 129 posture-carrying specs were seen. The 38 skipped include the replicated-store foundation, the mesh self-heal spec, the secure agent-pairing spec, the silent-loss conservation spec, the self-heal gate and the standards-registry spec itself. Nobody had to make a mistake for this to happen — you only had to number your heading.
11
+
12
+ The matcher is now CONTAINMENT with a canonical-heading preference, covering every shape present in the corpus: bare, numeric ordinal (`8.`, `8.2`), section-mark ordinal (`§4.`), letter ordinal (`D.`), the phrase mid-title, and the phrase parenthesised. A first pass allowing only a numeric ordinal was not enough — a re-sweep found the other four shapes still invisible.
13
+
14
+ A second defect is fixed alongside, found by pointing the repaired gate at a real 196KB spec: a correction-heavy spec QUOTES markers, and ordinary paragraph wrapping puts the quotation at line-start where it read as a live out-of-section declaration (a false A3). The discriminator is the closing backtick — a declaration is the line's content; a quotation closes its span and continues into prose. No fixture had ever contained a spec that talks *about* markers.
15
+
16
+ This is a DETECTOR change and stays one. `skills/spec-converge/SKILL.md` names the split: the marker is "the cheap deterministic signal", the integration reviewer "holds the semantic authority". No blocking power is added, and `--strict` is invoked by no workflow, package script or shell script — so this removes a hole the gate would otherwise have graduated WITH, rather than fixing an active incident.
17
+
18
+ ## What to Tell Your User
19
+
20
+ None — internal change (no user-facing surface).
21
+
22
+ ## Summary of New Capabilities
23
+
24
+ None — internal change (no user-facing surface).
25
+
26
+ ## Evidence
27
+
28
+ - Corpus effect: 91 → 129 specs actually checked; zero specs carrying a posture heading remain invisible. The remaining 20 mention the phrase only in prose with no heading, which is genuinely outside this gate's scope.
29
+ - Over-match risk measured rather than assumed: of 37 newly-visible specs, 2 matched on a non-canonical heading (`## Cross-Machine Coherence (multi-machine posture)`, `## 4. State and multi-machine posture`) and both are genuine posture sections. Zero false matches corpus-wide.
30
+ - The blind spot was verified by deleting the posture declaration from a numbered spec outright and running the gate: it passed clean.
31
+ - Tests: 20 passing, covering every heading shape found in the corpus, the prose-quotation case, and a guard proving the quotation fix did not open a hole for a genuine out-of-section declaration. The pre-existing tests all used the plain unnumbered heading, which is exactly why none of them caught this.
32
+ - Full unit suite green on the branch this was split from: 42,597 passing, 0 failures.
33
+
34
+ ## Follow-up
35
+
36
+ Graduation of this gate to `--strict` now has to triage 90 findings across 85 specs, where the old matcher reported 71. That decision — for this lint and three siblings whose enforcing mode is invoked nowhere — is tracked as ACT-102 and belongs to the operator. Three constitutional standards currently cite one of those four lints as their guard. <!-- tracked: ACT-102 -->
@@ -0,0 +1,79 @@
1
+ # Side-Effects Review — the posture gate could not see a numbered heading
2
+
3
+ **Version / slug:** `posture-gate-heading-blindspot`
4
+ **Date:** `2026-08-21`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `required (the word "gate" applies) — self-reviewed adversarially below, see §Second-pass`
7
+
8
+ ## Summary of the change
9
+
10
+ `scripts/lint-machine-local-justification.js` locates the spec section it grades with a heading match. That match was EXACT (`/^#{1,6}\s+Multi-machine posture\b/`), so any spec whose heading carried an ordinal or qualifier had no locatable section at all — the spec read as "no posture section", rules A1/A3 never fired, and it passed CLEAN without ever being checked. Measured on this corpus: 91 of 129 posture-carrying specs were seen, and the 38 skipped include the replicated-store foundation, the mesh self-heal spec, the secure agent-pairing spec, the silent-loss conservation spec, the self-heal gate and the standards-registry spec itself.
11
+
12
+ The matcher becomes CONTAINMENT with a canonical-heading preference. A second defect, found by pointing the fixed gate at a real 196KB spec, is fixed alongside: a prose QUOTATION of a marker, wrapped so it begins a line, was read as a live out-of-section declaration (a false A3).
13
+
14
+ Files touched: `scripts/lint-machine-local-justification.js`, `tests/unit/lint-machine-local-justification.test.ts`, three new fixtures under `tests/fixtures/spec-lint/`.
15
+
16
+ ## Decision-point inventory
17
+
18
+ - `lint-machine-local-justification` (Standard A marker floor) — **modify** — widens which specs the detector can see, and stops one class of false positive. No change to what it does once it sees a section.
19
+
20
+ This is a **detector**, not an authority. `skills/spec-converge/SKILL.md` states the split explicitly: "the `machine-local-justification` marker is the cheap deterministic signal; THIS reviewer holds the semantic authority." The change stays entirely on the detector side.
21
+
22
+ ## 1. Over-block — what legitimate inputs does this reject that it shouldn't?
23
+
24
+ The containment matcher can select a heading that merely *discusses* posture (e.g. `## Why the multi-machine posture check missed headings`) when a spec has no real posture section. That would grade a prose section as the posture section, and could emit a spurious A1 if that prose happens to contain the token `machine-local`.
25
+
26
+ **Measured rather than assumed:** of the 37 newly-visible specs, 2 matched on a non-canonical heading — `## Cross-Machine Coherence (multi-machine posture)` and `## 4. State and multi-machine posture` — and both are genuine posture sections. Zero false matches on discussion headings across the whole corpus.
27
+
28
+ Mitigations: (a) the canonical-heading preference means a spec carrying both a real section and an incidental heading resolves to the real one deterministically, not by document order; (b) the gate is report-first — a finding is exit 0 unless `--strict`, which is invoked nowhere.
29
+
30
+ The prose-quotation fix strictly REDUCES over-blocking: it removed a false A3 and, corpus-wide, dropped `A2-marker-outside-posture-section` from 1 to 0.
31
+
32
+ ## 2. Under-block — what failure modes does this still miss?
33
+
34
+ - A spec that discusses posture only in prose with **no heading at all** is still invisible. 20 specs are in that state. This is deliberate and unchanged: the gate's own header says it "does NOT flag a spec that simply omits a posture section — §168's 'absence defaults to unified-required' is a semantic call the reviewer owns."
35
+ - A marker that is well-formed but **substantively wrong** is still passed. Also deliberate — correctness is the reviewer's authority, and the gate's header says so.
36
+ - A fully-backticked marker alone on its own line is still read as a declaration. That is intended (nothing follows the span), but it means a spec could quote a marker in a way that still trips A3 if the quotation is the entire line. Judged acceptable: that shape is indistinguishable from a declaration by construction, and erring toward *checking* is the correct direction here.
37
+
38
+ ## 3. Level-of-abstraction fit
39
+
40
+ Correct layer. The alternative — teaching the spec-converge reviewer to find the section — moves deterministic text location into an LLM, which is the wrong direction. The section-finding belongs in the cheap deterministic layer; the semantic judgement stays with the reviewer.
41
+
42
+ Note that `scripts/generate-spec-contract.mjs` already tolerated a numeric ordinal in the same heading (`(?:\d+\.\s+)?`). Two tools reading the same heading disagreed about its shape; this closes that divergence in the stricter of the two.
43
+
44
+ ## 4. Signal vs authority compliance
45
+
46
+ **Compliant, and the change does not move the boundary.** The lint is a detector producing findings; the spec-converge integration reviewer is the authority. No blocking power is added. `--strict` exists but is invoked by no workflow, package script or shell script — deliberately, per the SKILL's hard-sequencing note. The change makes the signal *more complete*, which is precisely what a detector improvement should do.
47
+
48
+ ## 5. Interactions
49
+
50
+ - **Shadowing:** none. The reviewer's semantic posture check runs independently and reads whatever heading a human wrote; it was never affected by this blind spot. That is why declarations were still being reviewed — the human half worked, the automatic half did not.
51
+ - **Double-fire:** none. One finding per marker per rule; the quotation filter runs inside the single marker-parse loop.
52
+ - **Races / adjacent cleanup:** none. The script is a pure read over files passed on argv.
53
+ - **Newly surfaced findings:** the corpus goes from 71 to 90 findings, 20 of them newly visible. Because the gate is report-only and unwired, this changes no build outcome today. It WILL matter at graduation — see §8.
54
+
55
+ ## 6. External surfaces
56
+
57
+ No runtime surface. Nothing in `src/` changes; no route, hook, job, template or config is touched. Nothing is visible to other agents, other users or other systems. No timing or conversation-state dependence.
58
+
59
+ ## 7. Multi-machine posture (Cross-Machine Coherence)
60
+
61
+ **Machine-local BY DESIGN — and it carries no durable state at all.** This is a stateless CLI lint over files in the repo checkout, invoked per-run with paths on argv. It writes nothing, persists nothing, and generates no URLs or user-facing notices. There is no state to replicate, nothing to strand on topic transfer, and no read to merge. Every machine running it against the same checkout gets the same answer, because the answer is a pure function of the file bytes.
62
+
63
+ No `machine-local-justification` marker is declared, because this is not a machine-local *surface* — it is a stateless function with no locality at all. (Declaring `hardware-bound-resource` here would be the exact substantively-wrong-key mistake this very lint exists to catch.)
64
+
65
+ ## 8. Rollback cost
66
+
67
+ **Near-zero.** Revert the commit; the matcher returns to the exact-match form and the gate returns to seeing 91 specs. No migration, no data, no agent state, no release required — the script is not shipped to agents and is not invoked by CI.
68
+
69
+ The one thing to know before graduating this gate to `--strict`: it now reports 90 findings across 85 specs, where the pre-change matcher reported 71. Turning `--strict` on without triaging that backlog would fail the build. That decision is tracked as **ACT-102** (the graduation call for this lint and three siblings), and it is the operator's, not mine. Three constitutional standards currently cite one of those four lints as their guard.
70
+
71
+ ## Second-pass
72
+
73
+ The high-risk list includes "anything with the word … 'gate' … in it", so a second pass is required. The specific violation a second pass exists to catch is *brittle logic holding blocking authority*. Audited against that:
74
+
75
+ - The logic IS brittle (a regex over headings). That is acceptable **only** because it holds no authority — verified two ways: the script's default exit is 0 on findings, and `--strict` appears in no workflow, package script or shell script in the repo (independently documented in `docs/audits/phase-b/for-operator-enforcing-mode-never-invoked.md`).
76
+ - The change widens recall and narrows false positives. Both directions move the detector toward reporting the true state, which is the correct direction for a signal.
77
+ - The risk that a *future* graduation gives this brittle logic blocking authority is real, and is the reason §8 names the 90-finding backlog explicitly rather than leaving graduation to look free.
78
+
79
+ **Concur with the review**, with the §8 condition recorded: graduation is gated on triaging the backlog this change makes visible, and that is ACT-102's decision to make.