kestrel.markets
Version:
A typed, token-efficient language + runtime for agentic trading: agents author bounded plans, the runtime fires them at the tick. CLI + typed library + MCP server.
168 lines (156 loc) • 7.77 kB
text/typescript
/**
* # grade — honest grading and the fill model
*
* Charter: **if you can author it, you can grade it** — a Plan (realized EV through
* fills), a Wake or Scan (attention efficiency), a View (do agents decide better through
* it), a regime tag (gated-beats-pooled), a Pod node (the PM's allocations). Grade
* replays anything authored across recorded sessions under a **named, versioned fill
* model** and reports honest EV with counterfactuals as syntax (`VS ungated`, `VS null`,
* `BRACKET`) rather than bespoke scripts. It rests on one **FillModel** seam returning a
* calibrated `p_fill`, an expected fill price, and a support flag — never a binary fill —
* and every plan *and* the structural null cross the SAME fill model, so strategies are
* compared on fills, not on fill assumptions. Every grade stamps its judge; EVs across
* fill-model versions refuse naive comparison. **Names are data**: `BY name` /
* `BY lineage` are first-class grade dimensions, and clustering names with outcomes is
* how strategy families and sub-regimes emerge.
*
* (Phase 1: charter only. Implementation lands in a later milestone.)
*/
/**
* The **support guard** the future grader/RunRecord (kestrel-a57.1) applies before banking any
* expected-$ from a fill cell. A cell's E[$] is banked **only** when its `FillSupport` is
* `"calibrated"`; an `"extrapolated"` cell — or an unstated one — banks **$0** on the gain side: the
* Allocator refuses to bank paper-$ computed where support == extrapolated, so strategies cannot
* hill-climb into uncalibrated corners of the fill model.
*
* SIGN policy (fail-closed, AGENTS.md "never silently false"): a `"calibrated"` cell banks its E[$]
* as-is (both signs). An `"extrapolated"` / unstated cell refuses paper PROFIT (→ $0) but does NOT
* forgive a paper LOSS — zeroing a negative EV would flatter a strategy that routes losing fills into
* uncalibrated corners (a fail-OPEN, gameable asymmetry, the inverse of the hill-climb this guard
* prevents). So an extrapolated cell banks only its non-positive part: gains → $0, losses kept.
*
* RE-EXPRESSED, NOT FORKED (kestrel-dpy, ADR-0014): the policy and the `FillSupport` vocabulary now
* live in ONE place — the zero-dependency PROTOCOL home {@link ../protocol/support.ts} (promoted there
* under kestrel-h314) — and `bankableEv` is that module's function, re-exported here so grade keeps its
* import surface. Grade imports from the protocol home directly rather than hopping through
* `../support/index.ts` (itself only a thin re-export of the same protocol surface). The Blotter's signed
* `fill_claim` and the grader's `bankable` view therefore read the SAME policy and can never disagree. The
* invariant `bankableEvOf(partition(cells)) === Σ bankableEv(cell.ev, cell.support)` is pinned in
* `tests/support.partition.test.ts`.
*/
export { bankableEv } from "../protocol/support.ts";
// ─────────────────────────────────────────────────────────────────────────────
// The three-channel P&L headline contract + the sampled qualification gate (kestrel-9gu.12)
// ─────────────────────────────────────────────────────────────────────────────
/**
* Floor / expected / realized-sampled, side by side, with the HEADLINE selected by the fail-closed
* qualification gate (kestrel-9gu.8.6; 9gu.8 AC#7): strict-cross floor stays the headline until the
* sampled channel's calibration+causality+fidelity study is owner-approved on the record, and an
* extrapolated-support sampled result is never the headline (`bankableEv` stays). Both the
* EpisodeReport and the Blotter select through this one module — one policy, never forked.
*/
export {
sampledQualified,
selectHeadline,
readSampledQualificationClaim,
type PnlChannel,
type PnlChannels,
type SampledGateEvidence,
type SampledQualification,
type SampledQualificationClaim,
type HeadlinePnl,
} from "./headline.ts";
// ─────────────────────────────────────────────────────────────────────────────
// Agent decision receipts (kestrel-a57.5)
// ─────────────────────────────────────────────────────────────────────────────
/**
* The immutable agent PROPOSAL / DECLINE / STAND-DOWN receipt and its pure projector from the Session bus
* (kestrel-a57.5). A receipt is the curation-honest counterpart to the Blotter: the Blotter records what the
* engine DID; a receipt records what the agent DECIDED — including the declines and stand-downs a
* survivor-only ledger would drop. See {@link ./receipt.ts} for the typed immutable shape + content-
* addressing builder, and {@link ./receipts.ts} for the pure `projectReceipts(bus)` projector.
*/
export {
createReceipt,
serializeReceipt,
validateReceipt,
planHash,
counterfactualHash,
isSha256,
sha256,
ReceiptValidationError,
PlanParseError,
RECEIPT_SCHEMA,
DECISION_KINDS,
ARMING_DECISIONS,
COUNTERFACTUAL_KINDS,
} from "./receipt.ts";
export type {
ProposalReceipt,
ReceiptInput,
ReceiptPlan,
ReceiptCounterfactual,
Percept,
PerceptProjection,
ThesisAxes,
ThesisValue,
MeasurementVersions,
DecisionKind,
CounterfactualKind,
} from "./receipt.ts";
export {
projectReceipts,
serializeReceipts,
encodeDecision,
declinedAndStoodDown,
DECISION_CONTROL_TYPES,
// The PRODUCER half (kestrel-a57.18) — what the Session driver WRITES so the projector is non-empty
// on a real session bus.
decisionControlFields,
driverMeasurementVersions,
UNSTATED_THESIS,
DRIVER_COMMISSION_MODEL,
DRIVER_RISK_ENVELOPE,
DRIVER_GRADER,
} from "./receipts.ts";
export type {
SessionReceipts,
ReceiptSession,
SkippedDecision,
DecisionDescriptor,
CurationVerdict,
DecisionEmit,
} from "./receipts.ts";
// ─────────────────────────────────────────────────────────────────────────────
// Alpha-measurement kinds (kestrel-a57.6)
// ─────────────────────────────────────────────────────────────────────────────
/**
* Three type-incompatible alpha-measurement records — RULE (mechanical template over the whole universe),
* SELECTION (discretionary picks vs a frozen counterfactual on the same future tape), and DIAGNOSTIC
* (inspection only, never promotes). The KIND-axis sibling of ADR-0006: alphas across KINDS refuse naive
* comparison, enforced by the compiler (`compare`/`rank`/`promote` are pinned with `NoInfer<M>`; diagnostics
* have no ordering surface). {@link ./measurement.ts}.
*/
export {
ruleAlpha,
selectionAlpha,
diagnostic,
compare,
rank,
promote,
} from "./measurement.ts";
export type {
AlphaScore,
TemplateRef,
TapeRef,
FrozenCounterfactual,
RuleAlphaInput,
RuleAlphaMeasurement,
SelectionAlphaInput,
SelectionAlphaMeasurement,
DiagnosticInput,
DiagnosticMeasurement,
PromotableAlpha,
Comparison,
PromotionOutcome,
} from "./measurement.ts";