Skip to content

Latest commit

 

History

History
187 lines (115 loc) · 6.87 KB

File metadata and controls

187 lines (115 loc) · 6.87 KB

Provider Authoring Surface v0 Draft

1. Scope

This document defines the author-facing registration model used by language-specific provider libraries.

It sits above the provider host protocol in 10-provider.md.

This document is normative for authoring semantics. It does not change the required host list and run transport.

2. Design Goal

Provider libraries MUST optimize for the common path where authors write human test titles first and do not manually maintain protocol-shaped registration tables.

That author-facing convenience MUST still lower to explicit deterministic contract data before Observer sees the provider inventory.

The required rule is:

  • human-first authoring at the library surface
  • explicit deterministic identity at the provider boundary
  • no heuristic recovery after registration

The platform requirement is convergence of semantics, not uniformity of syntax.

Provider libraries for different languages MAY expose different author-facing APIs when that improves ecosystem fit, as long as they all lower into the same deterministic provider boundary.

3. Authoring Model

A provider library SHOULD expose a familiar test authoring surface appropriate for its ecosystem.

Different ecosystems are expected to choose different shapes here.

For example:

  • TypeScript may expose describe(...), test(...), and expect(...)
  • C may expose Test(...), TestId(...), and observe_assert(...)

Those surfaces do not need to look alike. They do need to lower to the same explicit registration semantics.

For ecosystems with nested suites, that usually means concepts equivalent to:

  • describe(...) for human grouping
  • test(...) or it(...) for a human test title
  • assertion helpers such as expect(...)

Those author-facing names are not themselves the required provider protocol payload. They are source inputs used to derive provider registrations.

4. Identity Model

Each registered test MUST resolve to a deterministic provider-local identity before the host list result is produced.

Provider libraries SHOULD support two identity modes:

  1. derived identity for the common path
  2. explicit identity override for refactor-stable registrations

The common path SHOULD allow authors to omit explicit identity and write only human suite titles and test titles.

When explicit identity is omitted, the provider library MUST derive identity mechanically from explicit registration data already present at authoring time, such as:

  • suite path
  • test title
  • duplicate occurrence order within the registration stream

The derivation algorithm MUST be deterministic.

The provider library MUST NOT infer identity from volatile or heuristic sources such as:

  • source file paths when they are not explicit contract data
  • line numbers
  • runtime stack inspection
  • object traversal order not already defined by the language surface
  • localized display formatting

When a provider library exposes an explicit identity override, the field SHOULD be called id unless the ecosystem has a stronger established term.

An explicit id, when present, MUST win over derived identity.

5. Lowering Requirement

Before host discovery output is emitted, the provider library MUST materialize each authored test into explicit provider registration data containing at least:

  • canonical inventory name to publish through list
  • stable execution target to publish through list
  • executable function or equivalent run binding

That lowering step MUST be complete before the provider host returns its visible test set.

Observer core MUST receive only explicit registration data at the provider boundary. It MUST NOT reconstruct missing identity later.

6. Uniqueness And Validation

Provider libraries MUST reject duplicate resolved identities.

Validation MUST happen on the materialized registration set, not only on the author-facing inputs.

At minimum, a provider library MUST reject:

  • empty explicit identity values
  • duplicate resolved canonical names if canonical names are derived from identity
  • duplicate execution targets
  • missing executable bindings

Validation errors are provider errors. They are not test failures.

7. Deterministic Ordering

The visible registration set produced by the provider library MUST be ordered deterministically before it is exposed through list.

If authoring order is part of the derivation algorithm, that order MUST be mechanically defined by the registration API.

If the provider library sorts registrations before exposure, the sort keys MUST be explicit and stable.

8. Observation Context

Provider libraries MAY expose bounded observational helpers to test code.

If they do, those helpers:

  • MUST be explicit opt-in at the test surface
  • MUST emit observational data only
  • MUST NOT alter canonical identity, pass or fail status, inventory hashes, or suite hashes

Representative forms include metrics, vectors, and tags.

If a provider library exposes more than one assertion-like form, those forms SHOULD preserve meaningful semantic distinctions rather than differing only cosmetically.

For example, a language surface may distinguish between:

  • ordinary assertions about observed behavior
  • invariants about test validity, setup integrity, or harness assumptions

Those categories MAY share implementation initially, but the semantic distinction SHOULD remain explicit so reporting and tooling can differentiate them later.

9. First-Cut TypeScript Shape

The current TypeScript library in this repository is the reference example for this authoring model in v0.

Its intended surface is:

describe("database", () => {
  test("access to the database", () => {
    expect(connect().connected).toBeTruthy();
  });
});

With optional explicit identity:

test("access to the database", { id: "database/access" }, () => {
  expect(connect().connected).toBeTruthy();
});

With optional observation:

test("access to the database", { id: "database/access" }, ({ observe }) => {
  observe.metric("wall_time_ns", 104233);
  observe.vector("request_latency_ns", [1000, 1100, 980]);
  observe.tag("resource_path", "fixtures/config.json");
  expect(true).toBeTruthy();
});

In this first cut, the resolved identity is used for both the published canonical name and the provider execution target.

That coupling is an implementation choice, not a permanent platform requirement.

10. Cross-Language Boundary Rule

Observer does not require provider libraries to share one author-facing DSL across languages.

It does require them to share one lowered semantic boundary.

That means all provider libraries, regardless of surface syntax, MUST converge on the same properties before the host protocol boundary:

  • explicit resolved identity
  • explicit executable binding
  • explicit published canonical name
  • explicit execution target
  • deterministic validation
  • deterministic visible ordering

This is the level at which cross-language consistency is enforced.