instar 1.3.483 → 1.3.484

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.
@@ -22,10 +22,27 @@
22
22
  * from `degraded` (framework present, this call failed) and
23
23
  * `skipped-abbreviated` (author chose the fast path).
24
24
  *
25
- * codex is the FIRST supported framework; the registry
26
- * (`SUPPORTED_REVIEWER_FRAMEWORKS`) is the single seam for gemini-cli and
27
- * others to plug in later (Out of Scope here). Adding a framework is one
28
- * registry entry + one `id`-union extension no skill change.
25
+ * codex is the FIRST supported framework; gemini-cli is the SECOND (Piece 3 of
26
+ * docs/specs/AUTONOMY-PRINCIPLES-ENFORCEMENT-SPEC.md cross-model convergence
27
+ * hardening). The registry (`SUPPORTED_REVIEWER_FRAMEWORKS`) remains the single
28
+ * seam for further frameworks. Adding a framework is one registry entry + one
29
+ * `id`-union extension — no skill change.
30
+ *
31
+ * Piece 3 additions (all signal-only, never-throw, same invariants as above):
32
+ * - `detectGeminiReviewer` + the gemini registry entry (family diversity).
33
+ * - `detectAllCrossModelReviewers` — collect EVERY available framework, not
34
+ * just the first match, so the skill runs one external pass per family.
35
+ * - `isConcreteReviewerModel` — the fail-loud model canary: a tier word
36
+ * ('capable', 'fast', …) falling through model resolution degrades the
37
+ * review LOUDLY instead of silently selecting a dead reviewer.
38
+ * - `hashSpecReviewableBody` — delta-gating: externals re-run only when the
39
+ * spec's reviewable body (frontmatter stripped) actually changed.
40
+ * - `recordFrameworkActivationObservation` / `wasNonClaudeFrameworkActiveWithin`
41
+ * — the durable standing-framework baseline: activation is judged against
42
+ * a lookback window of recorded observations, not a just-in-time reading,
43
+ * so a just-before-converge framework deactivation cannot exempt a spec.
44
+ * - `TRUSTED_REVIEWER_FRAMEWORKS` — the provider allowlist (no spec egress
45
+ * to untrusted/custom endpoints).
29
46
  */
30
47
  import { type IntelligenceFramework } from './intelligenceProviderFactory.js';
31
48
  /**
@@ -70,7 +87,7 @@ export declare function orderContextDeterministically(context: readonly Referenc
70
87
  * Rule-1 / auth-probe vocabulary so a report can render a specific
71
88
  * remediation.
72
89
  */
73
- export type CrossModelUnavailableReason = 'codex-not-installed' | 'codex-not-authed' | 'codex-auth-apikey-forbidden' | 'no-supported-framework';
90
+ export type CrossModelUnavailableReason = 'codex-not-installed' | 'codex-not-authed' | 'codex-auth-apikey-forbidden' | 'gemini-not-installed' | 'gemini-not-authed' | 'no-supported-framework';
74
91
  export interface CrossModelDetectionResult {
75
92
  available: boolean;
76
93
  /** Present when available; the framework id that will run the review. */
@@ -99,6 +116,16 @@ export interface CrossModelDetectInputs {
99
116
  env?: NodeJS.ProcessEnv;
100
117
  /** Clock injection for the Rule-1 killswitch sunset check. */
101
118
  now?: Date;
119
+ /**
120
+ * Path to the gemini binary if detected, else null. Defaults to
121
+ * `detectGeminiPath()` (PATH + known-location resolution).
122
+ */
123
+ geminiPathDetected?: string | null;
124
+ /**
125
+ * Path to the gemini CLI's cached OAuth credentials. Defaults to
126
+ * `${GEMINI_HOME || ~/.gemini}/oauth_creds.json`.
127
+ */
128
+ geminiOauthCredsPath?: string;
102
129
  }
103
130
  /**
104
131
  * Detect a codex reviewer. Returns `{ available: true, framework, model }`
@@ -109,6 +136,17 @@ export interface CrossModelDetectInputs {
109
136
  * real host. It NEVER throws.
110
137
  */
111
138
  export declare function detectCodexReviewer(inputs?: CrossModelDetectInputs): CrossModelDetectionResult;
139
+ /**
140
+ * Detect a gemini reviewer (Piece 3 — the second family in the registry).
141
+ * Returns `{ available: true, framework, model }` iff BOTH of: gemini binary
142
+ * detected, cached OAuth credentials present (`access_token` or
143
+ * `refresh_token`). Any miss → a specific reason.
144
+ *
145
+ * Pure-ish: all external inputs are injectable (mirrors
146
+ * `detectCodexReviewer`). With no inputs it probes the real host. It NEVER
147
+ * throws.
148
+ */
149
+ export declare function detectGeminiReviewer(inputs?: CrossModelDetectInputs): CrossModelDetectionResult;
112
150
  export interface ReviewerResult {
113
151
  /** Outcome class for the cross-model pass. */
114
152
  status: 'ok' | 'degraded' | 'unavailable';
@@ -162,22 +200,66 @@ export interface ReviewerInvokeArgs {
162
200
  timeoutMs?: number;
163
201
  }): Promise<string>;
164
202
  };
203
+ /**
204
+ * Optional detection override — `runCrossModelReview` passes the detection
205
+ * it already computed (so review never re-probes the host), and tests inject
206
+ * synthetic detections (e.g. a tier-word model to exercise the canary).
207
+ * Absent → the entry runs its own real-host detect, as before (back-compat).
208
+ */
209
+ detectionOverride?: CrossModelDetectionResult;
165
210
  }
211
+ /**
212
+ * Fail-loud model canary (Piece 3). A cross-model review must run on a
213
+ * CONCRETE model id — never a bare tier word that fell through a
214
+ * tier→model resolution map (the `resolveModelForFramework` fall-through
215
+ * failure class: the literal string 'capable' is not a model, and silently
216
+ * passing it selects a dead reviewer). Returns false for undefined/empty
217
+ * strings and for bare tier words (case-insensitive). Both registry entries
218
+ * check this BEFORE invoking the provider and degrade LOUDLY
219
+ * (`model-resolution-canary`) on a failure.
220
+ */
221
+ export declare function isConcreteReviewerModel(model: string | undefined): boolean;
166
222
  /**
167
223
  * The supported-reviewer registry. codex first — the order IS the preference
168
- * order. gemini-cli and others land here as later steps (Out of Scope).
224
+ * order. gemini second (Piece 3). Further frameworks land here as later
225
+ * registry entries. NOTE: the registry only ever carries first-party OAuth
226
+ * CLI adapters — see `TRUSTED_REVIEWER_FRAMEWORKS` below.
169
227
  */
170
228
  export declare const SUPPORTED_REVIEWER_FRAMEWORKS: SupportedReviewerFramework[];
229
+ /**
230
+ * Trusted-provider allowlist (Piece 3 — no spec egress to untrusted
231
+ * endpoints). The registry only ever carries FIRST-PARTY OAuth CLI adapters:
232
+ * the full spec text is handed to the reviewer model, so it must NEVER be
233
+ * sent to a custom/base-URL endpoint an operator (or attacker) pointed a
234
+ * framework at. The pi-cli multi-provider case is deliberately EXCLUDED from
235
+ * cross-model review for exactly this reason — its provider may be a custom
236
+ * endpoint. A framework id outside this list is refused by the script
237
+ * wrapper (`--family`) with reason `untrusted-framework`.
238
+ */
239
+ export declare const TRUSTED_REVIEWER_FRAMEWORKS: readonly string[];
240
+ /** Is `id` on the trusted first-party reviewer allowlist? */
241
+ export declare function isTrustedReviewerFramework(id: string): boolean;
171
242
  /**
172
243
  * Walk the registry in preference order and return the FIRST available
173
- * framework's detection result. If none is available, returns the codex
174
- * reason when there's exactly one entry (so the report can be specific), else
175
- * the generic `no-supported-framework`.
244
+ * framework's detection result (back-compat single-reviewer entry point
245
+ * the multi-family collection is `detectAllCrossModelReviewers`). If none is
246
+ * available, returns the preference-leader's specific reason (codex today) so
247
+ * the report can render a concrete remediation, rather than the generic
248
+ * `no-supported-framework`.
176
249
  *
177
250
  * SIGNAL-ONLY: never throws, never blocks. A `false` simply routes the skill
178
251
  * to the internal-only fallback (spec §4).
179
252
  */
180
253
  export declare function detectCrossModelReviewer(inputs?: CrossModelDetectInputs): CrossModelDetectionResult;
254
+ /**
255
+ * Collect EVERY available reviewer framework, in registry preference order
256
+ * (Piece 3 — family diversity: GPT and Gemini catch different failure
257
+ * classes, so the externals pass runs one review PER available family, not
258
+ * first-match-only). Returns an empty array when none is available.
259
+ *
260
+ * SIGNAL-ONLY: never throws, never blocks.
261
+ */
262
+ export declare function detectAllCrossModelReviewers(inputs?: CrossModelDetectInputs): CrossModelDetectionResult[];
181
263
  /**
182
264
  * Map a provider rejection into a coarse `degraded` reason. The provider
183
265
  * surfaces timeouts, non-zero exits, and (via the circuit breaker) rate
@@ -306,5 +388,53 @@ export declare function runCrossModelReview(args: {
306
388
  detectInputs?: CrossModelDetectInputs;
307
389
  providerOverride?: ReviewerInvokeArgs['providerOverride'];
308
390
  }): Promise<ReviewerResult>;
391
+ /**
392
+ * Hash the spec's REVIEWABLE body (Piece 3 delta-gating): sha256 hex of the
393
+ * spec text with the leading YAML frontmatter block stripped and line endings
394
+ * normalized (\r\n → \n). Frontmatter is excluded so tag-writes
395
+ * (`review-convergence`, `approved: true`, cross-model flags) and other
396
+ * metadata edits do NOT change the hash — externals re-run only when the
397
+ * content a reviewer would actually read changed. The skill runs externals on
398
+ * round 1 and on any round where this hash differs from the last external
399
+ * pass's hash; an unchanged round records a skip-with-logged-note.
400
+ */
401
+ export declare function hashSpecReviewableBody(specText: string): string;
402
+ /**
403
+ * One recorded observation of which reviewer frameworks were available at a
404
+ * moment in time. Appended (JSONL) to
405
+ * `<stateDir>/state/framework-activation-history.jsonl` by the script
406
+ * wrapper's `--detect-only --state-dir` path on every detection.
407
+ */
408
+ export interface FrameworkActivationObservation {
409
+ /** ISO timestamp; defaults to now. */
410
+ ts?: string;
411
+ /** framework id → was it available/active at observation time. */
412
+ frameworks: Record<string, boolean>;
413
+ }
414
+ /**
415
+ * Append ONE observation line to the durable framework-activation history
416
+ * (Piece 3 — the standing-framework baseline). The externals-mandatory check
417
+ * is judged against this recorded history over a lookback window, NOT a
418
+ * just-in-time reading — so deactivating a framework right before converging
419
+ * cannot present the agent as "genuinely single-framework."
420
+ *
421
+ * mkdir -p's the state dir; caps the file at the most recent
422
+ * `ACTIVATION_HISTORY_MAX_LINES` lines on every write. Filesystem errors
423
+ * propagate — a silently-unrecorded baseline would quietly weaken the
424
+ * mandatory check (fail-loud).
425
+ */
426
+ export declare function recordFrameworkActivationObservation(stateDir: string, observation: FrameworkActivationObservation): void;
427
+ /**
428
+ * Was ANY non-Claude reviewer framework active at ANY point within the
429
+ * lookback window, per the durable activation history? This is the
430
+ * externals-mandatory check (Piece 3): `true` means the cross-model pass is
431
+ * NON-SKIPPABLE for the spec — including when a framework was deactivated
432
+ * inside the window (a just-before-converge deactivation does not exempt the
433
+ * spec). The advisory "externals unavailable" floor is legitimate only when
434
+ * this returns `false` across the whole lookback.
435
+ *
436
+ * NEVER throws: a missing file → false; corrupt lines are skipped.
437
+ */
438
+ export declare function wasNonClaudeFrameworkActiveWithin(stateDir: string, lookbackDays: number, now?: Date): boolean;
309
439
  export {};
310
440
  //# sourceMappingURL=crossModelReviewer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"crossModelReviewer.d.ts","sourceRoot":"","sources":["../../src/core/crossModelReviewer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"crossModelReviewer.d.ts","sourceRoot":"","sources":["../../src/core/crossModelReviewer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAUH,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,kCAAkC,CAAC;AAI1C;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,SAAU,CAAC;AAEzC;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,QAAY,CAAC;AAE9C;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,2BAA2B,EAAE,SAAS,MAAM,EAK/C,CAAC;AAgBX;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,SAAS,oBAAoB,EAAE,GACvC,oBAAoB,EAAE,CAKxB;AAOD;;;;GAIG;AACH,MAAM,MAAM,2BAA2B,GACnC,qBAAqB,GACrB,kBAAkB,GAClB,6BAA6B,GAC7B,sBAAsB,GACtB,mBAAmB,GACnB,wBAAwB,CAAC;AAE7B,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,OAAO,CAAC;IACnB,yEAAyE;IACzE,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,MAAM,CAAC,EAAE,2BAA2B,CAAC;CACtC;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kFAAkF;IAClF,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,8DAA8D;IAC9D,GAAG,CAAC,EAAE,IAAI,CAAC;IACX;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAwBD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,GAAE,sBAA2B,GAClC,yBAAyB,CA8B3B;AAoCD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,GAAE,sBAA2B,GAClC,yBAAyB,CAqB3B;AAID,MAAM,WAAW,cAAc;IAC7B,8CAA8C;IAC9C,MAAM,EAAE,IAAI,GAAG,UAAU,GAAG,aAAa,CAAC;IAC1C,kDAAkD;IAClD,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gDAAgD;IAChD,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3B,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,cAAc,GAAG,gBAAgB,GAAG,SAAS,CAAC;AAEpF,MAAM,WAAW,aAAa;IAC5B,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,aAAa,CAAC;IACvB,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,6EAA6E;IAC7E,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,UAAU,0BAA0B;IAClC,gEAAgE;IAChE,EAAE,EAAE,qBAAqB,CAAC;IAC1B,4EAA4E;IAC5E,MAAM,CAAC,MAAM,CAAC,EAAE,sBAAsB,GAAG,yBAAyB,CAAC;IACnE;;;;OAIG;IACH,MAAM,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAC3D;AAED,MAAM,WAAW,kBAAkB;IACjC,iFAAiF;IACjF,UAAU,EAAE,MAAM,CAAC;IACnB,wBAAwB;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,gBAAgB,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;KAAE,CAAC;IAC5I;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,yBAAyB,CAAC;CAC/C;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAM1E;AAsJD;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,EAAE,0BAA0B,EAGrE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B,EAAE,SAAS,MAAM,EAAgC,CAAC;AAE1F,6DAA6D;AAC7D,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,GAAE,sBAA2B,GAClC,yBAAyB,CAS3B;AAED;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,GAAE,sBAA2B,GAClC,yBAAyB,EAAE,CAO7B;AAID;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAU1D;AAID;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,aAAa,CA0BlF;AAuBD,MAAM,WAAW,oBAAoB;IACnC,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,0EAA0E;IAC1E,gBAAgB,EAAE,MAAM,CAAC;IACzB,8BAA8B;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACjC,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,SAAS,EAAE,OAAO,CAAC;IACnB,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,oBAAoB,GAAG,eAAe,CA2EpF;AAID;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,oBAAoB,GAC5B,WAAW,GACX,aAAa,GACb,UAAU,GACV,qBAAqB,GACrB,qBAAqB,CAAC;AAE1B,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,GAAG,qBAAqB,GAAG,qBAAqB,EACrE,MAAM,CAAC,EAAE,MAAM,GACd,cAAc,CAQhB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,cAAc,EAAE,EACxB,IAAI,GAAE;IAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC1C,cAAc,CA6BhB;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,SAAS,EAAE,eAAe,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,sBAAsB,CAAC;IACtC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,kBAAkB,CAAC,CAAC;CAC3D,GAAG,OAAO,CAAC,cAAc,CAAC,CA0B1B;AAID;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQ/D;AAID;;;;;GAKG;AACH,MAAM,WAAW,8BAA8B;IAC7C,sCAAsC;IACtC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AASD;;;;;;;;;;;GAWG;AACH,wBAAgB,oCAAoC,CAClD,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,8BAA8B,GAC1C,IAAI,CAkBN;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,GAAG,CAAC,EAAE,IAAI,GACT,OAAO,CAiCT"}
@@ -22,17 +22,36 @@
22
22
  * from `degraded` (framework present, this call failed) and
23
23
  * `skipped-abbreviated` (author chose the fast path).
24
24
  *
25
- * codex is the FIRST supported framework; the registry
26
- * (`SUPPORTED_REVIEWER_FRAMEWORKS`) is the single seam for gemini-cli and
27
- * others to plug in later (Out of Scope here). Adding a framework is one
28
- * registry entry + one `id`-union extension no skill change.
25
+ * codex is the FIRST supported framework; gemini-cli is the SECOND (Piece 3 of
26
+ * docs/specs/AUTONOMY-PRINCIPLES-ENFORCEMENT-SPEC.md cross-model convergence
27
+ * hardening). The registry (`SUPPORTED_REVIEWER_FRAMEWORKS`) remains the single
28
+ * seam for further frameworks. Adding a framework is one registry entry + one
29
+ * `id`-union extension — no skill change.
30
+ *
31
+ * Piece 3 additions (all signal-only, never-throw, same invariants as above):
32
+ * - `detectGeminiReviewer` + the gemini registry entry (family diversity).
33
+ * - `detectAllCrossModelReviewers` — collect EVERY available framework, not
34
+ * just the first match, so the skill runs one external pass per family.
35
+ * - `isConcreteReviewerModel` — the fail-loud model canary: a tier word
36
+ * ('capable', 'fast', …) falling through model resolution degrades the
37
+ * review LOUDLY instead of silently selecting a dead reviewer.
38
+ * - `hashSpecReviewableBody` — delta-gating: externals re-run only when the
39
+ * spec's reviewable body (frontmatter stripped) actually changed.
40
+ * - `recordFrameworkActivationObservation` / `wasNonClaudeFrameworkActiveWithin`
41
+ * — the durable standing-framework baseline: activation is judged against
42
+ * a lookback window of recorded observations, not a just-in-time reading,
43
+ * so a just-before-converge framework deactivation cannot exempt a spec.
44
+ * - `TRUSTED_REVIEWER_FRAMEWORKS` — the provider allowlist (no spec egress
45
+ * to untrusted/custom endpoints).
29
46
  */
47
+ import crypto from 'node:crypto';
30
48
  import fs from 'node:fs';
31
49
  import os from 'node:os';
32
50
  import path from 'node:path';
33
- import { detectCodexPath } from './Config.js';
51
+ import { detectCodexPath, detectGeminiPath } from './Config.js';
34
52
  import { validateRule1 } from '../providers/adapters/openai-codex/credentials.js';
35
53
  import { resolveCliModelFlag } from '../providers/adapters/openai-codex/models.js';
54
+ import { resolveCliModelFlag as resolveGeminiModelFlag } from '../providers/adapters/gemini-cli/models.js';
36
55
  import { buildIntelligenceProvider, } from './intelligenceProviderFactory.js';
37
56
  // ── Constants (tunable) ─────────────────────────────────────────────────
38
57
  /**
@@ -154,6 +173,86 @@ export function detectCodexReviewer(inputs = {}) {
154
173
  model: resolveCliModelFlag(REVIEW_MODEL_TIER),
155
174
  };
156
175
  }
176
+ /**
177
+ * Resolve the default gemini oauth_creds.json path. DELIBERATELY no env-var
178
+ * override: the gemini CLI (verified v0.25.2) resolves creds at
179
+ * `~/.gemini/oauth_creds.json` UNCONDITIONALLY — there is no GEMINI_HOME.
180
+ * Honoring one here would make detection probe a path the CLI never reads
181
+ * (false-unavailable on an authed host -> the gemini pass silently skipped AND
182
+ * a false `gemini-cli:false` recorded into the activation baseline — the exact
183
+ * suppression Piece 3 exists to prevent). Tests inject `geminiOauthCredsPath`.
184
+ */
185
+ function defaultGeminiOauthCredsPath() {
186
+ return path.join(os.homedir(), '.gemini', 'oauth_creds.json');
187
+ }
188
+ /**
189
+ * Is the gemini CLI's cached OAuth credentials file an authed shape? Authed
190
+ * iff the file parses as JSON with a non-empty string `access_token` OR
191
+ * `refresh_token` (the CLI refreshes an expired access token from the refresh
192
+ * token, so either is a usable seat). A missing / unreadable / malformed file
193
+ * → false (not authed). Never throws.
194
+ */
195
+ function geminiOauthCredsAuthed(credsPath) {
196
+ try {
197
+ const raw = fs.readFileSync(credsPath, 'utf-8');
198
+ const parsed = JSON.parse(raw);
199
+ const nonEmptyString = (v) => typeof v === 'string' && v.length > 0;
200
+ return nonEmptyString(parsed?.access_token) || nonEmptyString(parsed?.refresh_token);
201
+ }
202
+ catch {
203
+ // @silent-fallback-ok — deny-safe: missing/unreadable/malformed creds mean
204
+ // "not authed" (the reviewer is reported unavailable with a named reason);
205
+ // mirrors the codex auth probe above.
206
+ return false;
207
+ }
208
+ }
209
+ /**
210
+ * Detect a gemini reviewer (Piece 3 — the second family in the registry).
211
+ * Returns `{ available: true, framework, model }` iff BOTH of: gemini binary
212
+ * detected, cached OAuth credentials present (`access_token` or
213
+ * `refresh_token`). Any miss → a specific reason.
214
+ *
215
+ * Pure-ish: all external inputs are injectable (mirrors
216
+ * `detectCodexReviewer`). With no inputs it probes the real host. It NEVER
217
+ * throws.
218
+ */
219
+ export function detectGeminiReviewer(inputs = {}) {
220
+ const env = inputs.env ?? process.env;
221
+ const geminiPath = inputs.geminiPathDetected !== undefined ? inputs.geminiPathDetected : detectGeminiPath();
222
+ const credsPath = inputs.geminiOauthCredsPath ?? defaultGeminiOauthCredsPath();
223
+ // 1. Binary present?
224
+ if (!geminiPath) {
225
+ return { available: false, reason: 'gemini-not-installed' };
226
+ }
227
+ // 2. Authed via the CLI's cached OAuth?
228
+ if (!geminiOauthCredsAuthed(credsPath)) {
229
+ return { available: false, reason: 'gemini-not-authed' };
230
+ }
231
+ return {
232
+ available: true,
233
+ framework: 'gemini-cli',
234
+ model: resolveGeminiModelFlag(REVIEW_MODEL_TIER),
235
+ };
236
+ }
237
+ /**
238
+ * Fail-loud model canary (Piece 3). A cross-model review must run on a
239
+ * CONCRETE model id — never a bare tier word that fell through a
240
+ * tier→model resolution map (the `resolveModelForFramework` fall-through
241
+ * failure class: the literal string 'capable' is not a model, and silently
242
+ * passing it selects a dead reviewer). Returns false for undefined/empty
243
+ * strings and for bare tier words (case-insensitive). Both registry entries
244
+ * check this BEFORE invoking the provider and degrade LOUDLY
245
+ * (`model-resolution-canary`) on a failure.
246
+ */
247
+ export function isConcreteReviewerModel(model) {
248
+ if (typeof model !== 'string')
249
+ return false;
250
+ const trimmed = model.trim();
251
+ if (trimmed.length === 0)
252
+ return false;
253
+ const TIER_WORDS = new Set(['fast', 'balanced', 'capable', 'haiku', 'sonnet', 'opus']);
254
+ return !TIER_WORDS.has(trimmed.toLowerCase());
255
+ }
157
256
  /**
158
257
  * The codex reviewer entry. Detection delegates to `detectCodexReviewer`;
159
258
  * `review` routes through the factory-built `CodexCliIntelligenceProvider`.
@@ -162,9 +261,20 @@ const codexReviewer = {
162
261
  id: 'codex-cli',
163
262
  detect: (inputs) => detectCodexReviewer(inputs),
164
263
  review: async (args) => {
165
- const detection = detectCodexReviewer();
264
+ const detection = args.detectionOverride ?? detectCodexReviewer();
166
265
  const model = detection.model ?? resolveCliModelFlag(REVIEW_MODEL_TIER);
167
266
  const tag = `cross-model:codex-cli:${model}`;
267
+ // Fail-loud model canary (Piece 3): NEVER silently review with a
268
+ // tier-word model — a fall-through 'capable' is a dead reviewer.
269
+ if (!isConcreteReviewerModel(model)) {
270
+ return {
271
+ status: 'degraded',
272
+ framework: 'codex-cli',
273
+ model,
274
+ reason: 'model-resolution-canary',
275
+ flag: `cross-model-review: codex-cli:${model} (degraded: model-resolution-canary)`,
276
+ };
277
+ }
168
278
  // Build (or accept an injected) provider. The factory wraps it in the
169
279
  // account-global circuit breaker, so a rate-limited review degrades the
170
280
  // same way every other instar LLM call does.
@@ -210,16 +320,107 @@ const codexReviewer = {
210
320
  };
211
321
  },
212
322
  };
323
+ /**
324
+ * The gemini reviewer entry (Piece 3 — family diversity: a second non-Claude
325
+ * model family alongside GPT). Detection delegates to `detectGeminiReviewer`;
326
+ * `review` routes through the factory-built `GeminiCliIntelligenceProvider`
327
+ * (same circuit-breaker wrapping, same degraded semantics as codex).
328
+ */
329
+ const geminiReviewer = {
330
+ id: 'gemini-cli',
331
+ detect: (inputs) => detectGeminiReviewer(inputs),
332
+ review: async (args) => {
333
+ const detection = args.detectionOverride ?? detectGeminiReviewer();
334
+ const model = detection.model ?? resolveGeminiModelFlag(REVIEW_MODEL_TIER);
335
+ const tag = `cross-model:gemini-cli:${model}`;
336
+ // Fail-loud model canary (Piece 3): NEVER silently review with a
337
+ // tier-word model — a fall-through 'capable' is a dead reviewer.
338
+ if (!isConcreteReviewerModel(model)) {
339
+ return {
340
+ status: 'degraded',
341
+ framework: 'gemini-cli',
342
+ model,
343
+ reason: 'model-resolution-canary',
344
+ flag: `cross-model-review: gemini-cli:${model} (degraded: model-resolution-canary)`,
345
+ };
346
+ }
347
+ // Build (or accept an injected) provider. The factory wraps it in the
348
+ // account-global circuit breaker, so a rate-limited review degrades the
349
+ // same way every other instar LLM call does.
350
+ const provider = args.providerOverride ??
351
+ buildIntelligenceProvider({ framework: 'gemini-cli' });
352
+ if (!provider) {
353
+ // Binary vanished between detect and review (or detection said
354
+ // unavailable and review was called anyway). Degraded, not a throw.
355
+ return {
356
+ status: 'degraded',
357
+ framework: 'gemini-cli',
358
+ model,
359
+ reason: 'provider-unavailable',
360
+ flag: `cross-model-review: gemini-cli:${model} (degraded: provider-unavailable)`,
361
+ };
362
+ }
363
+ let raw;
364
+ try {
365
+ raw = await provider.evaluate(args.promptText, {
366
+ model: REVIEW_MODEL_TIER,
367
+ timeoutMs: args.timeoutMs,
368
+ attribution: { component: 'crossModelReviewer' }, // attribution for /metrics/features
369
+ });
370
+ }
371
+ catch (err) {
372
+ const reason = classifyReviewFailure(err);
373
+ return {
374
+ status: 'degraded',
375
+ framework: 'gemini-cli',
376
+ model,
377
+ reason,
378
+ flag: `cross-model-review: gemini-cli:${model} (degraded: ${reason})`,
379
+ };
380
+ }
381
+ const parsed = parseReviewerReply(raw, tag);
382
+ return {
383
+ status: 'ok',
384
+ framework: 'gemini-cli',
385
+ model,
386
+ verdict: parsed.verdict,
387
+ findings: [parsed],
388
+ flag: `cross-model-review: gemini-cli:${model}`,
389
+ };
390
+ },
391
+ };
213
392
  /**
214
393
  * The supported-reviewer registry. codex first — the order IS the preference
215
- * order. gemini-cli and others land here as later steps (Out of Scope).
394
+ * order. gemini second (Piece 3). Further frameworks land here as later
395
+ * registry entries. NOTE: the registry only ever carries first-party OAuth
396
+ * CLI adapters — see `TRUSTED_REVIEWER_FRAMEWORKS` below.
216
397
  */
217
- export const SUPPORTED_REVIEWER_FRAMEWORKS = [codexReviewer];
398
+ export const SUPPORTED_REVIEWER_FRAMEWORKS = [
399
+ codexReviewer,
400
+ geminiReviewer,
401
+ ];
402
+ /**
403
+ * Trusted-provider allowlist (Piece 3 — no spec egress to untrusted
404
+ * endpoints). The registry only ever carries FIRST-PARTY OAuth CLI adapters:
405
+ * the full spec text is handed to the reviewer model, so it must NEVER be
406
+ * sent to a custom/base-URL endpoint an operator (or attacker) pointed a
407
+ * framework at. The pi-cli multi-provider case is deliberately EXCLUDED from
408
+ * cross-model review for exactly this reason — its provider may be a custom
409
+ * endpoint. A framework id outside this list is refused by the script
410
+ * wrapper (`--family`) with reason `untrusted-framework`.
411
+ */
412
+ export const TRUSTED_REVIEWER_FRAMEWORKS = ['codex-cli', 'gemini-cli'];
413
+ /** Is `id` on the trusted first-party reviewer allowlist? */
414
+ export function isTrustedReviewerFramework(id) {
415
+ return TRUSTED_REVIEWER_FRAMEWORKS.includes(id);
416
+ }
218
417
  /**
219
418
  * Walk the registry in preference order and return the FIRST available
220
- * framework's detection result. If none is available, returns the codex
221
- * reason when there's exactly one entry (so the report can be specific), else
222
- * the generic `no-supported-framework`.
419
+ * framework's detection result (back-compat single-reviewer entry point
420
+ * the multi-family collection is `detectAllCrossModelReviewers`). If none is
421
+ * available, returns the preference-leader's specific reason (codex today) so
422
+ * the report can render a concrete remediation, rather than the generic
423
+ * `no-supported-framework`.
223
424
  *
224
425
  * SIGNAL-ONLY: never throws, never blocks. A `false` simply routes the skill
225
426
  * to the internal-only fallback (spec §4).
@@ -230,13 +431,29 @@ export function detectCrossModelReviewer(inputs = {}) {
230
431
  if (result.available)
231
432
  return result;
232
433
  }
233
- // Nothing available. Surface the single framework's specific reason when
234
- // there's only one entry (codex today); otherwise the generic reason.
235
- if (SUPPORTED_REVIEWER_FRAMEWORKS.length === 1) {
236
- return SUPPORTED_REVIEWER_FRAMEWORKS[0].detect(inputs);
237
- }
434
+ // Nothing available. Surface the preference-leader's specific reason.
435
+ const leader = SUPPORTED_REVIEWER_FRAMEWORKS[0];
436
+ if (leader)
437
+ return leader.detect(inputs);
238
438
  return { available: false, reason: 'no-supported-framework' };
239
439
  }
440
+ /**
441
+ * Collect EVERY available reviewer framework, in registry preference order
442
+ * (Piece 3 — family diversity: GPT and Gemini catch different failure
443
+ * classes, so the externals pass runs one review PER available family, not
444
+ * first-match-only). Returns an empty array when none is available.
445
+ *
446
+ * SIGNAL-ONLY: never throws, never blocks.
447
+ */
448
+ export function detectAllCrossModelReviewers(inputs = {}) {
449
+ const available = [];
450
+ for (const framework of SUPPORTED_REVIEWER_FRAMEWORKS) {
451
+ const result = framework.detect(inputs);
452
+ if (result.available)
453
+ available.push(result);
454
+ }
455
+ return available;
456
+ }
240
457
  // ── Failure classification ──────────────────────────────────────────────
241
458
  /**
242
459
  * Map a provider rejection into a coarse `degraded` reason. The provider
@@ -484,7 +701,116 @@ export async function runCrossModelReview(args) {
484
701
  return framework.review({
485
702
  promptText: args.assembled.promptText,
486
703
  timeoutMs: args.timeoutMs ?? REVIEW_TIMEOUT_MS,
704
+ // Hand the already-computed detection down so the entry never re-probes
705
+ // the host (and tests stay hermetic to the injected inputs).
706
+ detectionOverride: detection,
487
707
  ...(args.providerOverride ? { providerOverride: args.providerOverride } : {}),
488
708
  });
489
709
  }
710
+ // ── Delta-gating (reviewable-body hash) ─────────────────────────────────
711
+ /**
712
+ * Hash the spec's REVIEWABLE body (Piece 3 delta-gating): sha256 hex of the
713
+ * spec text with the leading YAML frontmatter block stripped and line endings
714
+ * normalized (\r\n → \n). Frontmatter is excluded so tag-writes
715
+ * (`review-convergence`, `approved: true`, cross-model flags) and other
716
+ * metadata edits do NOT change the hash — externals re-run only when the
717
+ * content a reviewer would actually read changed. The skill runs externals on
718
+ * round 1 and on any round where this hash differs from the last external
719
+ * pass's hash; an unchanged round records a skip-with-logged-note.
720
+ */
721
+ export function hashSpecReviewableBody(specText) {
722
+ const normalized = (specText ?? '').replace(/\r\n/g, '\n');
723
+ // Strip ONE leading frontmatter block: `---\n ... \n---` at the very top,
724
+ // where the close fence is a WHOLE line (anchored `(\n|$)`) — `\n---\n?`
725
+ // could terminate mid-line on `--- text` / `----` inside the block
726
+ // (second-pass finding, PR 3).
727
+ const body = normalized.replace(/^---\n[\s\S]*?\n---(\n|$)/, '');
728
+ return crypto.createHash('sha256').update(body, 'utf-8').digest('hex');
729
+ }
730
+ /** Max JSONL lines retained in the activation-history file. */
731
+ const ACTIVATION_HISTORY_MAX_LINES = 2000;
732
+ function activationHistoryPath(stateDir) {
733
+ return path.join(stateDir, 'state', 'framework-activation-history.jsonl');
734
+ }
735
+ /**
736
+ * Append ONE observation line to the durable framework-activation history
737
+ * (Piece 3 — the standing-framework baseline). The externals-mandatory check
738
+ * is judged against this recorded history over a lookback window, NOT a
739
+ * just-in-time reading — so deactivating a framework right before converging
740
+ * cannot present the agent as "genuinely single-framework."
741
+ *
742
+ * mkdir -p's the state dir; caps the file at the most recent
743
+ * `ACTIVATION_HISTORY_MAX_LINES` lines on every write. Filesystem errors
744
+ * propagate — a silently-unrecorded baseline would quietly weaken the
745
+ * mandatory check (fail-loud).
746
+ */
747
+ export function recordFrameworkActivationObservation(stateDir, observation) {
748
+ const file = activationHistoryPath(stateDir);
749
+ fs.mkdirSync(path.dirname(file), { recursive: true });
750
+ const entry = JSON.stringify({
751
+ ts: observation.ts ?? new Date().toISOString(),
752
+ frameworks: observation.frameworks,
753
+ });
754
+ let lines = [];
755
+ try {
756
+ lines = fs.readFileSync(file, 'utf-8').split('\n').filter((l) => l.trim().length > 0);
757
+ }
758
+ catch {
759
+ // No file yet — first observation.
760
+ }
761
+ lines.push(entry);
762
+ if (lines.length > ACTIVATION_HISTORY_MAX_LINES) {
763
+ lines = lines.slice(-ACTIVATION_HISTORY_MAX_LINES);
764
+ }
765
+ fs.writeFileSync(file, lines.join('\n') + '\n', 'utf-8');
766
+ }
767
+ /**
768
+ * Was ANY non-Claude reviewer framework active at ANY point within the
769
+ * lookback window, per the durable activation history? This is the
770
+ * externals-mandatory check (Piece 3): `true` means the cross-model pass is
771
+ * NON-SKIPPABLE for the spec — including when a framework was deactivated
772
+ * inside the window (a just-before-converge deactivation does not exempt the
773
+ * spec). The advisory "externals unavailable" floor is legitimate only when
774
+ * this returns `false` across the whole lookback.
775
+ *
776
+ * NEVER throws: a missing file → false; corrupt lines are skipped.
777
+ */
778
+ export function wasNonClaudeFrameworkActiveWithin(stateDir, lookbackDays, now) {
779
+ try {
780
+ const file = activationHistoryPath(stateDir);
781
+ const raw = fs.readFileSync(file, 'utf-8');
782
+ const cutoff = (now ?? new Date()).getTime() - lookbackDays * 24 * 60 * 60 * 1000;
783
+ for (const line of raw.split('\n')) {
784
+ if (!line.trim())
785
+ continue;
786
+ try {
787
+ const parsed = JSON.parse(line);
788
+ const ts = typeof parsed.ts === 'string' ? Date.parse(parsed.ts) : NaN;
789
+ if (!Number.isFinite(ts) || ts < cutoff)
790
+ continue;
791
+ const frameworks = parsed.frameworks;
792
+ if (frameworks && typeof frameworks === 'object') {
793
+ // Only TRUSTED reviewer framework ids count toward the baseline — a
794
+ // stray/hand-written key (e.g. "claude-code": true) must not flip
795
+ // the externals-mandatory decision (second-pass finding, PR 3).
796
+ const entries = Object.entries(frameworks);
797
+ if (entries.some(([id, v]) => v === true && isTrustedReviewerFramework(id))) {
798
+ return true;
799
+ }
800
+ }
801
+ }
802
+ catch {
803
+ // @silent-fallback-ok — a corrupt history line is skipped (never throws);
804
+ // the read is a union-over-time, so a lost line can only UNDER-report
805
+ // activation, which keeps externals mandatory-safe, never lies them off.
806
+ }
807
+ }
808
+ return false;
809
+ }
810
+ catch {
811
+ // @silent-fallback-ok — a missing/unreadable history file is the expected
812
+ // pre-first-run state: no recorded activation is the correct answer.
813
+ return false;
814
+ }
815
+ }
490
816
  //# sourceMappingURL=crossModelReviewer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"crossModelReviewer.js","sourceRoot":"","sources":["../../src/core/crossModelReviewer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"crossModelReviewer.js","sourceRoot":"","sources":["../../src/core/crossModelReviewer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.3.483",
3
+ "version": "1.3.484",
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,6 +1,6 @@
1
1
  ---
2
2
  name: spec-converge
3
- description: Iteratively review an instar-development spec with multi-angle internal reviewers (security, scalability, adversarial, integration, decision-completeness, lessons-aware) and a real cross-model external reviewer routed through the agent's own installed codex CLI (GPT-tier) until convergence, then produce a comprehensive ELI10 convergence report. Output is a spec tagged review-convergence — one of the two tags /instar-dev requires before it will touch instar source. NOT user-invocable; run by the instar-developing agent before any spec-driven /instar-dev work.
3
+ description: Iteratively review an instar-development spec with multi-angle internal reviewers (security, scalability, adversarial, integration, decision-completeness, lessons-aware) and real cross-model external reviewers routed through the agent's own installed CLIs (codex GPT-tier, gemini → Gemini-tier; one pass per available family) until convergence, then produce a comprehensive ELI10 convergence report. Output is a spec tagged review-convergence — one of the two tags /instar-dev requires before it will touch instar source. NOT user-invocable; run by the instar-developing agent before any spec-driven /instar-dev work.
4
4
  metadata:
5
5
  user_invocable: "false"
6
6
  audience: "instar-developing agent only — NOT end users"
@@ -72,29 +72,37 @@ The skill spawns reviewers in parallel:
72
72
  - **Decision-Completeness.** (Autonomy Principle 2 — `docs/specs/AUTONOMY-PRINCIPLES-ENFORCEMENT-SPEC.md` Piece 2.) Enumerates every point where the building agent would have to **stop mid-run and ask the user**. Each must be either **frontloaded** into a `## Frontloaded Decisions` section or explicitly tagged **cheap-to-change-after** because the work ships behind a named dark/dry-run/read-only phase. The reviewer **CONTESTS every cheap tag** — it independently asserts reversibility, and a closed non-cheap taxonomy overrides any tag: anything touching **durable external side-effects, money, identity, or a published/user-visible interface is NEVER cheap**, regardless of a "ships dark" label. A contested tag the reviewer rejects is a **material finding that blocks convergence**. Prompt: `templates/reviewer-decision-completeness.md`. Applies to ALL specs through this skill (D7) — no size gate, no per-spec override (D11; the rejected `disposition: override` escape hatch would reopen the exact skip-hatch Principle 2 closes).
73
73
  - **Lessons-aware.** Loads the canonical Instar Design Principles + Lessons Learned index (`docs/INSTAR-DESIGN-PRINCIPLES-AND-LESSONS.md`) plus the running agent's local `.instar/memory/feedback_*.md` entries, then checks the spec for (a) direct contradictions of documented principles/lessons, (b) applicable lessons the spec fails to engage with, (c) behavioral lessons violated by agent-facing surfaces the spec proposes, and **(d) FOUNDATION/SUBSYSTEM AUDIT — the design the spec TESTS, EXTENDS, or BUILDS ON, not just the spec's own surface: does that foundation violate a known standard or repeat a known mistake?** The audit MUST reach one layer below the spec boundary. A spec can be internally clean while faithfully testing or extending a flawed foundation — e.g. a test-harness spec that correctly proves a permission gate which *itself* holds brittle blocking authority in violation of Signal-vs-Authority, or an extension spec built on a subsystem with an unaddressed gap. Taking the underlying subsystem "as given" is exactly how a standards violation survives review: the spec passes, the foundation's flaw is never weighed. When the foundation is flawed, the finding is "this spec is sound but the subsystem it depends on violates standard X / repeats mistake Y — surface it before building on/around it." Catches the "Phase 2" anti-pattern, the spec-converge-pre-auth-circular failure mode (see `feedback_spec_converge_pre_auth_circular`), and the foundation-not-audited gap (the Slack-permission-gate brittle-enum-as-authority that the harness convergence cleared because it audited only the harness, 2026-06-09).
74
74
 
75
- **External reviewer (cross-model, via the agent's own installed codex CLI):**
75
+ **External reviewers (cross-model, via the agent's own installed CLIs — one pass PER AVAILABLE FAMILY):**
76
76
 
77
- The external "cross-model" pass is a single independent GPT-tier read that sits *outside* the Claude family to catch the blind spots Claude models share. It is **real**, routed through the agent's own `codex login` (no new API key, no new network dependency), and implemented in code — NOT a hand-wave. Run it like this:
77
+ The external "cross-model" pass is a set of independent non-Claude reads that sit *outside* the Claude family to catch the blind spots Claude models share. It is **real**, routed through the agent's own CLI logins (`codex login` → GPT-tier, gemini OAuth → Gemini-tier; no new API key, no new network dependency), and implemented in code — NOT a hand-wave. **Family diversity is the point**: GPT and Gemini catch different failure classes, so the pass runs ONE review per available family (detect-all), not first-match-only. Run it like this:
78
78
 
79
- 1. **Detect** whether a supported reviewer framework is installed + authed:
79
+ 1. **Detect** every supported reviewer framework that is installed + authed:
80
80
  ```bash
81
- node skills/spec-converge/scripts/cross-model-review.mjs --spec <spec-path> --detect-only
81
+ node skills/spec-converge/scripts/cross-model-review.mjs --spec <spec-path> --detect-only --state-dir .instar
82
82
  ```
83
- Returns `{ available, framework?, model?, reason? }`. `available:false` skip the external pass, set the fallback flag (see §"No-codex fallback" below / Phase 5), and continue internal-only. **Never block.**
83
+ Returns `{ available, frameworks: [...all available...], framework?, model?, reason? }` (the single-framework fields remain for back-compat). `--state-dir` records the detection into the **durable framework-activation history** (`state/framework-activation-history.jsonl`) the standing-framework baseline the mandatory-check in Phase 3 reads. `available:false` → set the fallback flag (see Phase 5) and continue internal-only **only if the mandatory-check permits it** (Phase 3). **Never block.**
84
84
 
85
- 2. **Run** the external review when available — pass the spec plus the same architectural context docs the internal reviewers receive (the docs the spec references):
85
+ 2. **Run** one external review per available family — pass the spec plus the same architectural context docs the internal reviewers receive (the docs the spec references):
86
86
  ```bash
87
87
  node skills/spec-converge/scripts/cross-model-review.mjs \
88
- --spec <spec-path> \
88
+ --spec <spec-path> --family codex-cli \
89
+ --context docs/foo.md --context docs/bar.md
90
+ node skills/spec-converge/scripts/cross-model-review.mjs \
91
+ --spec <spec-path> --family gemini-cli \
89
92
  --context docs/foo.md --context docs/bar.md
90
93
  ```
91
- It emits a JSON `ReviewerResult` on stdout: `{ status, framework?, model?, verdict?, findings?, reason?, flag }`. Fold its `findings` into the round alongside the internal reviewers'. `status:'degraded'` (codex present but the call failed — timeout / error / rate-limited) is a *partial* cross-model pass for the round: fold in whatever came back and record the `degraded` flag — it does **not** collapse to `unavailable`.
94
+ Each emits a JSON `ReviewerResult` on stdout: `{ status, framework?, model?, verdict?, findings?, reason?, flag }`. Fold each `findings` into the round alongside the internal reviewers'. `status:'degraded'` (framework present but the call failed — timeout / error / rate-limited) is a *partial* cross-model pass for the round: fold in whatever came back and record the `degraded` flag — it does **not** collapse to `unavailable`. (Omitting `--family` keeps the old single-pass first-match behavior for existing callers.)
95
+
96
+ Two structural guards on the pass:
97
+
98
+ - **Fail-loud model canary.** Model selection is dynamic (the `'capable'` tier resolved per framework — never a pinned name), and a tier word that falls through resolution (`'capable'` is not a model) is caught by `isConcreteReviewerModel` BEFORE the provider is invoked: the round degrades loudly with reason `model-resolution-canary` instead of silently selecting a dead reviewer.
99
+ - **Trusted-provider allowlist.** `--family` only accepts frameworks on `TRUSTED_REVIEWER_FRAMEWORKS` (`codex-cli`, `gemini-cli` — first-party OAuth CLI adapters). The full spec text is handed to the reviewer, so it must NEVER be sent to a custom/base-URL endpoint; **pi-cli is deliberately excluded** from cross-model review for this reason (its provider may be a custom endpoint). An untrusted family is refused with `reason: 'untrusted-framework'`.
92
100
 
93
- The detection + invocation + parsing live in the unit-tested `src/core/crossModelReviewer.ts` module (built to `dist/core/crossModelReviewer.js`); the script is a thin file-I/O wrapper. codex is the **first** supported framework in an extensible registry (`SUPPORTED_REVIEWER_FRAMEWORKS`) — gemini-cli and others plug in there later with **no skill change**.
101
+ The detection + invocation + parsing live in the unit-tested `src/core/crossModelReviewer.ts` module (built to `dist/core/crossModelReviewer.js`); the script is a thin file-I/O wrapper. codex and gemini are the supported frameworks in an extensible registry (`SUPPORTED_REVIEWER_FRAMEWORKS`) — further first-party CLIs plug in there with **no skill change**.
94
102
 
95
103
  Each internal reviewer receives the spec, the architectural context docs referenced in the spec (`docs/signal-vs-authority.md`, `docs/integrated-being.md`, relevant subsystem docs), and a prompt specific to their perspective. Each produces a structured finding list.
96
104
 
97
- The **six internal reviewers + the cross-model external pass** run in parallel (the external pass is one cross-model read through the first available supported framework — the honest mechanism, not three phantom API models). Their findings are collected.
105
+ The **six internal reviewers + the cross-model external passes** run in parallel (one external read per available supported family — the honest mechanism, not three phantom API models). Their findings are collected.
98
106
 
99
107
  **Code-backed reviewer — the Standards-Conformance Gate (auto-invoked).** Alongside the internal reviewers + the cross-model external pass, call the live gate: `POST /spec/conformance-check` with the spec (body `{ "specPath": "<path-within-specsDir>" }`, or `{ "markdown": "<spec text>" }`). Unlike the prompt-driven reviewers, the gate is *code that reads the living constitution* (`docs/STANDARDS-REGISTRY.md`) and returns a per-standard report — `ok` / `at-risk` / `n/a` + a reason for every standing standard. Fold its `at-risk` entries into the round's findings. It is the structural complement to the Lessons-aware reviewer: lessons-aware reads the lessons doc + local memory (prompt-driven); the gate reads the constitution itself (code), so a registry edit can never be silently missed. **Signal-only:** advisory — it surfaces violations, it does not block (blocking authority is the separate, later `scg-blocking-authority` follow-up, per *Signal vs. Authority*). **Fail-open:** if the gate is disabled/unreachable (503) or returns `degraded: true`, note that the constitutional pass was not authoritative and continue — a down gate must never stall spec review. (This auto-invocation is the dogfood-to-ship enforcement of the **Self-Hosting** standard — the gate now *runs* at spec-review rather than being a step the author must remember.)
100
108
 
@@ -110,7 +118,26 @@ Every update preserves the spec's structure. Changes are additive (new sections
110
118
 
111
119
  ### Phase 3 — Convergence check
112
120
 
113
- After the spec is updated, the skill runs another full review round (the six internal reviewers + the cross-model external pass, in parallel, on the updated spec).
121
+ After the spec is updated, the skill runs another full review round (the six internal reviewers + the cross-model external passes, in parallel, on the updated spec).
122
+
123
+ #### Delta-gating the external passes (mandatory, but not blindly every round)
124
+
125
+ The externals are **MANDATORY on round 1 and on any round where the spec's reviewable body changed** since the last external pass. "Changed" is decided by content hash, not memory:
126
+
127
+ ```bash
128
+ node skills/spec-converge/scripts/cross-model-review.mjs --spec <spec-path> --hash-only
129
+ ```
130
+
131
+ prints `{ hash }` — `hashSpecReviewableBody`'s sha256 of the spec with the leading YAML frontmatter stripped and line endings normalized, so tag-writes and approval edits never change it. Record the hash alongside each external pass; when a later round's hash equals the last external pass's hash, the externals for that round are **skipped-with-logged-note** (the iteration log records "externals delta-skipped: body unchanged since round N, hash <prefix>"). This is the cost answer — redundant re-reviews of an unchanged spec are killed — and it does **NOT** count as `skipped-abbreviated`: the spec still received its external review of this exact content.
132
+
133
+ #### The mandatory-check (durable standing-framework baseline)
134
+
135
+ The external passes are **NON-SKIPPABLE** whenever a non-Claude framework was **active at ANY point in the last 7 days** per the durable activation history:
136
+
137
+ - The check is `wasNonClaudeFrameworkActiveWithin(stateDir, 7)` (exported from `src/core/crossModelReviewer.ts`), read from `state/framework-activation-history.jsonl` — the file every `--detect-only --state-dir` invocation appends to.
138
+ - A **just-before-converge deactivation does not exempt the spec**: activation is judged against the recorded lookback window, never a just-in-time reading. A framework deactivated inside the window keeps externals mandatory.
139
+ - A **mid-converge deactivation** (frameworks available at round 1, gone at round N) is logged in the iteration log and **fails report validation**.
140
+ - The advisory "externals unavailable" floor (Phase 5's `unavailable` flag) is legitimate ONLY for an agent that has been genuinely single-framework across the whole lookback — a recorded standing fact, not a 30-second-old flip.
114
141
 
115
142
  Convergence criteria (BOTH must hold — additive, per Autonomy Principle 2):
116
143
 
@@ -186,7 +213,7 @@ review-convergence: "<ISO timestamp>"
186
213
  review-iterations: <N>
187
214
  review-completed-at: "<ISO timestamp>"
188
215
  review-report: "docs/specs/reports/<slug>-convergence.md"
189
- cross-model-review: "<flag>" # codex-cli:<model> | unavailable | degraded-all-rounds | skipped-abbreviated
216
+ cross-model-review: "<flag>" # codex-cli:<model> | gemini-cli:<model> | unavailable | degraded-all-rounds | skipped-abbreviated
190
217
  cross-model-review-reason: "<reason>" # only when unavailable / degraded / degraded-all-rounds
191
218
  single-run-completable: true # earned, not minted — written only when Open questions reached zero
192
219
  frontloaded-decisions: <N> # count from the Decision-Completeness reviewer's final round
@@ -253,7 +280,7 @@ The convergence check is structural. If the LLM comparator finds new material is
253
280
  A smaller finding count is NOT convergence. Convergence is zero material findings in a new round.
254
281
 
255
282
  ### Skipping a reviewer perspective to ship faster
256
- All six internal reviewers (security, scalability, adversarial, integration, decision-completeness, lessons-aware) AND the cross-model external pass run on every round. Skipping is visible in the iteration log and fails the report validation. During pattern-instance abbreviated convergence, the external cross-model pass may be skipped to save costrecord that honestly as `cross-model-review: skipped-abbreviated` (distinct from `unavailable`: the framework may be present, but the author chose the fast path) but the lessons-aware reviewer MUST run; it's the only structural defense against the spec-converge-pre-auth-circular failure mode.
283
+ All six internal reviewers (security, scalability, adversarial, integration, decision-completeness, lessons-aware) AND the cross-model external passes run on every round (subject to Phase 3's delta-gating — an unchanged-body round delta-skips with a logged note, which is NOT a skip of the perspective). Skipping is visible in the iteration log and fails the report validation. **Abbreviated convergence may NO LONGER skip the external pass when the 7-day activation history shows a non-Claude framework** (`wasNonClaudeFrameworkActiveWithin`see Phase 3's mandatory-check): a framework that was active at any point in the lookback makes externals mandatory, and a just-before-converge deactivation does not exempt the spec. `cross-model-review: skipped-abbreviated` remains a legitimate record ONLY for genuinely single-framework agents (no non-Claude framework anywhere in the lookback; distinct from `unavailable`). In ALL abbreviated runs the lessons-aware AND decision-completeness reviewers MUST still run; lessons-aware is the only structural defense against the spec-converge-pre-auth-circular failure mode.
257
284
 
258
285
  ### Rewriting the spec between iterations to hide findings
259
286
  Spec edits must address findings, not evade them. The iteration log records both the finding and the resolution. An edit that changes the spec to make the finding "not applicable" without actually solving the concern is caught at the next review round.
@@ -15,20 +15,37 @@
15
15
  * access, so context must be inlined before the spawn.
16
16
  *
17
17
  * Modes:
18
- * --detect-only Print detection JSON and exit (no codex spawn).
19
- * { available, framework?, model?, reason? }
18
+ * --detect-only Print detection JSON and exit (no spawn).
19
+ * { available, frameworks: [...all available...],
20
+ * framework?, model?, reason? } — the `frameworks`
21
+ * array is the Piece-3 family-diverse collection;
22
+ * the single-framework fields stay for back-compat.
23
+ * With --state-dir <dir>, also records the
24
+ * activation observation to the durable
25
+ * framework-activation history (the standing-
26
+ * framework baseline for the mandatory check).
27
+ * --hash-only Print { hash } — sha256 of the spec's reviewable
28
+ * body (frontmatter-stripped, CRLF-normalized) for
29
+ * the skill's delta-gating. Requires --spec.
20
30
  * (default) Detect; if available, assemble the prompt + run
21
- * the codex review; print the ReviewerResult JSON.
31
+ * the review; print the ReviewerResult JSON. With
32
+ * --family <id>, run through THAT framework
33
+ * specifically (must be on the trusted first-party
34
+ * allowlist — spec text is never sent to a custom/
35
+ * base-URL endpoint; pi-cli is excluded by design).
22
36
  *
23
37
  * Usage:
24
38
  * node skills/spec-converge/scripts/cross-model-review.mjs \
25
39
  * --spec docs/specs/<slug>.md \
26
40
  * [--context docs/foo.md --context docs/bar.md ...] \
27
- * [--detect-only] \
41
+ * [--detect-only] [--state-dir .instar] \
42
+ * [--hash-only] \
43
+ * [--family codex-cli|gemini-cli] \
28
44
  * [--timeout-ms 120000]
29
45
  *
30
46
  * Output: a single JSON object on stdout (machine-readable for the skill).
31
- * On detect-only: the CrossModelDetectionResult.
47
+ * On detect-only: the detection JSON above.
48
+ * On hash-only: { hash }.
32
49
  * On full run: the ReviewerResult ({ status, framework?, model?, verdict?,
33
50
  * findings?, reason?, flag }).
34
51
  *
@@ -60,19 +77,30 @@ function fail(msg) {
60
77
 
61
78
  function parseArgs() {
62
79
  const args = process.argv.slice(2);
63
- const out = { spec: null, context: [], detectOnly: false, timeoutMs: null };
80
+ const out = {
81
+ spec: null,
82
+ context: [],
83
+ detectOnly: false,
84
+ hashOnly: false,
85
+ family: null,
86
+ stateDir: null,
87
+ timeoutMs: null,
88
+ };
64
89
  for (let i = 0; i < args.length; i++) {
65
90
  const a = args[i];
66
91
  if (a === '--spec') out.spec = args[++i];
67
92
  else if (a === '--context') out.context.push(args[++i]);
68
93
  else if (a === '--detect-only') out.detectOnly = true;
94
+ else if (a === '--hash-only') out.hashOnly = true;
95
+ else if (a === '--family') out.family = args[++i];
96
+ else if (a === '--state-dir') out.stateDir = args[++i];
69
97
  else if (a === '--timeout-ms') out.timeoutMs = parseInt(args[++i], 10);
70
98
  else fail(`Unknown arg: ${a}`);
71
99
  }
72
100
  if (!out.detectOnly && !out.spec) {
73
101
  fail(
74
102
  'Usage: cross-model-review.mjs --spec PATH [--context PATH ...] ' +
75
- '[--detect-only] [--timeout-ms N]',
103
+ '[--detect-only] [--hash-only] [--family ID] [--state-dir DIR] [--timeout-ms N]',
76
104
  );
77
105
  }
78
106
  return out;
@@ -98,17 +126,81 @@ function readRepoFile(rel) {
98
126
  }
99
127
 
100
128
  async function main() {
101
- const { spec, context, detectOnly, timeoutMs } = parseArgs();
129
+ const { spec, context, detectOnly, hashOnly, family, stateDir, timeoutMs } = parseArgs();
102
130
  const mod = await loadModule();
103
131
 
104
- // Detection is the same in both modes.
105
- const detection = mod.detectCrossModelReviewer();
132
+ // ── --hash-only: the delta-gating hash of the spec's reviewable body ──
133
+ if (hashOnly) {
134
+ if (!spec) fail('--hash-only requires --spec PATH');
135
+ const specMarkdown = readRepoFile(spec);
136
+ process.stdout.write(JSON.stringify({ hash: mod.hashSpecReviewableBody(specMarkdown) }) + '\n');
137
+ process.exit(0);
138
+ }
106
139
 
140
+ // ── --detect-only: report ALL available families (Piece 3) ──
107
141
  if (detectOnly) {
108
- process.stdout.write(JSON.stringify(detection) + '\n');
142
+ const all = mod.detectAllCrossModelReviewers();
143
+ // Back-compat: keep the old single-framework fields (first-match shape).
144
+ const first = mod.detectCrossModelReviewer();
145
+ const report = {
146
+ available: all.length > 0,
147
+ frameworks: all,
148
+ ...(first.framework ? { framework: first.framework } : {}),
149
+ ...(first.model ? { model: first.model } : {}),
150
+ ...(first.reason ? { reason: first.reason } : {}),
151
+ };
152
+ // Record the activation observation into the durable standing-framework
153
+ // baseline when a state dir was provided. A record failure is surfaced in
154
+ // the JSON (fail-loud), never silently swallowed — a missing baseline
155
+ // would quietly weaken the externals-mandatory check.
156
+ if (stateDir) {
157
+ const frameworks = {};
158
+ for (const entry of mod.SUPPORTED_REVIEWER_FRAMEWORKS) {
159
+ frameworks[entry.id] = all.some((d) => d.framework === entry.id);
160
+ }
161
+ try {
162
+ mod.recordFrameworkActivationObservation(stateDir, { frameworks });
163
+ report.activationRecorded = true;
164
+ } catch (err) {
165
+ report.activationRecorded = false;
166
+ report.activationRecordError =
167
+ err instanceof Error ? err.message.slice(0, 200) : String(err);
168
+ }
169
+ }
170
+ process.stdout.write(JSON.stringify(report) + '\n');
109
171
  process.exit(0);
110
172
  }
111
173
 
174
+ // ── full run ──
175
+ // --family: run through ONE specific framework. Allowlist-gated — the full
176
+ // spec text is never sent to a custom/base-URL endpoint (pi-cli excluded).
177
+ let familyEntry = null;
178
+ if (family) {
179
+ if (!mod.isTrustedReviewerFramework(family)) {
180
+ process.stdout.write(
181
+ JSON.stringify({
182
+ status: 'unavailable',
183
+ reason: 'untrusted-framework',
184
+ flag: 'cross-model-review: unavailable',
185
+ }) + '\n',
186
+ );
187
+ process.exit(0);
188
+ }
189
+ familyEntry = mod.SUPPORTED_REVIEWER_FRAMEWORKS.find((f) => f.id === family) ?? null;
190
+ if (!familyEntry) {
191
+ process.stdout.write(
192
+ JSON.stringify({
193
+ status: 'unavailable',
194
+ reason: 'no-supported-framework',
195
+ flag: 'cross-model-review: unavailable',
196
+ }) + '\n',
197
+ );
198
+ process.exit(0);
199
+ }
200
+ }
201
+
202
+ const detection = familyEntry ? familyEntry.detect() : mod.detectCrossModelReviewer();
203
+
112
204
  // Unavailable → print the unavailable flag, exit 0. Never block.
113
205
  if (!detection.available) {
114
206
  const flag = mod.buildCrossModelFlag('unavailable', detection.reason);
@@ -130,10 +222,16 @@ async function main() {
130
222
  context: contextDocs,
131
223
  });
132
224
 
133
- const result = await mod.runCrossModelReview({
134
- assembled,
135
- ...(Number.isFinite(timeoutMs) ? { timeoutMs } : {}),
136
- });
225
+ const result = familyEntry
226
+ ? await familyEntry.review({
227
+ promptText: assembled.promptText,
228
+ timeoutMs: Number.isFinite(timeoutMs) ? timeoutMs : mod.REVIEW_TIMEOUT_MS,
229
+ detectionOverride: detection,
230
+ })
231
+ : await mod.runCrossModelReview({
232
+ assembled,
233
+ ...(Number.isFinite(timeoutMs) ? { timeoutMs } : {}),
234
+ });
137
235
 
138
236
  // Surface truncation in the emitted result so the skill/report can note it.
139
237
  process.stdout.write(JSON.stringify({ ...result, promptTruncated: assembled.truncated }) + '\n');
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "./builtin-manifest.schema.json",
3
3
  "schemaVersion": 1,
4
- "generatedAt": "2026-06-10T23:23:57.878Z",
5
- "instarVersion": "1.3.483",
4
+ "generatedAt": "2026-06-11T00:03:52.959Z",
5
+ "instarVersion": "1.3.484",
6
6
  "entryCount": 201,
7
7
  "entries": {
8
8
  "hook:session-start": {
@@ -0,0 +1,37 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: minor -->
5
+
6
+ ## What Changed
7
+
8
+ Implements Piece 3 (final piece) of `docs/specs/AUTONOMY-PRINCIPLES-ENFORCEMENT-SPEC.md`. The spec-converge skill's external (non-Claude) review pass becomes mandatory with teeth, dynamic, and safe:
9
+
10
+ - **gemini-cli joins the reviewer registry** (`src/core/crossModelReviewer.ts`) — the registry seam's first extension beyond codex: never-throws detection (binary + cached OAuth at the path the CLI actually reads), provider via the existing factory with its own circuit breaker, identical degraded semantics.
11
+ - **Family-diverse**: one external pass per AVAILABLE family (detect-all), not first-match-only.
12
+ - **Delta-gated**: a content hash of the spec's reviewable body (frontmatter-stripped) decides when externals must re-run — round 1 and any changed round; unchanged rounds record a skip-with-logged-note instead of burning external quota.
13
+ - **Durable activation baseline**: framework availability observations are recorded to `state/framework-activation-history.jsonl`; externals are non-skippable whenever a non-Claude framework was active within a 7-day lookback — deactivating a framework just before converging no longer exempts a spec.
14
+ - **Trusted-provider allowlist**: only first-party OAuth CLIs (codex-cli, gemini-cli) can receive spec text; pi-cli/custom endpoints are structurally excluded (`untrusted-framework` refusal).
15
+ - **Fail-loud model canary**: a review pass degrades loudly (`model-resolution-canary`) rather than silently running with an unresolved tier-word model.
16
+
17
+ Honest scope notes: the spec's "broken `resolveModelForFramework` foundation" was already fixed on main before this build (recorded at PR #1055); the Claude-only-agent different-family floor + tracked-gap signal are disclosed residuals (see the side-effects artifact).
18
+
19
+ ## What to Tell Your User
20
+
21
+ - "When I review a spec before building, I now get a second opinion from EVERY non-Claude AI family I have access to (GPT via codex, Gemini via the gemini CLI) — automatically, on every round where the spec actually changed. I can't quietly skip it anymore: a record of which frameworks I've had active in the last week keeps the outside-opinion requirement honest."
22
+ - "Your spec text only ever goes to first-party AI providers you've logged into — never to custom or unknown endpoints."
23
+
24
+ ## Summary of New Capabilities
25
+
26
+ | Capability | How to Use |
27
+ |-----------|-----------|
28
+ | Gemini external reviewer | Automatic in spec-converge when the gemini CLI is installed + authed |
29
+ | Family-diverse external pass | Automatic — one pass per available family per changed round |
30
+ | Delta-gated externals | Automatic — unchanged rounds log a skip note instead of re-reviewing |
31
+ | 7-day activation baseline | Automatic — recorded on every detection; read at convergence |
32
+
33
+ ## Evidence
34
+
35
+ - 32 new unit tests (`crossModelReviewer-piece3.test.ts`) + 45 existing (`crossModelReviewer.test.ts`) + 3 integration (`cross-model-review-flow.test.ts`) — all green; `tsc` exit 0; full lint clean.
36
+ - Live smoke on the dev machine: detect-all reported codex-cli:gpt-5.5 AND gemini-cli:gemini-2.5-pro; `--family pi-cli` refused with `untrusted-framework`; the activation observation landed in the JSONL.
37
+ - Independent second-pass review verified the egress allowlist end-to-end and caught a real bug (a `GEMINI_HOME` env var the CLI doesn't actually honor) — fixed before ship.
@@ -0,0 +1,93 @@
1
+ # Side-Effects Review — Cross-Model Convergence Hardening (Autonomy Principles Enforcement, Piece 3)
2
+
3
+ **Version / slug:** `cross-model-hardening`
4
+ **Date:** `2026-06-10`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `independent reviewer subagent (see appended verdict)`
7
+
8
+ ## Summary of the change
9
+
10
+ Implements Piece 3 of `docs/specs/AUTONOMY-PRINCIPLES-ENFORCEMENT-SPEC.md`: cross-model convergence becomes **mandatory (with a durable activation baseline), dynamic (no pinning), family-diverse, delta-gated, allowlist-constrained, and fail-loud**. Honest scope note: the spec's headline "broken foundation" claim (`resolveModelForFramework` returning a dead tier string for gemini/pi) was **already fixed on main** before this build — recorded at PR #1055; this PR implements everything else.
11
+
12
+ - **gemini-cli reviewer registry entry** (`src/core/crossModelReviewer.ts`) — the registry seam's first extension beyond codex: injectable never-throws detection (binary + cached OAuth creds), provider via the existing factory (own circuit breaker), identical degraded semantics.
13
+ - **Family-diverse collection** — `detectAllCrossModelReviewers()` returns ALL available frameworks; the skill now runs one external pass per available family instead of first-match-only.
14
+ - **Delta-gating** — `hashSpecReviewableBody()` (sha256, frontmatter-stripped, CRLF-normalized); externals are mandatory on round 1 + any round where the reviewable body changed; an unchanged round records a skip-with-logged-note (≠ skipped-abbreviated).
15
+ - **Durable activation baseline** — `recordFrameworkActivationObservation()` / `wasNonClaudeFrameworkActiveWithin()` (JSONL at `state/framework-activation-history.jsonl`, 2000-line cap): externals are non-skippable whenever a non-Claude framework was active at any point in a 7-day lookback — a just-before-converge deactivation no longer exempts a spec (round-2 adversarial F-R2-3).
16
+ - **Trusted-provider allowlist** — `TRUSTED_REVIEWER_FRAMEWORKS = ['codex-cli','gemini-cli']`; the registry constructively carries only first-party OAuth CLIs; `--family pi-cli` (or any unlisted id) is refused (`untrusted-framework`) so the full spec text is never sent to a custom/base-URL endpoint.
17
+ - **Fail-loud canary** — `isConcreteReviewerModel()`: both entries degrade LOUDLY (`model-resolution-canary`) rather than silently reviewing with a bare tier word.
18
+
19
+ Files: `src/core/crossModelReviewer.ts`, `skills/spec-converge/scripts/cross-model-review.mjs`, `skills/spec-converge/SKILL.md`, `tests/unit/crossModelReviewer-piece3.test.ts` (new, 32 tests), hermeticity fixes in 2 existing test files.
20
+
21
+ ## Decision-point inventory
22
+
23
+ - Cross-model framework detection/selection — **modify** — first-match → all-available (collection only; no blocking authority).
24
+ - `--family` allowlist guard — **add** — hard-invariant refusal of an untrusted framework id at the script edge (egress protection, enumerable set).
25
+ - Externals-mandatory check (SKILL.md + `wasNonClaudeFrameworkActiveWithin`) — **add** — a deterministic read over the durable history that decides whether the SKILL FLOW may skip an external pass. Process-gating inside spec review; blocks no agent action or message.
26
+ - Model canary — **add** — degrades a review pass; blocks nothing.
27
+
28
+ ---
29
+
30
+ ## 1. Over-block
31
+
32
+ The allowlist refusing `pi-cli` could be seen as over-blocking a legitimate reviewer — deliberate: pi is multi-provider by design (its model flag may resolve to a custom endpoint), and the cost of a wrongly-allowed egress (full spec text to an attacker-controlled model) dwarfs the cost of one fewer reviewer family. The activation lookback could keep externals mandatory for an agent that genuinely uninstalled a framework yesterday — accepted: the 7-day tail is the entire point (anti-gaming), and the pass degrades to advisory-unavailable rather than hard-failing when the framework is truly gone.
33
+
34
+ ## 2. Under-block
35
+
36
+ The activation history only records when `--detect-only`/review runs execute — an agent that NEVER ran spec-converge in the lookback has an empty history and presents as single-framework. Acceptable: the first detect of the current convergence records the observation, so the gaming window is "deactivate before the FIRST round" — and a genuinely deactivated-everywhere agent degrades to the advisory floor exactly as specced. The history is also local-file mutable by the agent itself (not tamper-proof) — consistent with every other instar state file; the report banner + frontmatter flag remain the human-visible disclosure.
37
+
38
+ ## 3. Level-of-abstraction fit
39
+
40
+ Correct: detection/selection/hash/history are cheap structural helpers in the existing crossModelReviewer module (the registry's documented extension point); the SKILL owns the flow policy; nothing re-implements the provider factory, circuit breaker, or aggregation (`aggregateRoundOutcomes` unchanged and still computes the spec-level flag).
41
+
42
+ ## 4. Signal vs authority compliance
43
+
44
+ **Required reference:** docs/signal-vs-authority.md
45
+
46
+ - [x] No — no block/allow surface over agent behavior or messages. The two refusal points (allowlist, canary) are **hard-invariant validation** over enumerable sets (the principle's explicitly-allowed class — egress protection is the "safety guards on irreversible actions" case). Review outcomes only ever DEGRADE with logged reasons; judgment stays with the reviewers and the convergence process.
47
+
48
+ ## 5. Interactions
49
+
50
+ - **Back-compat:** `detectCrossModelReviewer` (first-match) and the script's default single-pass mode are unchanged; existing callers/tests pass (hermeticity fixes only — the suite previously assumed gemini absent, false on hosts with gemini installed).
51
+ - **Aggregation:** per-family results feed the existing per-round → spec-level aggregation unchanged; a delta-skip is recorded as a logged note, not a round outcome, so `degraded-all-rounds` semantics are preserved.
52
+ - **Double-fire/races:** the activation JSONL is append-with-cap from a single skill flow; worst case under concurrent convergences is a lost observation line (history is a union-over-time read, so this cannot flip mandatory→optional within the lookback).
53
+ - **Circuit breakers:** each framework keeps its own breaker via the factory — a rate-limited codex degrades that pass; gemini still runs (the family-diversity goal).
54
+
55
+ ## 6. External surfaces
56
+
57
+ - **LLM egress:** spec text now also flows to gemini (first-party Google OAuth CLI) when available — the same egress class as the existing codex pass, now explicitly allowlist-bounded. No new third-party endpoints; pi/custom endpoints structurally excluded.
58
+ - **Persistent state:** `state/framework-activation-history.jsonl` (capped). No fleet surface: spec-converge remains agent-private (decision recorded in the Piece-2 artifact); no `src/` runtime route/config change — `crossModelReviewer.ts` is library code consumed by the skill script.
59
+
60
+ ## 7. Rollback cost
61
+
62
+ Revert the commit. The history file is inert if orphaned. No migration, no API, no fleet propagation.
63
+
64
+ ## Conclusion
65
+
66
+ Piece 3 closes the spec: externals can no longer be quietly skipped (durable 7-day baseline + delta-gating with logged notes), selection is dynamic and family-diverse with zero pinned model names, and the two real security findings from convergence (spec egress to untrusted endpoints; silent dead-model reviews) are structurally closed (allowlist + canary). Verified: tsc clean, full lint clean, 77 unit (45 existing + 32 new) + 3 integration green, live smoke on this host detected both codex + gemini and refused pi-cli. Clear to ship as the final PR of the spec.
67
+
68
+ ---
69
+
70
+ ## Scope disclosure (honest residual)
71
+
72
+ Two spec clauses are NOT implemented in this PR and are tracked, not orphaned <!-- tracked: CMT-1317 -->: (a) the Claude-only-agent floor reaching a *different-family* model via the subscription-path/provider-registry fallback — a single-framework agent currently gets the honest advisory `unavailable` flag (the pre-existing behavior, loudly disclosed in the report banner), and (b) surfacing "no external family reachable at all" as a HumanAsDetector-style tracked-gap signal rather than the advisory note. Both need provider-registry plumbing that doesn't belong in this hardening pass.
73
+
74
+ ## Second-pass review
75
+
76
+ **Reviewer:** independent reviewer subagent (verified findings against the actually-installed gemini CLI v0.25.2).
77
+ **Independent read of the artifact: concern raised → all resolved this pass.**
78
+
79
+ - MUST-FIX (resolved): `GEMINI_HOME` is not a real gemini CLI env var (zero occurrences in the CLI dist; creds are unconditionally `~/.gemini/oauth_creds.json`). Honoring it made detection probe a path the CLI never reads — a false-unavailable would silently skip the gemini pass AND poison the activation baseline with `gemini-cli:false`, the exact suppression Piece 3 prevents. Fixed: env lookup dropped; injectable test seam kept.
80
+ - NICE-TO-HAVE (applied): frontmatter-strip close anchor tightened to a whole-line fence (`\n---(\n|$)`) so `--- text`/`----` inside the block can't terminate the strip mid-line.
81
+ - INFORMATIONAL (applied anyway): `wasNonClaudeFrameworkActiveWithin` now counts only TRUSTED reviewer framework ids, so a stray `{"claude-code":true}` line can't flip the externals-mandatory decision.
82
+ - HONESTY (applied): the scope disclosure above was added at the reviewer's prompting — the artifact previously implied full Piece-3 coverage.
83
+ - Confirmed clean: `--family` allowlist guard sits before any detect/provider call; no path (default, detect-all, or detectionOverride) can route spec text to a non-registry framework — the registry⊆allowlist invariant is itself unit-tested; `buildIntelligenceProvider({framework:'gemini-cli'})` cannot reach a custom base-URL (allowlisted child env); refresh-token-only IS authed for this CLI; the canary precedes provider construction in both entries; the 2000-line cap keeps the most recent lines; the reader never throws on corruption; the existing-test edits weaken no assertion.
84
+
85
+ After fixes: tsc exit 0, 77/77 unit + 3/3 integration green.
86
+
87
+ ---
88
+
89
+ ## Evidence pointers
90
+
91
+ - `tests/unit/crossModelReviewer-piece3.test.ts` (32): gemini detect triad, detect-all cardinality, canary accept/reject, hash frontmatter/CRLF stability, activation write/read/lookback/corrupt-line/cap, allowlist, gemini degraded paths.
92
+ - Live smoke: `--detect-only --state-dir` → codex-cli:gpt-5.5 + gemini-cli:gemini-2.5-pro both detected + observation written; `--family pi-cli` → `untrusted-framework`; `--hash-only` → stable hash.
93
+ - `npx tsc --noEmit` exit 0; `npm run lint` exit 0.