Per-instance extension for the skischule engagement's solutions file (solutions-platform.json) — a Plan 15 TARGET-SPEC. skischule's signature divergence is its typed COST ENGINE (seasonal seats · annual discount · peak weeks · the Chatwoot configurator), which the generic base deliberately does not model. This composes the base solution ($ref) and adds the cost-engine fields; unevaluatedProperties:false rejects anything neither the base nor this extension documents. The cost-component shape is skischule-internal and refined when skischule actually re-pins and migrates — not validated until then (§ Completion criterion).
solutions.schema.json.The whole file is a bare array of skSolution records. The fields of one record are below.
skSolution recordThe fields of a single skSolution — one per authored file.
ext/skischule/solutions.schema.json — change the schema, and this page changes.| Field | Type | Description |
|---|---|---|
costModel
|
object | The typed cost engine for this solution (replaces the generic costInputs). Priced under the shared Scenario by skischule's inline cost(sol, scenario) hook, never by the kernel. |
annualDisc
|
number | Fractional discount applied to annual (vs monthly) billing, e.g. 0.18 = 18% off. |
components required
|
array<costComponent> | The priced lines of the model — seats, AI seats, metered usage, one-offs, flat ranges. |
type required
|
— | Discriminator: a flat-range (tiered) charge. |
ratePerSeatMo required
|
number | Monthly rate per seat. |
label
|
string | Display label for the cost line. |
aiSeatFactor
|
number | How many AI seats per human seat (e.g. 1 = one Copilot per user). |
ratePerAiSeatMo required
|
number | Monthly rate per AI seat. |
demandVar
|
string | Name of the scenario demand variable that drives the meter (e.g. 'C_mo'). |
mode
|
string | How usage is billed — e.g. 'block' (priced per fixed block) vs per-unit. |
blockSize
|
number | Units per billing block when mode='block'. |
ratePerUnit required
|
number | Price per unit (or per block). |
included
|
number | Units included before metering starts. |
peak
|
boolean | Whether this line is driven by peak-week demand (the seasonal spike). |
amount required
|
number | The one-off amount. |
bucket
|
string | The chosen tier/bucket name this charge corresponds to. |
perMo required
|
oneOf | Flat monthly amount for the chosen bucket — either a single number, or a {low,high} range (skischule's Eigenbau prices hosting + LLM-token as ranges). |
low required
|
number | Lower bound of the monthly range. |
high required
|
number | Upper bound of the monthly range. |
variants
|
array<object> | The Chatwoot configurator's selectable build variants — each a hosting choice plus a per-assist selection that re-prices and re-scores the solution. |
key required
|
string | Stable variant selector. |
name
|
string | Display name of the variant. |
hosting
|
string | Hosting choice for this variant (e.g. 'cloud' | 'selfhost') — keys scoreDeltas.hosting. |
sel
|
map<string> | Per-assist selection map (assist label → chosen build mode, e.g. 'sidecar' | 'captain'). |
scoreDeltas
|
object | Additive Fit adjustments (clamped 1–5) applied on top of the base scores depending on a configurator choice — chiefly per-hosting. |
_note
|
string | Authoring note explaining the deltas; ignored by the kernel. |
hosting
|
map<map<number>> | hosting value → { criterionId → additive delta } applied when that hosting is selected. |
pricing
|
object | The surveyed list pricing for the solution's core product — provenance for the cost model (what the vendor actually charges). |
tier
|
string | Human summary of the relevant pricing tiers. |
monthly
|
string | The monthly figure or range used. |
verified
|
boolean | Whether the pricing was confirmed against the vendor (vs estimated). |
notes
|
string | Detail on the tiers, caps, and caveats behind the figure. |
risk
|
map<string> | Named risk-dimension prose (dimension → note) — skischule's authored risk commentary alongside the numeric riskScores. |
buildNarrative
|
oneOf | How the build/configuration of this solution actually works — the eigenbau/Chatwoot assembly story. Either a single prose string, or a structured object (skischule's Eigenbau uses {summary, tradeoffs[], backboneNote}). |
summary
|
string | One-paragraph summary of how the build is assembled. |
tradeoffs
|
array<string> | The trade-offs of building (vs. renting), one bullet each. |
backboneNote
|
string | Note on the backbone/infrastructure the build rests on. |