@hobin/developer 0.1.8 → 0.1.10

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.
Files changed (66) hide show
  1. package/README.md +215 -372
  2. package/REFERENCE_ROUTING.md +243 -0
  3. package/extensions/compaction-language.ts +303 -0
  4. package/extensions/developer.ts +607 -20
  5. package/extensions/machine.ts +45 -0
  6. package/extensions/references/behavior-preserving-structural-change.md +87 -8
  7. package/extensions/skills.ts +330 -52
  8. package/extensions/state.ts +227 -2
  9. package/package.json +9 -3
  10. package/skills/abstraction-review/SKILL.md +37 -23
  11. package/skills/abstraction-review/reference-policy.json +66 -0
  12. package/skills/abstraction-review/references/field-card.md +113 -168
  13. package/skills/abstraction-review/references/repair-table.md +66 -80
  14. package/skills/abstraction-review/references/worked-examples.md +79 -256
  15. package/skills/model/SKILL.md +31 -13
  16. package/skills/model/reference-policy.json +96 -0
  17. package/skills/model/references/contract-and-replacement-models.md +112 -0
  18. package/skills/model/references/logic-query-semantics.md +89 -0
  19. package/skills/model/references/planning-models.md +75 -0
  20. package/skills/model/references/problem-modeling.md +143 -276
  21. package/skills/model/references/proof-obligations.md +71 -0
  22. package/skills/model/references/relational-constraint-models.md +110 -0
  23. package/skills/model/references/solver-result-boundaries.md +83 -0
  24. package/skills/model/references/temporal-behavior-models.md +106 -0
  25. package/skills/naming-judgment/SKILL.md +17 -4
  26. package/skills/naming-judgment/reference-policy.json +29 -0
  27. package/skills/naming-judgment/references/domain-naming.md +29 -10
  28. package/skills/schedule/SKILL.md +16 -6
  29. package/skills/schedule/reference-policy.json +29 -0
  30. package/skills/schedule/references/structural-change-timing.md +81 -18
  31. package/skills/signal/SKILL.md +17 -6
  32. package/skills/signal/reference-policy.json +29 -0
  33. package/skills/signal/references/structural-movement.md +87 -14
  34. package/skills/sketch/SKILL.md +38 -42
  35. package/skills/sketch/reference-policy.json +212 -0
  36. package/skills/sketch/references/accumulator-invariants.md +125 -0
  37. package/skills/sketch/references/closure-and-conventional-interfaces.md +87 -0
  38. package/skills/sketch/references/composition-by-wishes.md +69 -0
  39. package/skills/sketch/references/data-driven-design.md +99 -22
  40. package/skills/sketch/references/data-shape-template-catalog.md +58 -19
  41. package/skills/sketch/references/design-levels-and-boundaries.md +133 -0
  42. package/skills/sketch/references/earned-abstraction.md +75 -0
  43. package/skills/sketch/references/generative-recursion.md +122 -0
  44. package/skills/sketch/references/generic-dispatch-systems.md +75 -0
  45. package/skills/sketch/references/language-semantics.md +82 -0
  46. package/skills/sketch/references/meaning-preserving-conversions.md +69 -0
  47. package/skills/sketch/references/process-shape-and-resources.md +157 -0
  48. package/skills/sketch/references/representation-barriers.md +73 -0
  49. package/skills/sketch/references/responsibility-and-collaboration.md +108 -0
  50. package/skills/sketch/references/runtime-and-compilation.md +84 -0
  51. package/skills/sketch/references/selection-and-creation.md +76 -0
  52. package/skills/sketch/references/state-history-and-order.md +126 -0
  53. package/skills/sketch/references/type-transitions.md +54 -0
  54. package/skills/sketch/references/variation-roles.md +59 -0
  55. package/skills/verify/SKILL.md +17 -6
  56. package/skills/verify/reference-policy.json +30 -0
  57. package/skills/verify/references/verifier-selection-and-pass-but-wrong.md +152 -192
  58. package/SOURCES.md +0 -104
  59. package/skills/abstraction-review/references/recipe-cards.md +0 -322
  60. package/skills/model/references/worked-models-and-specialized-techniques.md +0 -218
  61. package/skills/sketch/references/abstraction-barriers-and-closure.md +0 -160
  62. package/skills/sketch/references/abstraction-composition-and-state.md +0 -184
  63. package/skills/sketch/references/composition-generative-recursion-and-accumulators.md +0 -196
  64. package/skills/sketch/references/generic-operations-and-languages.md +0 -134
  65. package/skills/sketch/references/processes-state-and-time.md +0 -171
  66. package/skills/sketch/references/responsibility-and-variation.md +0 -245
@@ -16,6 +16,7 @@ export const PROTOCOL = "developer/v5" as const;
16
16
  export const ACTIVATION_ENTRY = "developer.activation" as const;
17
17
  export const FOCUS_ENTRY = "developer.question-focus" as const;
18
18
  export const ROUTE_TOOL = "developer_route_question" as const;
19
+ export const REFERENCE_TOOL = "developer_load_reference" as const;
19
20
  export const JUDGMENT_TOOL = "developer_record_judgment" as const;
20
21
  export const MAX_RESPONSE_FIELDS = 20;
21
22
  export const MAX_RESPONSE_OPTIONS = 20;
@@ -69,6 +70,38 @@ export interface RouteAlternative {
69
70
  reason: string;
70
71
  }
71
72
 
73
+ export interface ReferencePolicyRoute {
74
+ id: string;
75
+ question: string;
76
+ trigger: string;
77
+ methodStep: string;
78
+ references: string[];
79
+ readOrder: "any" | "listed";
80
+ artifacts: string[];
81
+ stop: string;
82
+ separateWhen: string;
83
+ }
84
+
85
+ export interface ReferencePolicyExemption {
86
+ when: string;
87
+ evidence: string[];
88
+ }
89
+
90
+ export interface ReferenceLoad {
91
+ path: string;
92
+ reason: string;
93
+ contentSha256: string;
94
+ sourceTrace: string;
95
+ referenceRouteIds: string[];
96
+ }
97
+
98
+ export interface ReferenceLoadEvent extends ReferenceLoad {
99
+ protocol: typeof PROTOCOL;
100
+ kind: "reference-load";
101
+ routeId: string;
102
+ target: string;
103
+ }
104
+
72
105
  export interface RouteEvent {
73
106
  protocol: typeof PROTOCOL;
74
107
  kind: "route";
@@ -78,6 +111,11 @@ export interface RouteEvent {
78
111
  reason: string;
79
112
  knownEvidence: string[];
80
113
  consideredAlternatives: RouteAlternative[];
114
+ availableReferences: string[];
115
+ referenceRoutes: ReferencePolicyRoute[];
116
+ referenceExemptionCriteria?: ReferencePolicyExemption;
117
+ referencePolicySha256?: string;
118
+ loadedReferences: ReferenceLoad[];
81
119
  targetQuestionId?: string;
82
120
  methodLocation?: string;
83
121
  executionProfile?: ImplementationProfile;
@@ -122,6 +160,17 @@ export interface QuestionUpdate {
122
160
  basis: string[];
123
161
  }
124
162
 
163
+ export interface ReferenceBasis extends ReferenceLoad {
164
+ trigger: string;
165
+ appliedRule: string;
166
+ artifact: string;
167
+ }
168
+
169
+ export interface ReferenceExemption {
170
+ reason: string;
171
+ evidence: string[];
172
+ }
173
+
125
174
  export interface JudgmentEvent {
126
175
  protocol: typeof PROTOCOL;
127
176
  kind: "judgment";
@@ -131,6 +180,8 @@ export interface JudgmentEvent {
131
180
  status: JudgmentStatus;
132
181
  result: string;
133
182
  basis: string[];
183
+ referenceBasis: ReferenceBasis[];
184
+ referenceExemption?: ReferenceExemption;
134
185
  openedQuestions: PendingQuestion[];
135
186
  questionUpdates: QuestionUpdate[];
136
187
  artifacts: string[];
@@ -141,6 +192,7 @@ export type DeveloperEvent =
141
192
  | ActivationEvent
142
193
  | FocusEvent
143
194
  | RouteEvent
195
+ | ReferenceLoadEvent
144
196
  | JudgmentEvent;
145
197
 
146
198
  export interface DeveloperState {
@@ -240,6 +292,118 @@ function parseRouteAlternative(value: unknown): RouteAlternative | undefined {
240
292
  return { target: value.target, reason: value.reason };
241
293
  }
242
294
 
295
+ function parseReferencePolicyRoute(
296
+ value: unknown,
297
+ ): ReferencePolicyRoute | undefined {
298
+ if (
299
+ !isObject(value) ||
300
+ typeof value.id !== "string" ||
301
+ typeof value.trigger !== "string" ||
302
+ !isStringArray(value.references) ||
303
+ (value.readOrder !== undefined &&
304
+ value.readOrder !== "any" &&
305
+ value.readOrder !== "listed") ||
306
+ !isStringArray(value.artifacts) ||
307
+ (value.question !== undefined && typeof value.question !== "string") ||
308
+ (value.methodStep !== undefined && typeof value.methodStep !== "string") ||
309
+ (value.stop !== undefined && typeof value.stop !== "string") ||
310
+ (value.separateWhen !== undefined && typeof value.separateWhen !== "string")
311
+ ) {
312
+ return undefined;
313
+ }
314
+ return {
315
+ id: value.id,
316
+ question:
317
+ typeof value.question === "string" ? value.question : value.trigger,
318
+ trigger: value.trigger,
319
+ methodStep:
320
+ typeof value.methodStep === "string"
321
+ ? value.methodStep
322
+ : "legacy route without a recorded integration step",
323
+ references: value.references,
324
+ readOrder: value.readOrder === "listed" ? "listed" : "any",
325
+ artifacts: value.artifacts,
326
+ stop:
327
+ typeof value.stop === "string"
328
+ ? value.stop
329
+ : "legacy route without a recorded stop",
330
+ separateWhen:
331
+ typeof value.separateWhen === "string"
332
+ ? value.separateWhen
333
+ : "re-route against the current policy before extending this judgment",
334
+ };
335
+ }
336
+
337
+ function parseReferencePolicyExemption(
338
+ value: unknown,
339
+ ): ReferencePolicyExemption | undefined {
340
+ if (
341
+ !isObject(value) ||
342
+ typeof value.when !== "string" ||
343
+ !isStringArray(value.evidence)
344
+ ) {
345
+ return undefined;
346
+ }
347
+ return { when: value.when, evidence: value.evidence };
348
+ }
349
+
350
+ function parseReferenceLoad(value: unknown): ReferenceLoad | undefined {
351
+ if (
352
+ !isObject(value) ||
353
+ typeof value.path !== "string" ||
354
+ typeof value.reason !== "string" ||
355
+ typeof value.contentSha256 !== "string" ||
356
+ typeof value.sourceTrace !== "string"
357
+ ) {
358
+ return undefined;
359
+ }
360
+ if (
361
+ value.referenceRouteIds !== undefined &&
362
+ !isStringArray(value.referenceRouteIds)
363
+ ) {
364
+ return undefined;
365
+ }
366
+ return {
367
+ path: value.path,
368
+ reason: value.reason,
369
+ contentSha256: value.contentSha256,
370
+ sourceTrace: value.sourceTrace,
371
+ referenceRouteIds: value.referenceRouteIds ?? [],
372
+ };
373
+ }
374
+
375
+ function parseReferenceBasis(value: unknown): ReferenceBasis | undefined {
376
+ const load = parseReferenceLoad(value);
377
+ if (
378
+ !load ||
379
+ !isObject(value) ||
380
+ typeof value.trigger !== "string" ||
381
+ typeof value.appliedRule !== "string" ||
382
+ typeof value.artifact !== "string"
383
+ ) {
384
+ return undefined;
385
+ }
386
+ return {
387
+ ...load,
388
+ trigger: value.trigger,
389
+ appliedRule: value.appliedRule,
390
+ artifact: value.artifact,
391
+ };
392
+ }
393
+
394
+ function parseReferenceExemption(
395
+ value: unknown,
396
+ ): ReferenceExemption | undefined {
397
+ if (
398
+ !isObject(value) ||
399
+ typeof value.reason !== "string" ||
400
+ !isStringArray(value.evidence)
401
+ ) {
402
+ return undefined;
403
+ }
404
+ return { reason: value.reason, evidence: value.evidence };
405
+ }
406
+
243
407
  function isQuestionResolutionOwner(
244
408
  value: unknown,
245
409
  ): value is QuestionResolutionOwner {
@@ -437,6 +601,16 @@ export function normalizeDeveloperEvent(
437
601
  !isStringArray(value.knownEvidence) ||
438
602
  (value.consideredAlternatives !== undefined &&
439
603
  !Array.isArray(value.consideredAlternatives)) ||
604
+ (value.availableReferences !== undefined &&
605
+ !isStringArray(value.availableReferences)) ||
606
+ (value.referenceRoutes !== undefined &&
607
+ !Array.isArray(value.referenceRoutes)) ||
608
+ (value.referenceExemptionCriteria !== undefined &&
609
+ !parseReferencePolicyExemption(value.referenceExemptionCriteria)) ||
610
+ (value.referencePolicySha256 !== undefined &&
611
+ typeof value.referencePolicySha256 !== "string") ||
612
+ (value.loadedReferences !== undefined &&
613
+ !Array.isArray(value.loadedReferences)) ||
440
614
  (value.targetQuestionId !== undefined &&
441
615
  typeof value.targetQuestionId !== "string") ||
442
616
  (value.methodLocation !== undefined &&
@@ -453,6 +627,14 @@ export function normalizeDeveloperEvent(
453
627
  : [];
454
628
  if (consideredAlternatives.some((alternative) => !alternative))
455
629
  return undefined;
630
+ const referenceRoutes = Array.isArray(value.referenceRoutes)
631
+ ? value.referenceRoutes.map(parseReferencePolicyRoute)
632
+ : [];
633
+ if (referenceRoutes.some((route) => !route)) return undefined;
634
+ const loadedReferences = Array.isArray(value.loadedReferences)
635
+ ? value.loadedReferences.map(parseReferenceLoad)
636
+ : [];
637
+ if (loadedReferences.some((reference) => !reference)) return undefined;
456
638
  return {
457
639
  protocol: PROTOCOL,
458
640
  kind: "route",
@@ -462,6 +644,14 @@ export function normalizeDeveloperEvent(
462
644
  reason: value.reason,
463
645
  knownEvidence: value.knownEvidence,
464
646
  consideredAlternatives: consideredAlternatives as RouteAlternative[],
647
+ availableReferences: value.availableReferences ?? [],
648
+ referenceRoutes: referenceRoutes as ReferencePolicyRoute[],
649
+ referenceExemptionCriteria:
650
+ value.referenceExemptionCriteria === undefined
651
+ ? undefined
652
+ : parseReferencePolicyExemption(value.referenceExemptionCriteria),
653
+ referencePolicySha256: value.referencePolicySha256,
654
+ loadedReferences: loadedReferences as ReferenceLoad[],
465
655
  targetQuestionId: value.targetQuestionId,
466
656
  methodLocation: value.methodLocation,
467
657
  executionProfile: value.executionProfile,
@@ -472,6 +662,24 @@ export function normalizeDeveloperEvent(
472
662
  };
473
663
  }
474
664
 
665
+ if (value.kind === "reference-load") {
666
+ const reference = parseReferenceLoad(value);
667
+ if (
668
+ !reference ||
669
+ typeof value.routeId !== "string" ||
670
+ typeof value.target !== "string"
671
+ ) {
672
+ return undefined;
673
+ }
674
+ return {
675
+ protocol: PROTOCOL,
676
+ kind: "reference-load",
677
+ routeId: value.routeId,
678
+ target: value.target,
679
+ ...reference,
680
+ };
681
+ }
682
+
475
683
  if (value.kind !== "judgment") return undefined;
476
684
  if (
477
685
  typeof value.routeId !== "string" ||
@@ -481,13 +689,21 @@ export function normalizeDeveloperEvent(
481
689
  typeof value.result !== "string" ||
482
690
  !isStringArray(value.basis) ||
483
691
  !isStringArray(value.artifacts) ||
484
- !Array.isArray(value.openedQuestions)
692
+ !Array.isArray(value.openedQuestions) ||
693
+ (value.referenceBasis !== undefined &&
694
+ !Array.isArray(value.referenceBasis)) ||
695
+ (value.referenceExemption !== undefined &&
696
+ !parseReferenceExemption(value.referenceExemption))
485
697
  ) {
486
698
  return undefined;
487
699
  }
488
700
 
489
701
  const openedQuestions = value.openedQuestions.map(parsePendingQuestion);
490
702
  if (openedQuestions.some((question) => !question)) return undefined;
703
+ const referenceBasis = Array.isArray(value.referenceBasis)
704
+ ? value.referenceBasis.map(parseReferenceBasis)
705
+ : [];
706
+ if (referenceBasis.some((basis) => !basis)) return undefined;
491
707
  if (
492
708
  value.questionUpdates !== undefined &&
493
709
  !Array.isArray(value.questionUpdates)
@@ -506,6 +722,11 @@ export function normalizeDeveloperEvent(
506
722
  status: value.status,
507
723
  result: value.result,
508
724
  basis: value.basis,
725
+ referenceBasis: referenceBasis as ReferenceBasis[],
726
+ referenceExemption:
727
+ value.referenceExemption === undefined
728
+ ? undefined
729
+ : parseReferenceExemption(value.referenceExemption),
509
730
  openedQuestions: openedQuestions as PendingQuestion[],
510
731
  questionUpdates: questionUpdates as QuestionUpdate[],
511
732
  artifacts: value.artifacts,
@@ -523,7 +744,11 @@ interface BranchEntryLike {
523
744
  message?: { role?: string; toolName?: string; details?: unknown };
524
745
  }
525
746
 
526
- const DEVELOPER_TOOL_NAMES = new Set<string>([ROUTE_TOOL, JUDGMENT_TOOL]);
747
+ const DEVELOPER_TOOL_NAMES = new Set<string>([
748
+ ROUTE_TOOL,
749
+ REFERENCE_TOOL,
750
+ JUDGMENT_TOOL,
751
+ ]);
527
752
 
528
753
  export function eventFromBranchEntry(
529
754
  entry: BranchEntryLike,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hobin/developer",
3
- "version": "0.1.8",
4
- "description": "Adaptive product-development reasoning and evidence for Pi.",
3
+ "version": "0.1.10",
4
+ "description": "Branch-aware judgment routing, evidence gates, and focused development skills for Pi.",
5
5
  "type": "module",
6
6
  "keywords": ["pi-package", "pi", "developer", "skills"],
7
7
  "license": "MIT",
@@ -21,7 +21,13 @@
21
21
  "publishConfig": {
22
22
  "access": "public"
23
23
  },
24
- "files": ["extensions", "skills", "README.md", "SOURCES.md", "LICENSE"],
24
+ "files": [
25
+ "extensions",
26
+ "skills",
27
+ "README.md",
28
+ "REFERENCE_ROUTING.md",
29
+ "LICENSE"
30
+ ],
25
31
  "engines": {
26
32
  "node": ">=22.19.0"
27
33
  },
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: abstraction-review
3
- description: "Judge whether a concrete wished interface, helper, API, workflow rule, boundary, or structural candidate is stable enough to keep, revise, split, reject, or defer. Use when a concrete candidate and the pressure behind it can be inspected, including when its contract or evidence may be incomplete."
3
+ description: "Judge whether an already-shaped wished interface, helper, API, workflow rule, boundary, or structural candidate is stable enough to keep, revise, split, reject, or defer. Use when concrete caller-facing shape and pressure can be inspected, even if evidence is incomplete. A desired representation or requested property list without an interface shape belongs to sketch, not abstraction review."
4
4
  ---
5
5
 
6
6
  # Abstraction Review
@@ -12,6 +12,19 @@ Decide whether a concrete abstraction candidate is safe to rely on.
12
12
  Is this candidate stable enough to keep, or should it be revised, split,
13
13
  rejected, or deferred?
14
14
 
15
+ ## Judgment Spine
16
+
17
+ ```text
18
+ existing candidate + current pressure
19
+ -> caller-visible promise and hidden detail
20
+ -> smallest plausible counterexample
21
+ -> observable stop and evidence
22
+ -> keep | revise-surface | revise-model | split | reject | defer
23
+ ```
24
+
25
+ Review only promises the candidate already makes. When operations, ownership, or
26
+ rules still need to be invented, hand off instead of constructing them here.
27
+
15
28
  ## Inputs
16
29
 
17
30
  - Concrete candidate and the pressure it should remove
@@ -41,13 +54,9 @@ routing to the caller.
41
54
 
42
55
  ## Completion
43
56
 
44
- Finish when the candidate can satisfy this sentence or is rejected/deferred for
45
- failing it:
46
-
47
- ```text
48
- Given <input artifact>, derive <output artifact> by <rule>, then check
49
- <observable stop>. If it fails, repair the named layer or contract.
50
- ```
57
+ Finish when each declared candidate promise is supported, contradicted, or left
58
+ as an explicit gap, and one observable stop can fail the candidate. A failed stop
59
+ produces a decision and owning-skill handoff, not an in-leaf redesign.
51
60
 
52
61
  Revisit when new callers, cases, implementation evidence, or failures change
53
62
  the contract or stop check.
@@ -57,13 +66,16 @@ the contract or stop check.
57
66
  1. Identify the candidate, its source, and confidence.
58
67
  2. State the pressure it is supposed to remove. Bias toward `reject` or `defer`
59
68
  when no pressure is visible.
60
- 3. Review pre-implementation intent or post-implementation evidence explicitly.
61
- 4. Choose the tested layer: Language, Unit, Law, Boundary, Engine, Time, or Run.
62
- 5. State the contract in caller language and the detail callers may ignore.
63
- 6. Name the reusable output artifact left by the review.
64
- 7. Define an observable stop check using cases, properties, tests, diffs,
65
- behavior, traces, or command output.
66
- 8. Decide without converting missing evidence into polished approval.
69
+ 3. State the contract in caller language, its relevant observers, and the detail
70
+ callers may ignore.
71
+ 4. Name only the promises the candidate makes: representation, responsibility,
72
+ substitution, closure, extension, process, state, or stable sense.
73
+ 5. Construct the smallest plausible counterexample to one promise.
74
+ 6. Define an observable stop using cases, properties, tests, diffs, traces, cost,
75
+ or command output.
76
+ 7. Decide and name the owning handoff for any missing model, design, timing,
77
+ naming, or verification artifact.
78
+ 8. Do not convert missing evidence into polished approval or a shadow design.
67
79
 
68
80
  ## Missing Evidence
69
81
 
@@ -75,14 +87,16 @@ human-owned.
75
87
  ## Boundary
76
88
 
77
89
  Do not discover structural movement, create the original design surface, decide
78
- timing, implement the change, or perform final completion review.
90
+ timing, implement the change, or perform final completion review. A desire such
91
+ as “replace this array with an object” is pressure, not yet a reviewable
92
+ abstraction, when public operations, caller shape, ownership, and hidden detail
93
+ still have to be invented; route that work to `sketch`.
79
94
 
80
95
  ## Reference Routing
81
96
 
82
- - Read [the field card](references/field-card.md) for substantial or auditable
83
- reviews.
84
- - Read [the recipe cards](references/recipe-cards.md) when the candidate needs a construction or
85
- repair rule.
86
- - Read [the repair table](references/repair-table.md) when a stop check fails.
87
- - Read [the worked examples](references/worked-examples.md) for concrete
88
- calibration.
97
+ The machine-readable [reference policy](reference-policy.json) is the routing
98
+ authority. Each route answers one narrower review question, identifies the exact
99
+ judgment step it refines, names its artifacts and stop, and states when to
100
+ separate or hand off. Select only routes that deepen this candidate judgment;
101
+ never use a review reference to recreate another skill's construction method.
102
+ Use the exemption only when no route trigger applies and cite its evidence.
@@ -0,0 +1,66 @@
1
+ {
2
+ "version": 2,
3
+ "routes": [
4
+ {
5
+ "id": "candidate-contract-review",
6
+ "question": "Does this already-shaped candidate make a truthful, evidence-backed promise to its callers?",
7
+ "trigger": "A concrete caller-facing interface, helper, boundary, role, or workflow candidate exists and needs an auditable keep, revise, split, reject, or defer decision.",
8
+ "method_step": "evaluate the candidate contract, hidden detail, owner, counterexample, and observable stop after confirming that the surface already exists",
9
+ "references": [
10
+ "references/field-card.md"
11
+ ],
12
+ "artifacts": [
13
+ "a completed candidate field card",
14
+ "one explicit promise and plausible counterexample",
15
+ "an observable stop check and bounded decision"
16
+ ],
17
+ "stop": "The candidate's declared promises are supported, contradicted, or left as explicit evidence gaps without constructing a missing surface.",
18
+ "separate_when": "No concrete caller-facing surface exists, product rules are unresolved, only structural movement is visible, timing is the question, or completion evidence is the question; hand off to sketch, model, signal, schedule, naming-judgment, or verify."
19
+ },
20
+ {
21
+ "id": "failed-candidate-check",
22
+ "question": "Which candidate promise failed, and which skill owns the missing repair artifact?",
23
+ "trigger": "An observable candidate stop check failed or current evidence directly contradicts one of the candidate's promises.",
24
+ "method_step": "localize the earliest broken promise after the field-card review, then choose one revision class and handoff",
25
+ "read_order": "listed",
26
+ "references": [
27
+ "references/field-card.md",
28
+ "references/repair-table.md"
29
+ ],
30
+ "artifacts": [
31
+ "the reviewed candidate field card",
32
+ "a failure log naming the contradicted promise and observation",
33
+ "one revision class and owning-skill handoff"
34
+ ],
35
+ "stop": "The failed stop is localized to one promise and the same check can be rerun after the owning skill produces a revised candidate.",
36
+ "separate_when": "Repair requires inventing operations, settling policy, changing implementation, or gathering completion evidence; do not perform that work inside abstraction review."
37
+ },
38
+ {
39
+ "id": "candidate-calibration",
40
+ "question": "Which known promise-and-falsifier shape best calibrates an otherwise complete but ambiguous candidate review?",
41
+ "trigger": "The field card is complete, but keep versus revise, split, reject, or defer remains ambiguous and a matching candidate-promise example can resolve the interpretation.",
42
+ "method_step": "calibrate the completed review by promise and falsifier, never by superficial API resemblance",
43
+ "read_order": "listed",
44
+ "references": [
45
+ "references/field-card.md",
46
+ "references/worked-examples.md"
47
+ ],
48
+ "artifacts": [
49
+ "the reviewed candidate field card",
50
+ "the selected calibration's matching promise and counterexample",
51
+ "a case-calibrated decision with an open consequence"
52
+ ],
53
+ "stop": "One calibration changes or confirms the decision for a stated reason; unmatched examples do not expand the candidate.",
54
+ "separate_when": "No calibration shares the candidate's promise and falsifier; use the field card directly or hand off instead of extending the example catalog."
55
+ }
56
+ ],
57
+ "exemption": {
58
+ "when": "The candidate is small and concrete, and the SKILL.md judgment spine already exposes its pressure, caller promise, hidden detail, counterexample, stop check, decision, and handoff without an audit, failure-localization, or calibration gap.",
59
+ "evidence": [
60
+ "the exact existing candidate surface",
61
+ "the current pressure and caller-visible promise",
62
+ "the falsifying case and observable stop",
63
+ "why no routed review extension adds a missing distinction"
64
+ ]
65
+ }
66
+ }