@lsctech/polaris 0.5.7 → 0.5.9

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 (36) hide show
  1. package/dist/autoresearch/index.js +30 -1
  2. package/dist/autoresearch/sol-evaluation-writer.js +135 -0
  3. package/dist/autoresearch/sol-evidence-normalizer.js +337 -0
  4. package/dist/autoresearch/sol-recommendations.js +130 -0
  5. package/dist/autoresearch/sol-report-renderer.js +282 -0
  6. package/dist/autoresearch/sol-run-health-bridge.js +246 -0
  7. package/dist/autoresearch/sol-scorecard-calculator.js +865 -0
  8. package/dist/cli/autoresearch.js +77 -0
  9. package/dist/cli/medic.js +65 -0
  10. package/dist/cluster-state/store.js +56 -0
  11. package/dist/config/defaults.js +3 -0
  12. package/dist/config/validator.js +141 -0
  13. package/dist/finalize/artifact-policy.js +2 -0
  14. package/dist/finalize/github.js +13 -9
  15. package/dist/finalize/index.js +231 -5
  16. package/dist/finalize/linear.js +8 -4
  17. package/dist/finalize/medic-gate.js +42 -0
  18. package/dist/finalize/steps/08-create-pr.js +2 -2
  19. package/dist/finalize/steps/11-update-linear.js +2 -2
  20. package/dist/loop/parent.js +234 -28
  21. package/dist/loop/worker-packet.js +19 -1
  22. package/dist/medic/run-health-consult.js +381 -0
  23. package/dist/medic/treatment-packets.js +169 -0
  24. package/dist/qc/artifacts.js +27 -0
  25. package/dist/qc/orchestration.js +3 -2
  26. package/dist/qc/providers/coderabbit.js +114 -11
  27. package/dist/qc/repair-loop.js +49 -14
  28. package/dist/qc/runner.js +10 -2
  29. package/dist/qc/schemas.js +1 -0
  30. package/dist/run-health/foreman-symptoms.js +100 -0
  31. package/dist/run-health/index.js +301 -0
  32. package/dist/run-health/qc-escalation.js +155 -0
  33. package/dist/run-health/schema.js +123 -0
  34. package/dist/types/sol-metrics.js +108 -0
  35. package/dist/types/sol-scorecard.js +148 -0
  36. package/package.json +1 -1
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ /**
3
+ * SOL raw metric event contracts.
4
+ *
5
+ * Typed contracts for the raw metric events that the SOL scoring pipeline
6
+ * distinguishes when building evidence and scorecards. These types name the
7
+ * six metric categories defined in the POL-487 acceptance criteria:
8
+ *
9
+ * 1. Provider startup failure
10
+ * 2. Router fallback
11
+ * 3. Worker execution failure
12
+ * 4. Validation failure
13
+ * 5. QC findings
14
+ * 6. User / Foreman intervention
15
+ *
16
+ * These are read-model types — they normalize the raw telemetry events and
17
+ * result packet signals into a typed contract that scoring functions consume.
18
+ * Nothing in this file writes to artifacts or triggers side effects.
19
+ *
20
+ * Relationship to SolEvidence:
21
+ * SolMetricEvent records are materialized by the evidence loader into the
22
+ * SolEvidence structure. The SolEvidence fields (foreman, worker, router,
23
+ * qc, intervention) already carry the aggregated versions; these typed
24
+ * event contracts let callers reason about individual metric records and
25
+ * construct per-scope scorecards.
26
+ */
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.isProviderStartupFailure = isProviderStartupFailure;
29
+ exports.isRouterFallback = isRouterFallback;
30
+ exports.isWorkerExecutionFailure = isWorkerExecutionFailure;
31
+ exports.isValidationFailure = isValidationFailure;
32
+ exports.isQcFinding = isQcFinding;
33
+ exports.isIntervention = isIntervention;
34
+ exports.summarizeMetricEvents = summarizeMetricEvents;
35
+ // ──────────────────────────────────────────────
36
+ // Type guards
37
+ // ──────────────────────────────────────────────
38
+ function isProviderStartupFailure(e) {
39
+ return e.category === "provider-startup-failure";
40
+ }
41
+ function isRouterFallback(e) {
42
+ return e.category === "router-fallback";
43
+ }
44
+ function isWorkerExecutionFailure(e) {
45
+ return e.category === "worker-execution-failure";
46
+ }
47
+ function isValidationFailure(e) {
48
+ return e.category === "validation-failure";
49
+ }
50
+ function isQcFinding(e) {
51
+ return e.category === "qc-finding";
52
+ }
53
+ function isIntervention(e) {
54
+ return e.category === "user-intervention" || e.category === "foreman-intervention";
55
+ }
56
+ /**
57
+ * Compute a SolMetricSummary from a list of metric events.
58
+ */
59
+ function summarizeMetricEvents(events) {
60
+ let providerStartupFailures = 0;
61
+ let routerFallbacks = 0;
62
+ let routerFallbackSuccesses = 0;
63
+ let workerExecutionFailures = 0;
64
+ let validationFailures = 0;
65
+ let qcFindingsTotal = 0;
66
+ let qcFindingsBlocking = 0;
67
+ let qcFindingsUnvalidated = 0;
68
+ let userInterventions = 0;
69
+ let foremanInterventions = 0;
70
+ for (const e of events) {
71
+ if (isProviderStartupFailure(e))
72
+ providerStartupFailures++;
73
+ else if (isRouterFallback(e)) {
74
+ routerFallbacks++;
75
+ if (e.fallback_succeeded)
76
+ routerFallbackSuccesses++;
77
+ }
78
+ else if (isWorkerExecutionFailure(e))
79
+ workerExecutionFailures++;
80
+ else if (isValidationFailure(e))
81
+ validationFailures++;
82
+ else if (isQcFinding(e)) {
83
+ qcFindingsTotal++;
84
+ if (e.blocking)
85
+ qcFindingsBlocking++;
86
+ if (e.unvalidated)
87
+ qcFindingsUnvalidated++;
88
+ }
89
+ else if (isIntervention(e)) {
90
+ if (e.actor === "user")
91
+ userInterventions++;
92
+ else
93
+ foremanInterventions++;
94
+ }
95
+ }
96
+ return {
97
+ provider_startup_failures: providerStartupFailures,
98
+ router_fallbacks: routerFallbacks,
99
+ router_fallback_successes: routerFallbackSuccesses,
100
+ worker_execution_failures: workerExecutionFailures,
101
+ validation_failures: validationFailures,
102
+ qc_findings_total: qcFindingsTotal,
103
+ qc_findings_blocking: qcFindingsBlocking,
104
+ qc_findings_unvalidated: qcFindingsUnvalidated,
105
+ user_interventions: userInterventions,
106
+ foreman_interventions: foremanInterventions,
107
+ };
108
+ }
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ /**
3
+ * SOL scorecard schema.
4
+ *
5
+ * Defines durable, reproducible scorecards for SOL evaluation subjects
6
+ * (Foreman, workers, providers, models, routing decisions, token efficiency,
7
+ * QC outcomes, and user/Foreman intervention). Scorecards are distinct from
8
+ * the run-level SolScoreReport: they are per-scope, carry explicit formula
9
+ * versions, source references, and recommendation inputs.
10
+ *
11
+ * Architecture reference: sol-evaluation-report-architecture.md §Artifact classes
12
+ *
13
+ * Design rules:
14
+ * - Every scorecard carries a formula_version so consumers can detect drift.
15
+ * - source_refs link back to the immutable raw evidence that produced the scorecard.
16
+ * - Missing evidence results in SolScorecardAvailability="skipped" with reasons.
17
+ * - Scorecards are derived and reproducible; raw evidence always wins on conflict.
18
+ * - Existing SolScoreReport (run-level evaluation) remains unchanged.
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.WORKER_QUALITY_PER_TOKEN_SPEC = exports.FOREMAN_QUALITY_PER_TOKEN_SPEC = exports.WORKER_TOKEN_EFFICIENCY_SPEC = exports.FOREMAN_TOKEN_EFFICIENCY_SPEC = exports.SOL_FORMULA_VERSIONS = void 0;
22
+ exports.buildRecommendationInputs = buildRecommendationInputs;
23
+ exports.computeAggregateScore = computeAggregateScore;
24
+ exports.determineScorecardAvailability = determineScorecardAvailability;
25
+ // ──────────────────────────────────────────────
26
+ // Helpers: formula version constants
27
+ // ──────────────────────────────────────────────
28
+ /**
29
+ * Named formula version constants.
30
+ * Use these in subscore and aggregate formula_version fields.
31
+ */
32
+ exports.SOL_FORMULA_VERSIONS = {
33
+ TOKEN_EFFICIENCY_V1: "token-efficiency/1.0",
34
+ QUALITY_PER_TOKEN_V1: "quality-per-token/1.0",
35
+ COMPOSITE_MEAN_V1: "composite-mean/1.0",
36
+ VALIDATION_BINARY_V1: "validation-binary/1.0",
37
+ DISPATCH_RATE_V1: "dispatch-rate/1.0",
38
+ INTERVENTION_BINARY_V1: "intervention-binary/1.0",
39
+ QC_REPAIR_LOOP_V1: "qc-repair-loop/1.0",
40
+ SCOPE_ADHERENCE_V1: "scope-adherence/1.0",
41
+ STARTUP_FAILURE_RATE_V1: "startup-failure-rate/1.0",
42
+ QUOTA_EXHAUSTION_RATE_V1: "quota-exhaustion-rate/1.0",
43
+ FALLBACK_FREQUENCY_V1: "fallback-frequency/1.0",
44
+ ROLE_SUITABILITY_V1: "role-suitability/1.0",
45
+ RUNTIME_PROXY_V1: "runtime-proxy/1.0",
46
+ QUALITY_OUTCOMES_V1: "quality-outcomes/1.0",
47
+ ROUTE_SELECTED_V1: "route-selected/1.0",
48
+ ROUTE_CANDIDATES_V1: "route-candidates/1.0",
49
+ ROUTE_FALLBACK_PATH_V1: "route-fallback-path/1.0",
50
+ ROUTE_OUTCOME_QUALITY_V1: "route-outcome-quality/1.0",
51
+ ROUTE_TOKEN_BURN_V1: "route-token-burn/1.0",
52
+ ROUTE_QC_RESULT_V1: "route-qc-result/1.0",
53
+ ROUTE_VALIDATION_RESULT_V1: "route-validation-result/1.0",
54
+ ROUTE_CONFIRMED_SIGNAL_V1: "route-confirmed-signal/1.0",
55
+ };
56
+ /**
57
+ * Token efficiency formula spec for the Foreman subject (v1.0).
58
+ * Budget = 150k tokens; 0.0 at 300k tokens.
59
+ */
60
+ exports.FOREMAN_TOKEN_EFFICIENCY_SPEC = {
61
+ formula_version: "token-efficiency/1.0",
62
+ budget: 150_000,
63
+ max_penalized: 300_000,
64
+ source_event_type: "bootstrap-context-size",
65
+ };
66
+ /**
67
+ * Token efficiency formula spec for the Worker subject (v1.0).
68
+ * Budget = 200k tokens; 0.0 at 500k tokens.
69
+ */
70
+ exports.WORKER_TOKEN_EFFICIENCY_SPEC = {
71
+ formula_version: "token-efficiency/1.0",
72
+ budget: 200_000,
73
+ max_penalized: 500_000,
74
+ source_event_type: "worker-heartbeat-tokens",
75
+ };
76
+ /**
77
+ * Quality-per-token formula spec for run-level (Foreman) subject (v1.0).
78
+ */
79
+ exports.FOREMAN_QUALITY_PER_TOKEN_SPEC = {
80
+ formula_version: "quality-per-token/1.0",
81
+ budget_denominator: 150_000,
82
+ subject: "foreman",
83
+ };
84
+ /**
85
+ * Quality-per-token formula spec for per-child (Worker) subject (v1.0).
86
+ */
87
+ exports.WORKER_QUALITY_PER_TOKEN_SPEC = {
88
+ formula_version: "quality-per-token/1.0",
89
+ budget_denominator: 200_000,
90
+ subject: "worker",
91
+ };
92
+ // ──────────────────────────────────────────────
93
+ // Helpers: scorecard construction utilities
94
+ // ──────────────────────────────────────────────
95
+ /**
96
+ * Build SolRecommendationInputs from a list of subscores and raw metrics.
97
+ * Applies the 0.6 threshold for below_threshold detection.
98
+ */
99
+ function buildRecommendationInputs(subscores, rawMetrics, aggregateScore) {
100
+ const THRESHOLD = 0.6;
101
+ const lowScoringDimensions = subscores
102
+ .filter((s) => s.score !== null && s.score < 0.5)
103
+ .map((s) => s.dimension);
104
+ const skippedDimensions = subscores
105
+ .filter((s) => s.score === null)
106
+ .map((s) => s.dimension);
107
+ return {
108
+ below_threshold: aggregateScore !== null && aggregateScore < THRESHOLD,
109
+ low_scoring_dimensions: lowScoringDimensions,
110
+ skipped_dimensions: skippedDimensions,
111
+ over_token_budget: (rawMetrics.max_bootstrap_tokens !== null &&
112
+ rawMetrics.max_bootstrap_tokens > exports.FOREMAN_TOKEN_EFFICIENCY_SPEC.budget) ||
113
+ (rawMetrics.worker_tokens_used !== null &&
114
+ rawMetrics.worker_tokens_used > exports.WORKER_TOKEN_EFFICIENCY_SPEC.budget),
115
+ intervention_detected: rawMetrics.user_intervened === true || rawMetrics.foreman_intervened === true,
116
+ router_issue_detected: rawMetrics.router_fallback_used === true || rawMetrics.router_exhausted === true,
117
+ qc_issue_detected: (rawMetrics.qc_blocking_findings !== null && rawMetrics.qc_blocking_findings > 0) ||
118
+ rawMetrics.qc_repair_loop_status === "all-providers-failed" ||
119
+ rawMetrics.qc_repair_loop_status === "operator-review",
120
+ notes: [],
121
+ };
122
+ }
123
+ /**
124
+ * Compute aggregate score from subscores (simple mean of non-null scores).
125
+ * Returns null when all subscores are skipped.
126
+ */
127
+ function computeAggregateScore(subscores) {
128
+ const scored = subscores.filter((s) => s.score !== null);
129
+ if (scored.length === 0)
130
+ return null;
131
+ const mean = scored.reduce((sum, s) => sum + s.score, 0) / scored.length;
132
+ return Number(mean.toFixed(4));
133
+ }
134
+ /**
135
+ * Determine scorecard availability from subscores.
136
+ * "complete" when all subscores have scores; "partial" when some are skipped;
137
+ * "skipped" when all are skipped; "unavailable" when subscores is empty.
138
+ */
139
+ function determineScorecardAvailability(subscores) {
140
+ if (subscores.length === 0)
141
+ return "unavailable";
142
+ const scored = subscores.filter((s) => s.score !== null).length;
143
+ if (scored === 0)
144
+ return "skipped";
145
+ if (scored < subscores.length)
146
+ return "partial";
147
+ return "complete";
148
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lsctech/polaris",
3
- "version": "0.5.7",
3
+ "version": "0.5.9",
4
4
  "description": "Polaris — standalone taskchain orchestration framework for governed AI agent workflows",
5
5
  "bin": {
6
6
  "polaris": "dist/cli/index.js",