feat(submissions): define bounded performance and scoped history contracts

This commit is contained in:
2026-10-11 03:35:12 +08:00
parent 5df3c370aa
commit 3cc90e4573
9 changed files with 976 additions and 2 deletions
+22 -1
View File
@@ -4,6 +4,8 @@ from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException, Query, Request, Response
from kf_oj.api.dependencies import current_principal, unsafe_principal
from kf_oj.contracts.judging_v2 import Language
from kf_oj.contracts.submission_performance import SubmissionPerformance
from kf_oj.contracts.submissions import (
CancellationAccepted,
CreateSubmission,
@@ -65,9 +67,11 @@ async def history(
principal: Annotated[Principal, Depends(current_principal)],
after: Annotated[str | None, Query(max_length=128)] = None,
limit: Annotated[int, Query(ge=1, le=100)] = 20,
problem_version_id: UUID | None = None,
language: Language | None = None,
):
try:
return await queries(request).page(principal, after, limit)
return await queries(request).page(principal, after, limit, problem_version_id, language)
except ValueError:
raise HTTPException(422, "invalid history request") from None
@@ -86,6 +90,23 @@ async def detail(
raise HTTPException(503, "stored result unavailable") from None
@router.get("/{submission_id}/performance", response_model=SubmissionPerformance)
async def performance(
submission_id: UUID,
request: Request,
principal: Annotated[Principal, Depends(current_principal)],
):
service = getattr(request.app.state, "submission_performance", None)
if service is None:
raise HTTPException(503, "performance service unavailable")
try:
return await service.detail(principal, submission_id)
except SubmissionUnavailable:
raise HTTPException(404, "submission unavailable") from None
except ValueError:
raise HTTPException(503, "performance unavailable") from None
@router.get("/{submission_id}/source", response_model=SubmissionSource)
async def source(
submission_id: UUID,
+9
View File
@@ -8,6 +8,7 @@ from kf_oj.api.app import create_app
from kf_oj.contracts.judge import JudgeTaskNotification
from kf_oj.contracts.judging import WIRE_MODELS
from kf_oj.contracts.judging_v2 import WIRE_MODELS as WIRE_MODELS_V2
from kf_oj.contracts.submission_performance import SubmissionPerformance
from kf_oj.core.settings import Settings
@@ -34,6 +35,14 @@ def main() -> None:
"budgets, result consistency, UUID canonical form and UTF-8 byte limits."
)
outputs[root / f"contracts/schemas/{name}.v1.schema.json"] = document
performance = SubmissionPerformance.model_json_schema()
performance["$schema"] = "https://json-schema.org/draft/2020-12/schema"
performance["$id"] = "urn:kf-oj:submission-performance:v1"
performance["$comment"] = (
"Anonymous bounded aggregates, decimal raw units and strict same-snapshot "
"counts; also run model validation and server-side ownership/environment checks."
)
outputs[root / "contracts/schemas/submission-performance.v1.schema.json"] = performance
for name, model in WIRE_MODELS_V2.items():
document = model.model_json_schema()
document["$schema"] = "https://json-schema.org/draft/2020-12/schema"
@@ -0,0 +1,126 @@
"""Bounded anonymous aggregates; raw measurements never pass through JS floats."""
from datetime import datetime
from typing import Annotated, Literal, Self
from pydantic import AfterValidator, Field, StrictBool, model_validator
from kf_oj.contracts.judging import I64_MAX, Digest, Identifier, Version, WireModel
from kf_oj.contracts.judging_v2 import Language
MAX_PERFORMANCE_SAMPLES = 10_000
MIN_PERFORMANCE_SAMPLES = 5
MAX_PERFORMANCE_BUCKETS = 64
def bounded_decimal(value: str) -> str:
if int(value) > I64_MAX:
raise ValueError("measurement exceeds signed storage range")
return value
DecimalMeasurement = Annotated[
str,
Field(strict=True, min_length=1, max_length=19, pattern=r"^(0|[1-9][0-9]*)$"),
AfterValidator(bounded_decimal),
]
SampleCount = Annotated[int, Field(strict=True, ge=0, le=MAX_PERFORMANCE_SAMPLES)]
UnavailableReason = Literal[
"not_accepted", "measurement_missing", "environment_unverified", "insufficient_samples"
]
class PerformanceBucket(WireModel):
start: DecimalMeasurement
end: DecimalMeasurement
upper_inclusive: StrictBool
count: SampleCount
@model_validator(mode="after")
def interval(self) -> Self:
if int(self.end) <= int(self.start):
raise ValueError("empty or reversed interval")
return self
class PerformanceMetric(WireModel):
unit: Literal["cpu_microseconds", "bytes"]
current: DecimalMeasurement | None
available: StrictBool
reason: UnavailableReason | None
sample_count: SampleCount
window_truncated: StrictBool
oldest_sample_at: datetime | None
# These counts are computed against the original integers, never rounded bins.
strictly_slower_count: SampleCount | None
tied_count: SampleCount | None
buckets: Annotated[tuple[PerformanceBucket, ...], Field(max_length=MAX_PERFORMANCE_BUCKETS)]
@model_validator(mode="after")
def aggregate(self) -> Self:
if self.oldest_sample_at is not None and self.oldest_sample_at.utcoffset() is None:
raise ValueError("sample timestamp must have a timezone")
if self.available:
if (
self.reason is not None
or self.current is None
or self.sample_count < MIN_PERFORMANCE_SAMPLES
or self.strictly_slower_count is None
or self.tied_count is None
or self.oldest_sample_at is None
or not self.buckets
):
raise ValueError("incomplete available aggregate")
if self.strictly_slower_count + self.tied_count > self.sample_count:
raise ValueError("comparison counts exceed the cohort")
if sum(b.count for b in self.buckets) != self.sample_count:
raise ValueError("histogram loses samples")
if int(self.buckets[0].start) != 0:
raise ValueError("histogram must include zero")
for index, bucket in enumerate(self.buckets):
if bucket.upper_inclusive != (index == len(self.buckets) - 1):
raise ValueError("only the last interval includes its upper endpoint")
if index and self.buckets[index - 1].end != bucket.start:
raise ValueError("histogram intervals must be contiguous")
elif (
self.reason is None
or self.buckets
or self.strictly_slower_count is not None
or self.tied_count is not None
):
raise ValueError("unavailable aggregate cannot expose comparison data")
if self.reason == "measurement_missing" and self.current is not None:
raise ValueError("missing measurement cannot claim a value")
if self.reason == "insufficient_samples" and (
self.sample_count >= MIN_PERFORMANCE_SAMPLES or self.current is None
):
raise ValueError("inconsistent insufficient cohort")
return self
class SubmissionPerformance(WireModel):
schema_version: Version = 1
kind: Literal["judge.performance"] = "judge.performance"
submission_id: Identifier
problem_version_id: Identifier
language: Language
as_of: datetime
# Opaque trusted comparison identity, not a worker name, path or credential.
comparison_group: Digest | None
window_limit: Literal[10_000] = MAX_PERFORMANCE_SAMPLES
minimum_samples: Literal[5] = MIN_PERFORMANCE_SAMPLES
cpu: PerformanceMetric
memory: PerformanceMetric
@model_validator(mode="after")
def snapshot(self) -> Self:
if self.as_of.utcoffset() is None:
raise ValueError("snapshot timestamp must have a timezone")
if self.cpu.unit != "cpu_microseconds" or self.memory.unit != "bytes":
raise ValueError("metric unit mismatch")
for metric in (self.cpu, self.memory):
if metric.available and self.comparison_group is None:
raise ValueError("comparison requires trusted environment binding")
if metric.oldest_sample_at is not None and metric.oldest_sample_at > self.as_of:
raise ValueError("sample is newer than the snapshot")
return self
@@ -88,7 +88,14 @@ class SubmissionQueries:
.where(Submission.id == submission_id, Submission.account_id == principal.account_id)
)
async def page(self, principal: Principal, after: str | None, limit: int) -> SubmissionPage:
async def page(
self,
principal: Principal,
after: str | None,
limit: int,
problem_version_id: UUID | None = None,
language: str | None = None,
) -> SubmissionPage:
if not 1 <= limit <= 100:
raise ValueError("invalid history limit")
query = (
@@ -98,6 +105,10 @@ class SubmissionQueries:
.order_by(Submission.created_at.desc(), Submission.id.desc())
.limit(limit + 1)
)
if problem_version_id is not None:
query = query.where(Submission.problem_version_id == problem_version_id)
if language is not None:
query = query.where(Submission.language == language)
if after is not None:
query = query.where(tuple_(Submission.created_at, Submission.id) < cursor_decode(after))
async with self.sessions() as session:
@@ -0,0 +1,78 @@
"""Protocol/route boundaries, not evidence of real measured execution."""
import copy
import json
from pathlib import Path
from uuid import UUID
import pytest
from fastapi.testclient import TestClient
from jsonschema import Draft202012Validator
from kf_oj.api.app import create_app
from kf_oj.api.dependencies import current_principal
from kf_oj.contracts.submission_performance import SubmissionPerformance
from kf_oj.core.settings import Settings
from kf_oj.modules.identity.public import Principal
ROOT = Path(__file__).parents[2]
def fixture():
return json.loads(
(ROOT / "tests/fixtures/contracts/submission-performance.valid.json").read_text()
)
def test_decimal_measurements_zero_and_four_languages_roundtrip():
data = fixture()
for language in ("c17", "cpp20", "python313", "java21"):
data["language"] = language
response = SubmissionPerformance.model_validate(data)
encoded = response.model_dump(mode="json")
assert encoded == data
assert encoded["cpu"]["current"] == "9007199254740993"
assert encoded["memory"]["current"] == "0"
Draft202012Validator(SubmissionPerformance.model_json_schema()).validate(encoded)
@pytest.mark.parametrize(
"change",
[
lambda v: v.update(language="Rust"),
lambda v: v.update(schema_version=True),
lambda v: v.update(username="other_user"),
lambda v: v.update(comparison_group=None),
lambda v: v.update(as_of="2026-10-11T00:00:00"),
lambda v: v["cpu"].update(current=9007199254740993),
lambda v: v["cpu"].update(current="092"),
lambda v: v["cpu"].update(current="9223372036854775808"),
lambda v: v["cpu"].update(sample_count=4),
lambda v: v["cpu"].update(strictly_slower_count=6, tied_count=1),
lambda v: v["cpu"].update(oldest_sample_at="2026-10-12T00:00:00Z"),
lambda v: v["cpu"]["buckets"][0].update(upper_inclusive=True),
lambda v: v["cpu"]["buckets"][0].update(count=2),
lambda v: v["cpu"]["buckets"][1].update(start="9007199254740994"),
lambda v: v["memory"].update(sample_count=5),
lambda v: v["memory"].update(tied_count=1),
lambda v: v["memory"].update(reason="measurement_missing"),
],
)
def test_no_rounded_fabricated_unbounded_or_inconsistent_aggregate(change):
data = copy.deepcopy(fixture())
change(data)
with pytest.raises(ValueError):
SubmissionPerformance.model_validate(data)
def test_performance_unconfigured_and_bad_history_filters_fail_closed():
app = create_app(Settings(_env_file=None, environment="test"))
sid = "11111111-1111-4111-8111-111111111111"
with TestClient(app) as client:
assert client.get(f"/api/v1/submissions/{sid}/performance").status_code == 503
app.dependency_overrides[current_principal] = lambda: Principal(UUID(sid), "owner")
response = client.get(f"/api/v1/submissions/{sid}/performance")
assert response.status_code == 503
assert response.headers["Cache-Control"] == "no-store"
assert client.get("/api/v1/submissions?language=rust").status_code == 422
assert client.get("/api/v1/submissions?problem_version_id=1001").status_code == 422
+309
View File
@@ -308,6 +308,161 @@
"title": "LoginResponse",
"type": "object"
},
"PerformanceBucket": {
"additionalProperties": false,
"properties": {
"count": {
"maximum": 10000.0,
"minimum": 0.0,
"title": "Count",
"type": "integer"
},
"end": {
"maxLength": 19,
"minLength": 1,
"pattern": "^(0|[1-9][0-9]*)$",
"title": "End",
"type": "string"
},
"start": {
"maxLength": 19,
"minLength": 1,
"pattern": "^(0|[1-9][0-9]*)$",
"title": "Start",
"type": "string"
},
"upper_inclusive": {
"title": "Upper Inclusive",
"type": "boolean"
}
},
"required": [
"start",
"end",
"upper_inclusive",
"count"
],
"title": "PerformanceBucket",
"type": "object"
},
"PerformanceMetric": {
"additionalProperties": false,
"properties": {
"available": {
"title": "Available",
"type": "boolean"
},
"buckets": {
"items": {
"$ref": "#/components/schemas/PerformanceBucket"
},
"maxItems": 64,
"title": "Buckets",
"type": "array"
},
"current": {
"anyOf": [
{
"maxLength": 19,
"minLength": 1,
"pattern": "^(0|[1-9][0-9]*)$",
"type": "string"
},
{
"type": "null"
}
],
"title": "Current"
},
"oldest_sample_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"title": "Oldest Sample At"
},
"reason": {
"anyOf": [
{
"enum": [
"not_accepted",
"measurement_missing",
"environment_unverified",
"insufficient_samples"
],
"type": "string"
},
{
"type": "null"
}
],
"title": "Reason"
},
"sample_count": {
"maximum": 10000.0,
"minimum": 0.0,
"title": "Sample Count",
"type": "integer"
},
"strictly_slower_count": {
"anyOf": [
{
"maximum": 10000.0,
"minimum": 0.0,
"type": "integer"
},
{
"type": "null"
}
],
"title": "Strictly Slower Count"
},
"tied_count": {
"anyOf": [
{
"maximum": 10000.0,
"minimum": 0.0,
"type": "integer"
},
{
"type": "null"
}
],
"title": "Tied Count"
},
"unit": {
"enum": [
"cpu_microseconds",
"bytes"
],
"title": "Unit",
"type": "string"
},
"window_truncated": {
"title": "Window Truncated",
"type": "boolean"
}
},
"required": [
"unit",
"current",
"available",
"reason",
"sample_count",
"window_truncated",
"oldest_sample_at",
"strictly_slower_count",
"tied_count",
"buckets"
],
"title": "PerformanceMetric",
"type": "object"
},
"PreparationKind": {
"enum": [
"compile",
@@ -907,6 +1062,84 @@
"title": "SubmissionPage",
"type": "object"
},
"SubmissionPerformance": {
"additionalProperties": false,
"properties": {
"as_of": {
"format": "date-time",
"title": "As Of",
"type": "string"
},
"comparison_group": {
"anyOf": [
{
"maxLength": 64,
"minLength": 64,
"pattern": "^[0-9a-f]{64}$",
"type": "string"
},
{
"type": "null"
}
],
"title": "Comparison Group"
},
"cpu": {
"$ref": "#/components/schemas/PerformanceMetric"
},
"kind": {
"const": "judge.performance",
"default": "judge.performance",
"title": "Kind",
"type": "string"
},
"language": {
"$ref": "#/components/schemas/kf_oj__contracts__judging_v2__Language"
},
"memory": {
"$ref": "#/components/schemas/PerformanceMetric"
},
"minimum_samples": {
"const": 5,
"default": 5,
"title": "Minimum Samples",
"type": "integer"
},
"problem_version_id": {
"format": "uuid",
"title": "Problem Version Id",
"type": "string"
},
"schema_version": {
"const": 1,
"default": 1,
"title": "Schema Version",
"type": "integer"
},
"submission_id": {
"format": "uuid",
"title": "Submission Id",
"type": "string"
},
"window_limit": {
"const": 10000,
"default": 10000,
"title": "Window Limit",
"type": "integer"
}
},
"required": [
"submission_id",
"problem_version_id",
"language",
"as_of",
"comparison_group",
"cpu",
"memory"
],
"title": "SubmissionPerformance",
"type": "object"
},
"SubmissionSource": {
"additionalProperties": false,
"properties": {
@@ -1557,6 +1790,39 @@
"title": "Limit",
"type": "integer"
}
},
{
"in": "query",
"name": "problem_version_id",
"required": false,
"schema": {
"anyOf": [
{
"format": "uuid",
"type": "string"
},
{
"type": "null"
}
],
"title": "Problem Version Id"
}
},
{
"in": "query",
"name": "language",
"required": false,
"schema": {
"anyOf": [
{
"$ref": "#/components/schemas/Language-Input"
},
{
"type": "null"
}
],
"title": "Language"
}
}
],
"responses": {
@@ -1712,6 +1978,49 @@
]
}
},
"/api/v1/submissions/{submission_id}/performance": {
"get": {
"operationId": "performance_api_v1_submissions__submission_id__performance_get",
"parameters": [
{
"in": "path",
"name": "submission_id",
"required": true,
"schema": {
"format": "uuid",
"title": "Submission Id",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SubmissionPerformance"
}
}
},
"description": "Successful Response"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
"description": "Validation Error"
}
},
"summary": "Performance",
"tags": [
"submissions"
]
}
},
"/api/v1/submissions/{submission_id}/source": {
"get": {
"operationId": "source_api_v1_submissions__submission_id__source_get",
@@ -0,0 +1,248 @@
{
"$comment": "Anonymous bounded aggregates, decimal raw units and strict same-snapshot counts; also run model validation and server-side ownership/environment checks.",
"$defs": {
"Language": {
"enum": [
"c17",
"cpp20",
"python313",
"java21"
],
"title": "Language",
"type": "string"
},
"PerformanceBucket": {
"additionalProperties": false,
"properties": {
"count": {
"maximum": 10000,
"minimum": 0,
"title": "Count",
"type": "integer"
},
"end": {
"maxLength": 19,
"minLength": 1,
"pattern": "^(0|[1-9][0-9]*)$",
"title": "End",
"type": "string"
},
"start": {
"maxLength": 19,
"minLength": 1,
"pattern": "^(0|[1-9][0-9]*)$",
"title": "Start",
"type": "string"
},
"upper_inclusive": {
"title": "Upper Inclusive",
"type": "boolean"
}
},
"required": [
"start",
"end",
"upper_inclusive",
"count"
],
"title": "PerformanceBucket",
"type": "object"
},
"PerformanceMetric": {
"additionalProperties": false,
"properties": {
"available": {
"title": "Available",
"type": "boolean"
},
"buckets": {
"items": {
"$ref": "#/$defs/PerformanceBucket"
},
"maxItems": 64,
"title": "Buckets",
"type": "array"
},
"current": {
"anyOf": [
{
"maxLength": 19,
"minLength": 1,
"pattern": "^(0|[1-9][0-9]*)$",
"type": "string"
},
{
"type": "null"
}
],
"title": "Current"
},
"oldest_sample_at": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"title": "Oldest Sample At"
},
"reason": {
"anyOf": [
{
"enum": [
"not_accepted",
"measurement_missing",
"environment_unverified",
"insufficient_samples"
],
"type": "string"
},
{
"type": "null"
}
],
"title": "Reason"
},
"sample_count": {
"maximum": 10000,
"minimum": 0,
"title": "Sample Count",
"type": "integer"
},
"strictly_slower_count": {
"anyOf": [
{
"maximum": 10000,
"minimum": 0,
"type": "integer"
},
{
"type": "null"
}
],
"title": "Strictly Slower Count"
},
"tied_count": {
"anyOf": [
{
"maximum": 10000,
"minimum": 0,
"type": "integer"
},
{
"type": "null"
}
],
"title": "Tied Count"
},
"unit": {
"enum": [
"cpu_microseconds",
"bytes"
],
"title": "Unit",
"type": "string"
},
"window_truncated": {
"title": "Window Truncated",
"type": "boolean"
}
},
"required": [
"unit",
"current",
"available",
"reason",
"sample_count",
"window_truncated",
"oldest_sample_at",
"strictly_slower_count",
"tied_count",
"buckets"
],
"title": "PerformanceMetric",
"type": "object"
}
},
"$id": "urn:kf-oj:submission-performance:v1",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"as_of": {
"format": "date-time",
"title": "As Of",
"type": "string"
},
"comparison_group": {
"anyOf": [
{
"maxLength": 64,
"minLength": 64,
"pattern": "^[0-9a-f]{64}$",
"type": "string"
},
{
"type": "null"
}
],
"title": "Comparison Group"
},
"cpu": {
"$ref": "#/$defs/PerformanceMetric"
},
"kind": {
"const": "judge.performance",
"default": "judge.performance",
"title": "Kind",
"type": "string"
},
"language": {
"$ref": "#/$defs/Language"
},
"memory": {
"$ref": "#/$defs/PerformanceMetric"
},
"minimum_samples": {
"const": 5,
"default": 5,
"title": "Minimum Samples",
"type": "integer"
},
"problem_version_id": {
"format": "uuid",
"title": "Problem Version Id",
"type": "string"
},
"schema_version": {
"const": 1,
"default": 1,
"title": "Schema Version",
"type": "integer"
},
"submission_id": {
"format": "uuid",
"title": "Submission Id",
"type": "string"
},
"window_limit": {
"const": 10000,
"default": 10000,
"title": "Window Limit",
"type": "integer"
}
},
"required": [
"submission_id",
"problem_version_id",
"language",
"as_of",
"comparison_group",
"cpu",
"memory"
],
"title": "SubmissionPerformance",
"type": "object"
}
+134
View File
@@ -195,6 +195,23 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/v1/submissions/{submission_id}/performance": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** Performance */
get: operations["performance_api_v1_submissions__submission_id__performance_get"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/v1/submissions/{submission_id}/source": {
parameters: {
query?: never;
@@ -366,6 +383,43 @@ export interface components {
expires_at: string;
user: components["schemas"]["CurrentUser"];
};
/** PerformanceBucket */
PerformanceBucket: {
/** Count */
count: number;
/** End */
end: string;
/** Start */
start: string;
/** Upper Inclusive */
upper_inclusive: boolean;
};
/** PerformanceMetric */
PerformanceMetric: {
/** Available */
available: boolean;
/** Buckets */
buckets: components["schemas"]["PerformanceBucket"][];
/** Current */
current: string | null;
/** Oldest Sample At */
oldest_sample_at: string | null;
/** Reason */
reason: ("not_accepted" | "measurement_missing" | "environment_unverified" | "insufficient_samples") | null;
/** Sample Count */
sample_count: number;
/** Strictly Slower Count */
strictly_slower_count: number | null;
/** Tied Count */
tied_count: number | null;
/**
* Unit
* @enum {string}
*/
unit: "cpu_microseconds" | "bytes";
/** Window Truncated */
window_truncated: boolean;
};
/**
* PreparationKind
* @enum {string}
@@ -582,6 +636,53 @@ export interface components {
/** Next After */
next_after: string | null;
};
/** SubmissionPerformance */
SubmissionPerformance: {
/**
* As Of
* Format: date-time
*/
as_of: string;
/** Comparison Group */
comparison_group: string | null;
cpu: components["schemas"]["PerformanceMetric"];
/**
* Kind
* @default judge.performance
* @constant
*/
kind: "judge.performance";
language: components["schemas"]["kf_oj__contracts__judging_v2__Language"];
memory: components["schemas"]["PerformanceMetric"];
/**
* Minimum Samples
* @default 5
* @constant
*/
minimum_samples: 5;
/**
* Problem Version Id
* Format: uuid
*/
problem_version_id: string;
/**
* Schema Version
* @default 1
* @constant
*/
schema_version: 1;
/**
* Submission Id
* Format: uuid
*/
submission_id: string;
/**
* Window Limit
* @default 10000
* @constant
*/
window_limit: 10000;
};
/** SubmissionSource */
SubmissionSource: {
language: components["schemas"]["kf_oj__contracts__judging_v2__Language"];
@@ -920,6 +1021,8 @@ export interface operations {
query?: {
after?: string | null;
limit?: number;
problem_version_id?: string | null;
language?: components["schemas"]["Language-Input"] | null;
};
header?: never;
path?: never;
@@ -1042,6 +1145,37 @@ export interface operations {
};
};
};
performance_api_v1_submissions__submission_id__performance_get: {
parameters: {
query?: never;
header?: never;
path: {
submission_id: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Successful Response */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["SubmissionPerformance"];
};
};
/** @description Validation Error */
422: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["HTTPValidationError"];
};
};
};
};
source_api_v1_submissions__submission_id__source_get: {
parameters: {
query?: never;
@@ -0,0 +1,38 @@
{
"schema_version": 1,
"kind": "judge.performance",
"submission_id": "11111111-1111-4111-8111-111111111111",
"problem_version_id": "22222222-2222-4222-8222-222222222222",
"language": "python313",
"as_of": "2026-10-11T00:00:00Z",
"comparison_group": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"window_limit": 10000,
"minimum_samples": 5,
"cpu": {
"unit": "cpu_microseconds",
"current": "9007199254740993",
"available": true,
"reason": null,
"sample_count": 6,
"window_truncated": false,
"oldest_sample_at": "2026-10-10T00:00:00Z",
"strictly_slower_count": 2,
"tied_count": 1,
"buckets": [
{"start": "0", "end": "9007199254740993", "upper_inclusive": false, "count": 3},
{"start": "9007199254740993", "end": "9007199254740999", "upper_inclusive": true, "count": 3}
]
},
"memory": {
"unit": "bytes",
"current": "0",
"available": false,
"reason": "insufficient_samples",
"sample_count": 0,
"window_truncated": false,
"oldest_sample_at": null,
"strictly_slower_count": null,
"tied_count": null,
"buckets": []
}
}