principles-disciple 1.186.0 → 1.187.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.
@@ -37,11 +37,14 @@ export interface RuleHostObservedDecision extends RuleHostResult {
37
37
  /**
38
38
  * PRI-491 — A structured record of an activation that was skipped at load
39
39
  * time (flag-off v2, unsupported action, unsupported context version,
40
- * missing target_ref, content_json not an object, no implementationCode).
40
+ * missing target_ref, content_json not an object, no implementationCode,
41
+ * or duplicate active activation for target_ref).
41
42
  *
42
43
  * Unlike compile/load failures (which emit rulehost_unhealthy), skipped
43
44
  * activations have a configuration/flag reason — the RuleCode itself may be
44
- * valid, but the runtime chose not to execute it.
45
+ * valid, but the runtime chose not to execute it. Duplicate activations are
46
+ * a special case: they ALSO emit rulehost_unhealthy (for telemetry), but are
47
+ * surfaced in skippedActivations so the owner can observe and act (rc-9).
45
48
  *
46
49
  * ERR-002 (rc-9): every skip carries a reason + nextAction, never silent.
47
50
  */
@@ -258,7 +258,13 @@ export class RuleHost {
258
258
  }
259
259
  }
260
260
  // Emit structured unhealthy evidence for duplicate groups; collect valid (non-duplicate) rows.
261
+ // PRI-497: duplicate activations are ALSO pushed to the `skipped` array
262
+ // so callers (gate.ts, CLI, Console) can observe them via
263
+ // skippedActivations — not just via rulehost_unhealthy event log.
264
+ // Both paths are populated (rc-9-no-silent-fallback): event log for
265
+ // telemetry, skipped array for structured caller-facing observability.
261
266
  const validRows = [];
267
+ const skipped = [];
262
268
  for (const [targetRef, group] of rowsByTargetRef) {
263
269
  if (group.length > 1) {
264
270
  const activationIds = [];
@@ -280,6 +286,14 @@ export class RuleHost {
280
286
  const artifactId = typeof r['artifact_id'] === 'string' ? r['artifact_id'] : '';
281
287
  if (activationId && artifactId) {
282
288
  this._recordUnhealthy(activationId, artifactId, targetRef, `duplicate active activation for target_ref ${targetRef}`, 'Deactivate all but one activation for this target_ref');
289
+ // PRI-497: also surface in skippedActivations for caller observability
290
+ skipped.push({
291
+ activationId,
292
+ ruleId: targetRef,
293
+ mode: 'live',
294
+ reason: 'duplicate_active_activation',
295
+ nextAction: 'Deactivate all but one activation for this target_ref',
296
+ });
283
297
  }
284
298
  }
285
299
  }
@@ -290,7 +304,6 @@ export class RuleHost {
290
304
  }
291
305
  }
292
306
  const loaded = [];
293
- const skipped = [];
294
307
  for (const r of validRows) {
295
308
  const activationId = typeof r['activation_id'] === 'string' ? r['activation_id'] : '';
296
309
  const artifactId = typeof r['artifact_id'] === 'string' ? r['artifact_id'] : '';
@@ -80,7 +80,7 @@ export function handleBeforeToolCall(event, ctx) {
80
80
  };
81
81
  const report = typeof ruleHost.evaluateDetailed === 'function'
82
82
  ? ruleHost.evaluateDetailed(hostInput)
83
- : { liveDecision: ruleHost.evaluate(hostInput), shadowDecisions: [] };
83
+ : { liveDecision: ruleHost.evaluate(hostInput), shadowDecisions: [], skippedActivations: [] };
84
84
  const hostResult = report.liveDecision;
85
85
  for (const shadowDecision of report.shadowDecisions) {
86
86
  try {
@@ -2,7 +2,7 @@
2
2
  "id": "principles-disciple",
3
3
  "name": "Principles Disciple",
4
4
  "description": "Evolutionary programming agent framework with strategic guardrails and reflection loops.",
5
- "version": "1.186.0",
5
+ "version": "1.187.0",
6
6
  "activation": {
7
7
  "onCapabilities": [
8
8
  "hook"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "principles-disciple",
3
- "version": "1.186.0",
3
+ "version": "1.187.0",
4
4
  "description": "Native OpenClaw plugin for Principles Disciple",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",