@sublang/slc 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -157,11 +157,11 @@ either, per key.
157
157
  ```yaml
158
158
  # slc.config.yaml
159
159
  agent: claude-code # claude-code | codex | gemini | opencode
160
- model: claude-opus-4-8 # optional; omit to use the agent CLI's default
160
+ model: claude-opus-5-5 # optional; omit to use the agent CLI's default
161
161
  effort: high # optional adapter-scoped reasoning effort
162
162
  fastMode: true # optional adapter-scoped fast mode; false is a literal request
163
163
  reviewerAgent: codex # optional; enables reviewed compilation
164
- reviewerModel: gpt-5.3-codex # optional reviewer model
164
+ reviewerModel: gpt-6-sol # optional reviewer model
165
165
  reviewerEffort: xhigh # optional reviewer reasoning effort
166
166
  reviewerFastMode: true # optional reviewer fast mode
167
167
  stallTimeout: 2400 # seconds of agent silence before a stalled call fails
@@ -3,14 +3,14 @@
3
3
  # SLC_REVIEWER_* variables, plus SLC_STALL_TIMEOUT, override these per key
4
4
  # (DR-006, DR-022).
5
5
  agent: claude-code
6
- # model: claude-opus-4-8
6
+ # model: claude-opus-5-5
7
7
  # effort: high
8
8
  # Fast mode is a literal request (true or false) where the agent CLI supports
9
9
  # it; omit it to keep the agent CLI's default.
10
10
  # fastMode: true
11
11
  # Optional independent review/fix loop; disabled until reviewerAgent is set.
12
12
  # reviewerAgent: codex
13
- # reviewerModel: gpt-5.3-codex
13
+ # reviewerModel: gpt-6-sol
14
14
  # reviewerEffort: xhigh
15
15
  # reviewerFastMode: true
16
16
  # Seconds of agent inactivity before a stalled call fails the run (DR-019);
@@ -13,9 +13,10 @@ interface MachineLike {
13
13
  provide(implementations: {
14
14
  actors: Record<string, unknown>;
15
15
  }): MachineLike;
16
- /** XState exposes `setup()`-registered guards here. */
16
+ /** XState exposes `setup()`-registered guards and actions here. */
17
17
  implementations?: {
18
18
  guards?: Record<string, unknown>;
19
+ actions?: Record<string, unknown>;
19
20
  };
20
21
  /** XState's resolved state nodes expose the actual invocation actor ids. */
21
22
  root?: ResolvedStateNodeLike;
@@ -1 +1 @@
1
- {"version":3,"file":"verify-coverage.d.ts","sourceRoot":"","sources":["../src/verify-coverage.ts"],"names":[],"mappings":"AA8BA,OAAO,EAgBL,KAAK,iBAAiB,EACvB,MAAM,aAAa,CAAC;AAErB,sEAAsE;AACtE,eAAO,MAAM,aAAa,YAAY,CAAC;AAavC,iFAAiF;AACjF,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,cAGC;CACF;AAyDD,6DAA6D;AAC7D,UAAU,WAAW;IACnB,MAAM,EAAE,iBAAiB,GAAG;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,OAAO,CAAC,eAAe,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,WAAW,CAAC;IAC3E,uDAAuD;IACvD,eAAe,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IACvD,4EAA4E;IAC5E,IAAI,CAAC,EAAE,qBAAqB,CAAC;CAC9B;AAsBD,UAAU,qBAAqB;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAC/C,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjC;AAqJD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,OAAO,GAAG,WAAW,CAwB3D;AAgnCD,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAU/D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,CAAC,GAAG,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,KAAK,OAAO,EAC7D,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,WAAW,GAAE,SAAS,OAAO,EAAO,GACnC,OAAO,CAST;AAg6DD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CA+IjE;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,OAAO,EAClB,IAAI,GAAE;IACJ,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;CACf,GACL,OAAO,CAAC,MAAM,EAAE,CAAC,CAkCnB;AAktBD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,MAAM,CA8BT;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAmBnD"}
1
+ {"version":3,"file":"verify-coverage.d.ts","sourceRoot":"","sources":["../src/verify-coverage.ts"],"names":[],"mappings":"AA8BA,OAAO,EAeL,KAAK,iBAAiB,EACvB,MAAM,aAAa,CAAC;AAErB,sEAAsE;AACtE,eAAO,MAAM,aAAa,YAAY,CAAC;AAavC,iFAAiF;AACjF,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,cAGC;CACF;AAyDD,6DAA6D;AAC7D,UAAU,WAAW;IACnB,MAAM,EAAE,iBAAiB,GAAG;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,OAAO,CAAC,eAAe,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,WAAW,CAAC;IAC3E,mEAAmE;IACnE,eAAe,CAAC,EAAE;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACnC,CAAC;IACF,4EAA4E;IAC5E,IAAI,CAAC,EAAE,qBAAqB,CAAC;CAC9B;AAyBD,UAAU,qBAAqB;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAC/C,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjC;AAqJD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,OAAO,GAAG,WAAW,CAwB3D;AAopCD,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAU/D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,CAAC,GAAG,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,KAAK,OAAO,EAC7D,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,WAAW,GAAE,SAAS,OAAO,EAAO,GACnC,OAAO,CAST;AAg6DD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CA+IjE;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,OAAO,EAClB,IAAI,GAAE;IACJ,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;CACf,GACL,OAAO,CAAC,MAAM,EAAE,CAAC,CAkCnB;AAyvBD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,MAAM,CA8BT;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAmBnD"}
@@ -24,7 +24,7 @@ import { mkdir, readFile, writeFile } from 'node:fs/promises';
24
24
  import { join } from 'node:path';
25
25
  import { setTimeout as delay } from 'node:timers/promises';
26
26
  import { createActor, fromPromise } from 'xstate';
27
- import { AWAIT_BOSS_REPLY_STATE, BOSS_REPLY_EVENT, CONTROLLER_ACTION_GUARDS, INTERRUPT_EVENT, NEEDS_BOSS_REPLY, VERIFY_MODULE, controllerDecisionNearMiss, enumerateCaptainStates, enumerateScriptStates, initialStateTarget, isControllerDecisionResult, isControllerMachine, loadFsmModule, normalizeArms, } from './verify.js';
27
+ import { AWAIT_BOSS_REPLY_STATE, BOSS_REPLY_EVENT, INTERRUPT_EVENT, NEEDS_BOSS_REPLY, VERIFY_MODULE, controllerDecisionNearMiss, enumerateCaptainStates, enumerateScriptStates, initialStateTarget, isControllerDecisionResult, isControllerMachine, loadFsmModule, normalizeArms, } from './verify.js';
28
28
  /** The `gears2fsm`-mandated captain actor name a machine declares. */
29
29
  export const CAPTAIN_ACTOR = 'captain';
30
30
  // Each check owns its resources, including concurrent checks and async actor
@@ -539,6 +539,40 @@ function tagsOf(state) {
539
539
  return [state.tags];
540
540
  return Array.isArray(state.tags) ? state.tags : [];
541
541
  }
542
+ /** XState's built-in actions that send the machine an event by themselves. */
543
+ const EVENT_RAISING_ACTION_TYPES = new Set([
544
+ 'xstate.raise',
545
+ 'xstate.sendTo',
546
+ 'xstate.enqueueActions',
547
+ ]);
548
+ /**
549
+ * Whether an `entry` or `exit` action list can move the machine without an
550
+ * external event: a built-in raise, send, or enqueue, written inline or behind
551
+ * a `setup()`-registered name. An action that only assigns keeps a parked leaf
552
+ * inert (DR-053).
553
+ */
554
+ function raisesEvent(machine, actions) {
555
+ const typeOf = (action) => {
556
+ if (typeof action === 'string')
557
+ return action;
558
+ if ((typeof action === 'object' && action !== null) ||
559
+ typeof action === 'function') {
560
+ const type = action.type;
561
+ return typeof type === 'string' ? type : undefined;
562
+ }
563
+ return undefined;
564
+ };
565
+ const list = actions === undefined ? [] : Array.isArray(actions) ? actions : [actions];
566
+ return list.some((action) => {
567
+ const type = typeOf(action);
568
+ if (type === undefined)
569
+ return false;
570
+ if (EVENT_RAISING_ACTION_TYPES.has(type))
571
+ return true;
572
+ const named = typeOf(machine.implementations?.actions?.[type]);
573
+ return named !== undefined && EVENT_RAISING_ACTION_TYPES.has(named);
574
+ });
575
+ }
542
576
  function stateRefForTarget(refs, target, source) {
543
577
  const absolute = target.startsWith('#');
544
578
  const normalized = absolute
@@ -2441,7 +2475,7 @@ async function runFsmCoverage(fsmModule, sourceText) {
2441
2475
  const detail = nearMiss.missing.length > 0
2442
2476
  ? `missing ${JSON.stringify(nearMiss.missing[0])}`
2443
2477
  : `extra ${JSON.stringify(nearMiss.extra[0])}`;
2444
- findings.push(`state ${captain.binding.stateId}: controller decision contract near-miss (${detail}); the controller domain requires exactly ${CONTROLLER_ACTION_GUARDS.join(', ')}`);
2478
+ findings.push(`state ${captain.binding.stateId}: controller decision contract near-miss (${detail}); the controller domain requires exactly ${nearMiss.domain.join(', ')}`);
2445
2479
  }
2446
2480
  for (const ref of parallelRefs) {
2447
2481
  await coverageYield();
@@ -2604,6 +2638,29 @@ async function runFsmCoverage(fsmModule, sourceText) {
2604
2638
  resolveGuard(machine, rawGuard) === undefined)) {
2605
2639
  continue;
2606
2640
  }
2641
+ // A controller's final defensive fallback rejects malformed actor
2642
+ // output. It is not a second business action for a valid result,
2643
+ // provided the parked leaf it enters cannot leave by itself.
2644
+ const targetRef = stateRefForTarget(refs, target, captain.ref);
2645
+ if (isControllerDecisionResult(state.result) &&
2646
+ rawGuard === undefined &&
2647
+ index === rawDoneArms.length - 1 &&
2648
+ targetRef !== undefined &&
2649
+ tagsOf(targetRef.state).includes('playbook.parked') &&
2650
+ targetRef.state.invoke === undefined &&
2651
+ targetRef.state.states === undefined &&
2652
+ !Object.hasOwn(targetRef.state, 'always') &&
2653
+ !Object.hasOwn(targetRef.state, 'after') &&
2654
+ !raisesEvent(machine, targetRef.state.entry) &&
2655
+ !raisesEvent(machine, targetRef.state.exit) &&
2656
+ !rawDoneArms
2657
+ .slice(0, index)
2658
+ .some((otherArm) => stateRefForTarget(refs, rawArmTarget(otherArm) ?? '', captain.ref) === targetRef) &&
2659
+ transitionArms(captain.invocation.onError).some((errorArm, errorIndex, errorArms) => errorIndex === errorArms.length - 1 &&
2660
+ armGuard(errorArm) === undefined &&
2661
+ stateRefForTarget(refs, rawArmTarget(errorArm) ?? '', captain.ref) === targetRef)) {
2662
+ continue;
2663
+ }
2607
2664
  const guard = orderedArmPredicate(machine, rawDoneArms, index);
2608
2665
  if (guard === undefined)
2609
2666
  continue;