From c14ce0ab0646af7fc9ba05b1d21c12a54cb448da Mon Sep 17 00:00:00 2001 From: systemfsoftware-bot Date: Thu, 29 Oct 2026 15:26:21 -0400 Subject: [PATCH] refactor(schema)!: conform to the effect-tsgo 0.54 lint rules Adds { readonly brand: unique symbol } as the second type argument of Schema.Class, TaggedClass and TaggedError, types InvokeRead's read part as the class's fields without the brand, and rewrites flat-map-to-tap and sleep-zero-to-yield-now. None of it needs tsgo 0.54 to compile. Ported from the packages/discern slice of systemfsoftware/systemfsoftware#874. Claude-Session: https://claude.ai/code/session_017rX35xUAHEjVVaDKVVzubW --- packages/discern/src/DiscernError.schema.ts | 78 +++++++++++-------- packages/discern/src/Observation.schema.ts | 30 +++---- packages/discern/src/ProcedureError.schema.ts | 42 +++++----- .../src/admit-budget-charge.workflow.ts | 42 +++++----- .../src/admit-procedure-depth.workflow.ts | 30 ++++--- .../discern/src/decision-model.blueprint.ts | 9 +-- packages/discern/src/routing.ts | 2 +- .../discern/src/score-eval-record.workflow.ts | 28 ++++--- packages/discern/src/select-case.workflow.ts | 34 ++++---- .../src/select-eligibility.workflow.ts | 34 ++++---- .../src/select-observation-source.workflow.ts | 40 ++++++---- packages/discern/src/select-route.workflow.ts | 46 ++++++----- 12 files changed, 245 insertions(+), 170 deletions(-) diff --git a/packages/discern/src/DiscernError.schema.ts b/packages/discern/src/DiscernError.schema.ts index de0005e..395ea3c 100644 --- a/packages/discern/src/DiscernError.schema.ts +++ b/packages/discern/src/DiscernError.schema.ts @@ -1,41 +1,49 @@ import { Schema } from 'effect' import { EvalRecord } from './EvalReport.schema.js' -export class UncertainMatchError extends Schema.TaggedError()('UncertainMatchError', { - caseId: Schema.String, - reason: Schema.String, -}) { +export class UncertainMatchError + extends Schema.TaggedError()('UncertainMatchError', { + caseId: Schema.String, + reason: Schema.String, + }) +{ override get message(): string { return `Semantic case "${this.caseId}" was uncertain: ${this.reason}` } } -export class ExhaustiveMatchError extends Schema.TaggedError()('ExhaustiveMatchError', {}) { +export class ExhaustiveMatchError + extends Schema.TaggedError()('ExhaustiveMatchError', {}) +{ override get message(): string { return 'A supposedly exhaustive semantic classification had no matching case' } } -export class DecisionIdCollisionError extends Schema.TaggedError()( - 'DecisionIdCollisionError', - { - decisionId: Schema.String, - }, -) { +export class DecisionIdCollisionError + extends Schema.TaggedError()( + 'DecisionIdCollisionError', + { + decisionId: Schema.String, + }, + ) +{ override get message(): string { return `Decision id collision for "${this.decisionId}": definitions differ` } } -export class InvalidThresholdError extends Schema.TaggedError()( - 'InvalidThresholdError', - { - threshold: Schema.String, - value: Schema.Finite, - limit: Schema.Finite, - message: Schema.String, - }, -) {} +export class InvalidThresholdError + extends Schema.TaggedError()( + 'InvalidThresholdError', + { + threshold: Schema.String, + value: Schema.Finite, + limit: Schema.Finite, + message: Schema.String, + }, + ) +{} /** * A span names its ends in the wrong order. `low` and `high` carry the ends as @@ -66,10 +74,12 @@ export class CalibrationValuesRefused extends Schema.TaggedError()('PolicyCommandRejected', { - caseIds: Schema.Array(Schema.String), - cause: Schema.optional(Schema.Unknown), -}) { +export class PolicyCommandRejected + extends Schema.TaggedError()('PolicyCommandRejected', { + caseIds: Schema.Array(Schema.String), + cause: Schema.optional(Schema.Unknown), + }) +{ override get message(): string { return `The policy run rejected its command for the cases [${this.caseIds.join(', ')}]` } @@ -80,10 +90,12 @@ export class PolicyCommandRejected extends Schema.TaggedError()('MeasureCommandRejected', { - record: EvalRecord, - cause: Schema.optional(Schema.Unknown), -}) { +export class MeasureCommandRejected + extends Schema.TaggedError()('MeasureCommandRejected', { + record: EvalRecord, + cause: Schema.optional(Schema.Unknown), + }) +{ override get message(): string { return `The eval run rejected its command for the example scored ${this.record['status']}` } @@ -94,10 +106,12 @@ export class MeasureCommandRejected extends Schema.TaggedError()('MeasureInputRefused', { - expected: Schema.Boolean, - cause: Schema.optional(Schema.Unknown), -}) { +export class MeasureInputRefused + extends Schema.TaggedError()('MeasureInputRefused', { + expected: Schema.Boolean, + cause: Schema.optional(Schema.Unknown), + }) +{ override get message(): string { return `The labelled example the measurement expected to ${ this.expected ? 'match' : 'miss' diff --git a/packages/discern/src/Observation.schema.ts b/packages/discern/src/Observation.schema.ts index 7181b6c..d4e8caf 100644 --- a/packages/discern/src/Observation.schema.ts +++ b/packages/discern/src/Observation.schema.ts @@ -37,24 +37,28 @@ export const Observations = Schema.Struct({ }) export type Observations = typeof Observations.Type -export class UnsupportedObservationFormatError extends Schema.TaggedError()( - 'UnsupportedObservationFormatError', - { - version: Schema.Finite, - detail: Schema.String, - }, -) { +export class UnsupportedObservationFormatError + extends Schema.TaggedError()( + 'UnsupportedObservationFormatError', + { + version: Schema.Finite, + detail: Schema.String, + }, + ) +{ override get message(): string { return `Observation snapshot version ${this.version} is unsupported: ${this.detail}` } } -export class MalformedObservationSnapshotError extends Schema.TaggedError()( - 'MalformedObservationSnapshotError', - { - detail: Schema.String, - }, -) { +export class MalformedObservationSnapshotError + extends Schema.TaggedError()( + 'MalformedObservationSnapshotError', + { + detail: Schema.String, + }, + ) +{ override get message(): string { return `The observation snapshot is malformed: ${this.detail}` } diff --git a/packages/discern/src/ProcedureError.schema.ts b/packages/discern/src/ProcedureError.schema.ts index 12ab29d..d529e7e 100644 --- a/packages/discern/src/ProcedureError.schema.ts +++ b/packages/discern/src/ProcedureError.schema.ts @@ -1,21 +1,25 @@ import { Schema } from 'effect' import { RouteCandidate } from './Route.schema.js' -export class NoEligibleProcedureError extends Schema.TaggedError()( - 'NoEligibleProcedureError', - { - reason: Schema.String, - }, -) { +export class NoEligibleProcedureError + extends Schema.TaggedError()( + 'NoEligibleProcedureError', + { + reason: Schema.String, + }, + ) +{ override get message(): string { return this.reason } } -export class RoutingUncertainError extends Schema.TaggedError()('RoutingUncertainError', { - reason: Schema.String, - ranked: Schema.Array(RouteCandidate), -}) { +export class RoutingUncertainError + extends Schema.TaggedError()('RoutingUncertainError', { + reason: Schema.String, + ranked: Schema.Array(RouteCandidate), + }) +{ override get message(): string { return `Could not route the request confidently: ${this.reason}` } @@ -28,14 +32,16 @@ export class RoutingUncertainError extends Schema.TaggedError()( - 'ProcedureCommandRejectedError', - { - membership: Schema.Array(Schema.String), - issue: Schema.String, - cause: Schema.optional(Schema.Unknown), - }, -) { +export class ProcedureCommandRejectedError + extends Schema.TaggedError()( + 'ProcedureCommandRejectedError', + { + membership: Schema.Array(Schema.String), + issue: Schema.String, + cause: Schema.optional(Schema.Unknown), + }, + ) +{ override get message(): string { return `Routing rejected the command for a registry of ${this.membership.join(', ')}: ${this.issue}` } diff --git a/packages/discern/src/admit-budget-charge.workflow.ts b/packages/discern/src/admit-budget-charge.workflow.ts index a29c56e..7e461d0 100644 --- a/packages/discern/src/admit-budget-charge.workflow.ts +++ b/packages/discern/src/admit-budget-charge.workflow.ts @@ -6,32 +6,38 @@ import { BudgetLimit } from './Budget.schema.js' const BudgetChargeTypeId: unique symbol = Symbol.for('@systemfsoftware/discern/BudgetCharge') type BudgetChargeTypeId = typeof BudgetChargeTypeId -export class ChargeAdmitted extends Schema.TaggedClass()('ChargeAdmitted', { - decisions: Schema.Finite, -}) { +export class ChargeAdmitted + extends Schema.TaggedClass()('ChargeAdmitted', { + decisions: Schema.Finite, + }) +{ readonly [BudgetChargeTypeId] = BudgetChargeTypeId } -export class BudgetExhausted extends Schema.TaggedError()('BudgetExhausted', { - reason: Schema.String, - spentDecisions: Schema.Finite, - spentCalls: Schema.Finite, - requestedDecisions: Schema.Finite, - maxDecisions: BudgetLimit, - maxCalls: BudgetLimit, -}) { +export class BudgetExhausted + extends Schema.TaggedError()('BudgetExhausted', { + reason: Schema.String, + spentDecisions: Schema.Finite, + spentCalls: Schema.Finite, + requestedDecisions: Schema.Finite, + maxDecisions: BudgetLimit, + maxCalls: BudgetLimit, + }) +{ override get message(): string { return `Budget exhausted after ${this.spentDecisions} decisions and ${this.spentCalls} calls: ${this.reason}` } } -export class AdmitBudgetCharge extends Schema.TaggedClass()('AdmitBudgetCharge', { - spentDecisions: Schema.Finite, - spentCalls: Schema.Finite, - requestedDecisions: Schema.Finite, - maxDecisions: BudgetLimit, - maxCalls: BudgetLimit, -}) { +export class AdmitBudgetCharge + extends Schema.TaggedClass()('AdmitBudgetCharge', { + spentDecisions: Schema.Finite, + spentCalls: Schema.Finite, + requestedDecisions: Schema.Finite, + maxDecisions: BudgetLimit, + maxCalls: BudgetLimit, + }) +{ static readonly [Workflow.InstrumentationBrand] = { requestedDecisions: 'app.discern.requested_decisions', } as const diff --git a/packages/discern/src/admit-procedure-depth.workflow.ts b/packages/discern/src/admit-procedure-depth.workflow.ts index ce75720..f5b86d8 100644 --- a/packages/discern/src/admit-procedure-depth.workflow.ts +++ b/packages/discern/src/admit-procedure-depth.workflow.ts @@ -5,10 +5,12 @@ import * as Result from 'effect/Result' const ProcedureDepthTypeId: unique symbol = Symbol.for('@systemfsoftware/discern/ProcedureDepth') type ProcedureDepthTypeId = typeof ProcedureDepthTypeId -export class DepthAdmitted extends Schema.TaggedClass()('DepthAdmitted', { - depth: Schema.Finite, - limit: Schema.Finite, -}) { +export class DepthAdmitted + extends Schema.TaggedClass()('DepthAdmitted', { + depth: Schema.Finite, + limit: Schema.Finite, + }) +{ readonly [ProcedureDepthTypeId] = ProcedureDepthTypeId } @@ -19,19 +21,23 @@ export class DepthAdmitted extends Schema.TaggedClass()('DepthAdm * bounded by the code that makes them — so the depth limit counts uncertain * routing invocations alone. */ -export class DepthExceededError extends Schema.TaggedError()('DepthExceededError', { - depth: Schema.Finite, - limit: Schema.Finite, -}) { +export class DepthExceededError + extends Schema.TaggedError()('DepthExceededError', { + depth: Schema.Finite, + limit: Schema.Finite, + }) +{ override get message(): string { return `Procedure routing reached depth ${this.depth}, at the limit of ${this.limit}` } } -export class AdmitProcedureDepth extends Schema.TaggedClass()('AdmitProcedureDepth', { - depth: Schema.Finite, - limit: Schema.Finite, -}) { +export class AdmitProcedureDepth + extends Schema.TaggedClass()('AdmitProcedureDepth', { + depth: Schema.Finite, + limit: Schema.Finite, + }) +{ static readonly [Workflow.InstrumentationBrand] = {} as const } diff --git a/packages/discern/src/decision-model.blueprint.ts b/packages/discern/src/decision-model.blueprint.ts index a80ab3b..6bc62bd 100644 --- a/packages/discern/src/decision-model.blueprint.ts +++ b/packages/discern/src/decision-model.blueprint.ts @@ -235,11 +235,10 @@ export const recording = (into: ObservationStore): Interceptor => (inner) => Effect.flatMap( CurrentRegion.useSync((path) => path), (regionPath) => - Effect.flatMap(inner.decide(options), (response) => - Effect.as( - recordAnswers(into, options.decisions, options.state, response.answers, regionPath), - response, - )), + Effect.tap( + inner.decide(options), + (response) => recordAnswers(into, options.decisions, options.state, response.answers, regionPath), + ), ) ) diff --git a/packages/discern/src/routing.ts b/packages/discern/src/routing.ts index eb27e52..e4ba94b 100644 --- a/packages/discern/src/routing.ts +++ b/packages/discern/src/routing.ts @@ -84,7 +84,7 @@ export interface InvokeRequest { * by position, never looked up again. */ export type InvokeRead> = - & (typeof SelectRoute)['Type'] + & Omit<(typeof SelectRoute)['Type'], 'brand'> & { readonly ranking: ReadonlyArray> } diff --git a/packages/discern/src/score-eval-record.workflow.ts b/packages/discern/src/score-eval-record.workflow.ts index 9f514cc..2bdf1f0 100644 --- a/packages/discern/src/score-eval-record.workflow.ts +++ b/packages/discern/src/score-eval-record.workflow.ts @@ -6,33 +6,43 @@ import { PatternStatus } from './Verdict.schema.js' const EvalScoreTypeId: unique symbol = Symbol.for('@systemfsoftware/discern/EvalScore') type EvalScoreTypeId = typeof EvalScoreTypeId -export class TruePositive extends Schema.TaggedClass()('TruePositive', {}) { +export class TruePositive + extends Schema.TaggedClass()('TruePositive', {}) +{ readonly [EvalScoreTypeId] = EvalScoreTypeId } -export class FalsePositive extends Schema.TaggedClass()('FalsePositive', {}) { +export class FalsePositive + extends Schema.TaggedClass()('FalsePositive', {}) +{ readonly [EvalScoreTypeId] = EvalScoreTypeId } -export class TrueNegative extends Schema.TaggedClass()('TrueNegative', {}) { +export class TrueNegative + extends Schema.TaggedClass()('TrueNegative', {}) +{ readonly [EvalScoreTypeId] = EvalScoreTypeId } -export class FalseNegative extends Schema.TaggedClass()('FalseNegative', {}) { +export class FalseNegative + extends Schema.TaggedClass()('FalseNegative', {}) +{ readonly [EvalScoreTypeId] = EvalScoreTypeId } -export class Abstained extends Schema.TaggedClass()('Abstained', {}) { +export class Abstained extends Schema.TaggedClass()('Abstained', {}) { readonly [EvalScoreTypeId] = EvalScoreTypeId } export const EvalScore = Schema.Union([TruePositive, FalsePositive, TrueNegative, FalseNegative, Abstained]) export type EvalScore = typeof EvalScore.Type -export class ScoreEvalRecord extends Schema.TaggedClass()('ScoreEvalRecord', { - expected: Schema.Boolean, - status: PatternStatus, -}) { +export class ScoreEvalRecord + extends Schema.TaggedClass()('ScoreEvalRecord', { + expected: Schema.Boolean, + status: PatternStatus, + }) +{ static readonly [Workflow.InstrumentationBrand] = { expected: 'app.discern.score-eval-record.expected', } as const diff --git a/packages/discern/src/select-case.workflow.ts b/packages/discern/src/select-case.workflow.ts index d3eb2b3..a631336 100644 --- a/packages/discern/src/select-case.workflow.ts +++ b/packages/discern/src/select-case.workflow.ts @@ -5,27 +5,35 @@ import * as Result from 'effect/Result' const SelectCaseDecisionTypeId: unique symbol = Symbol.for('@systemfsoftware/discern/SelectCaseDecision') type SelectCaseDecisionTypeId = typeof SelectCaseDecisionTypeId -export class CaseSelected extends Schema.TaggedClass()('CaseSelected', { - caseId: Schema.String, -}) { +export class CaseSelected + extends Schema.TaggedClass()('CaseSelected', { + caseId: Schema.String, + }) +{ readonly [SelectCaseDecisionTypeId] = SelectCaseDecisionTypeId } -export class FallbackSelected extends Schema.TaggedClass()('FallbackSelected', {}) { +export class FallbackSelected + extends Schema.TaggedClass()('FallbackSelected', {}) +{ readonly [SelectCaseDecisionTypeId] = SelectCaseDecisionTypeId } -export class UncertainHandled extends Schema.TaggedClass()('UncertainHandled', { - caseId: Schema.String, - reason: Schema.String, -}) { +export class UncertainHandled + extends Schema.TaggedClass()('UncertainHandled', { + caseId: Schema.String, + reason: Schema.String, + }) +{ readonly [SelectCaseDecisionTypeId] = SelectCaseDecisionTypeId } -export class UncertainUnhandled extends Schema.TaggedError()('UncertainUnhandled', { - caseId: Schema.String, - reason: Schema.String, -}) { +export class UncertainUnhandled + extends Schema.TaggedError()('UncertainUnhandled', { + caseId: Schema.String, + reason: Schema.String, + }) +{ override get message(): string { return `Case "${this.caseId}" was uncertain and no handler answered it` } @@ -48,7 +56,7 @@ export type CaseVerdict = typeof CaseVerdict.Type type DecisiveCase = (typeof CaseVerdict.cases)['Match']['Type'] | (typeof CaseVerdict.cases)['Uncertain']['Type'] type UncertainVerdict = (typeof CaseVerdict.cases)['Uncertain']['Type'] -export class SelectCase extends Schema.TaggedClass()('SelectCase', { +export class SelectCase extends Schema.TaggedClass()('SelectCase', { cases: Schema.Array(CaseVerdict), hasUncertainHandler: Schema.Boolean, }) { diff --git a/packages/discern/src/select-eligibility.workflow.ts b/packages/discern/src/select-eligibility.workflow.ts index c71f0f6..e2ffcf0 100644 --- a/packages/discern/src/select-eligibility.workflow.ts +++ b/packages/discern/src/select-eligibility.workflow.ts @@ -5,28 +5,36 @@ import * as Result from 'effect/Result' const EligibilityDecisionTypeId: unique symbol = Symbol.for('@systemfsoftware/discern/EligibilityDecision') type EligibilityDecisionTypeId = typeof EligibilityDecisionTypeId -export class EligibilityQuestion extends Schema.TaggedClass()('EligibilityQuestion', { - membership: Schema.Array(Schema.String), - candidates: Schema.Array(Schema.String), -}) { +export class EligibilityQuestion + extends Schema.TaggedClass()('EligibilityQuestion', { + membership: Schema.Array(Schema.String), + candidates: Schema.Array(Schema.String), + }) +{ static readonly [Workflow.InstrumentationBrand] = {} as const } -export class NoCandidateEligible extends Schema.TaggedClass()('NoCandidateEligible', { - membership: Schema.Array(Schema.String), -}) { +export class NoCandidateEligible + extends Schema.TaggedClass()('NoCandidateEligible', { + membership: Schema.Array(Schema.String), + }) +{ readonly [EligibilityDecisionTypeId] = EligibilityDecisionTypeId } -export class SingleCandidateEligible extends Schema.TaggedClass()('SingleCandidateEligible', { - candidate: Schema.String, -}) { +export class SingleCandidateEligible + extends Schema.TaggedClass()('SingleCandidateEligible', { + candidate: Schema.String, + }) +{ readonly [EligibilityDecisionTypeId] = EligibilityDecisionTypeId } -export class CandidateDistribution extends Schema.TaggedClass()('CandidateDistribution', { - candidates: Schema.TupleWithRest(Schema.Tuple([Schema.String, Schema.String]), [Schema.String]), -}) { +export class CandidateDistribution + extends Schema.TaggedClass()('CandidateDistribution', { + candidates: Schema.TupleWithRest(Schema.Tuple([Schema.String, Schema.String]), [Schema.String]), + }) +{ readonly [EligibilityDecisionTypeId] = EligibilityDecisionTypeId } diff --git a/packages/discern/src/select-observation-source.workflow.ts b/packages/discern/src/select-observation-source.workflow.ts index 3acbf58..dc23185 100644 --- a/packages/discern/src/select-observation-source.workflow.ts +++ b/packages/discern/src/select-observation-source.workflow.ts @@ -5,33 +5,41 @@ import * as Result from 'effect/Result' const SourceSelectionTypeId: unique symbol = Symbol.for('@systemfsoftware/discern/SourceSelection') type SourceSelectionTypeId = typeof SourceSelectionTypeId -export class AllRecorded extends Schema.TaggedClass()('AllRecorded', {}) { +export class AllRecorded + extends Schema.TaggedClass()('AllRecorded', {}) +{ readonly [SourceSelectionTypeId] = SourceSelectionTypeId } -export class AskForMissing extends Schema.TaggedClass()('AskForMissing', { - missing: Schema.Array(Schema.String), -}) { +export class AskForMissing + extends Schema.TaggedClass()('AskForMissing', { + missing: Schema.Array(Schema.String), + }) +{ readonly [SourceSelectionTypeId] = SourceSelectionTypeId } export const SourceSelection = Schema.Union([AllRecorded, AskForMissing]) -export class SelectObservationSource extends Schema.TaggedClass()( - 'SelectObservationSource', - { - hitIds: Schema.Array(Schema.String), - missing: Schema.Array(Schema.String), - onMissing: Schema.Literals(['fail', 'ask']), - }, -) { +export class SelectObservationSource + extends Schema.TaggedClass()( + 'SelectObservationSource', + { + hitIds: Schema.Array(Schema.String), + missing: Schema.Array(Schema.String), + onMissing: Schema.Literals(['fail', 'ask']), + }, + ) +{ static readonly [Workflow.InstrumentationBrand] = { onMissing: 'app.discern.on_missing' } as const } -export class RecordingMissing extends Schema.TaggedError()('RecordingMissing', { - missing: Schema.Array(Schema.String), - detail: Schema.String, -}) { +export class RecordingMissing + extends Schema.TaggedError()('RecordingMissing', { + missing: Schema.Array(Schema.String), + detail: Schema.String, + }) +{ override get message(): string { return this.detail } diff --git a/packages/discern/src/select-route.workflow.ts b/packages/discern/src/select-route.workflow.ts index 1257be9..9c17197 100644 --- a/packages/discern/src/select-route.workflow.ts +++ b/packages/discern/src/select-route.workflow.ts @@ -10,13 +10,15 @@ type RouteDecisionTypeId = typeof RouteDecisionTypeId * The router picked one procedure: the leader cleared both thresholds, or * eligibility left only one candidate, so no model was consulted at all. */ -export class RouteMatched extends Schema.TaggedClass()('RouteMatched', { - id: Schema.String, - probability: Schema.Finite, - margin: Schema.Finite, - by: Schema.Literals(['model', 'elimination']), - ranked: Schema.Array(RouteCandidate), -}) { +export class RouteMatched + extends Schema.TaggedClass()('RouteMatched', { + id: Schema.String, + probability: Schema.Finite, + margin: Schema.Finite, + by: Schema.Literals(['model', 'elimination']), + ranked: Schema.Array(RouteCandidate), + }) +{ readonly [RouteDecisionTypeId] = RouteDecisionTypeId } @@ -25,14 +27,16 @@ export class RouteMatched extends Schema.TaggedClass()('RouteMatch * so a caller deciding what to do about the uncertainty sees what the router * saw. */ -export class RouteUncertain extends Schema.TaggedClass()('RouteUncertain', { - reason: Schema.String, - ranked: Schema.Array(RouteCandidate), -}) { +export class RouteUncertain + extends Schema.TaggedClass()('RouteUncertain', { + reason: Schema.String, + ranked: Schema.Array(RouteCandidate), + }) +{ readonly [RouteDecisionTypeId] = RouteDecisionTypeId } -export class RouteNone extends Schema.TaggedClass()('RouteNone', { +export class RouteNone extends Schema.TaggedClass()('RouteNone', { reason: Schema.String, }) { readonly [RouteDecisionTypeId] = RouteDecisionTypeId @@ -55,19 +59,21 @@ export type Route = | RouteUncertainOf | (typeof RouteNone)['Encoded'] -export class NoEligible extends Schema.TaggedClass()('NoEligible', { +export class NoEligible extends Schema.TaggedClass()('NoEligible', { membership: Schema.Array(Schema.String), }) {} -export class OneEligible extends Schema.TaggedClass()('OneEligible', { +export class OneEligible extends Schema.TaggedClass()('OneEligible', { candidate: RouteCandidate, }) {} -export class ManyEligible extends Schema.TaggedClass()('ManyEligible', { - leader: RouteCandidate, - runnerUp: RouteCandidate, - ranked: Schema.Array(RouteCandidate), -}) {} +export class ManyEligible + extends Schema.TaggedClass()('ManyEligible', { + leader: RouteCandidate, + runnerUp: RouteCandidate, + ranked: Schema.Array(RouteCandidate), + }) +{} /** * The eligibility outcome the registry computed before anything was asked: @@ -77,7 +83,7 @@ export class ManyEligible extends Schema.TaggedClass()('ManyEligib export const EligibilityOutcome = Schema.Union([NoEligible, OneEligible, ManyEligible]) export type EligibilityOutcome = typeof EligibilityOutcome.Type -export class SelectRoute extends Schema.TaggedClass()('SelectRoute', { +export class SelectRoute extends Schema.TaggedClass()('SelectRoute', { eligibility: EligibilityOutcome, minProbability: Schema.Finite, minMargin: Schema.Finite,