Skip to content

ADR 0012: Response Envelope and Uncertainty Semantics

ADR 0012: Response Envelope and Uncertainty Semantics

Status: Accepted for architectural direction.

Date: 2026-05-11.

Context

The backend will answer student-facing academic queries.

Some source requirements will be parsed exactly.

Some source requirements will remain unparsed in early versions.

Some query answers will depend on user-provided grades or academic progress.

Some query answers will depend on catalog versions that may not be loaded.

The frontend needs a consistent way to display answers, warnings, source references, and uncertainty.

The backend should not hide uncertainty inside prose.

The backend should not force every academic query into true or false.

ADR 0005 already established that unparsed requirements are first-class data.

This ADR defines the response shape that carries that decision through the API.

Decision

Every successful JSON API response will use a common envelope.

The envelope has:

  • data;
  • meta;
  • warnings;
  • unknowns;
  • source_references.

Every error JSON response will use:

  • error;
  • meta;
  • warnings;
  • unknowns;
  • source_references.

meta must include API version and loaded index metadata when available.

warnings must contain machine-readable non-fatal issues.

unknowns must contain machine-readable semantic uncertainty.

source_references must contain source provenance used by the response.

Query result statuses must use:

  • satisfied;
  • not_satisfied;
  • partial;
  • unknown;
  • conflict;
  • not_applicable.

Unparsed requirements that can affect an answer must produce unknown or a response-level unknown entry.

Missing user grade data that can affect an answer must produce unknown or a specific missing-data warning.

Catalog mismatch must be explicit.

Catalog unavailability must be explicit.

State-dependent responses must not be publicly cacheable.

Catalog-only responses may be publicly cacheable.

HTTP caching policy should follow RFC 9111, including restrictive directives such as no-store for sensitive responses: RFC 9111.

HTTP method choice should follow RFC 9110 safe and idempotent method semantics: RFC 9110.

Envelope Example

{
"data": {
"target": {
"course_code": "CS 246"
},
"status": "partial",
"missing": [],
"unknown_requirement_ids": ["unparsed_requirement:req_123"]
},
"meta": {
"api_version": "v1",
"index_id": "idx_2026_2027_undergrad_20260511_001",
"index_schema_version": "0.1.0",
"catalog_version_id": "uw_undergrad_2026_2027",
"upstream_catalog_id": "67e557ed6ed2fe2bd3a38956"
},
"warnings": [],
"unknowns": [
{
"code": "unparsed_requirement",
"requirement_id": "unparsed_requirement:req_123",
"message": "A source requirement fragment could not be parsed into structured conditions."
}
],
"source_references": [
{
"source_reference_id": "src_ref_456"
}
]
}

Consequences

The frontend can build one uncertainty rendering system.

The backend can keep semantic uncertainty separate from HTTP transport errors.

The project can improve parser coverage without changing the response contract.

Source references remain visible in query and graph responses.

The API becomes slightly more verbose.

The verbosity is acceptable because the app is source-sensitive and advisory.

Clients must handle unknown and partial as first-class statuses.

Tests must assert unknown propagation.

Alternatives Considered

Alternative 1: Plain Endpoint-Specific JSON Only

Each endpoint could define its own response shape.

This is initially lighter.

However, it would duplicate metadata, warning, unknown, and source-reference handling.

It would make frontend rendering inconsistent.

This alternative is rejected.

Alternative 2: Boolean Query Results

Queries could return true or false.

This is easy to consume.

However, Waterloo requirements include grade thresholds, nested choices, academic progress, program restrictions, antirequisites, and unparsed source fragments.

Boolean responses would hide why an answer is uncertain or partial.

This alternative is rejected.

Alternative 3: Treat Unknowns as Errors

The backend could return HTTP errors when it cannot fully answer a query.

This would force users to notice uncertainty.

However, a query can be valid and useful even when some parts are unknown.

HTTP errors should describe request or server failure.

Semantic uncertainty should be represented in the result.

This alternative is rejected.

Follow-Up

Define exact warning object schema.

Define exact unknown object schema.

Define exact source reference summary schema.

Define per-endpoint response payload schemas.

Add tests that ensure unparsed requirements cannot disappear from relevant answers.