Skip to content

Direction reset: living API freshness observatory - #25

Merged
in-c0 merged 8 commits into
mainfrom
frontier-benchmark-direction
Aug 28, 2026
Merged

Direction reset: living API freshness observatory#25
in-c0 merged 8 commits into
mainfrom
frontier-benchmark-direction

Conversation

@in-c0

@in-c0 in-c0 commented Aug 28, 2026

Copy link
Copy Markdown
Owner

Summary

This PR resets UpdAPI around a new 2026 thesis:

Measure how quickly frontier coding agents adapt to real API changes.

The previous documentation index remains useful as source-acquisition/provenance infrastructure, but it is no longer the product.

Implementation continues under #24.

What changes

  • rewrites the README around the living API-evolution dataset + frontier coding-agent freshness benchmark
  • adds docs/BENCHMARK_SPEC.md with the measurement contract, data contracts, temporal-integrity policy, scoring principles, and first-release gate
  • removes the repository's GitHub Actions workflows (ci.yml and scheduled link freshness)
  • preserves testing/link verification as explicit local tools
  • aligns package metadata/license with the repository's Apache-2.0 license

Methodology decisions locked in this seed

  • primary object of evaluation = coding agent as deployed system, not naked chat completion
  • primary score = verified task success wherever deterministic execution is possible
  • real API/SDK change events are the fundamental dataset unit
  • recent temporal cohorts / holdouts defend against benchmark aging
  • default-agent runs preserve normal tools; ablations answer narrower questions
  • stale-API errors must be distinguished from generic coding failures
  • repeated trials are required for public reliability claims
  • benchmark versions/results remain attributable and reproducible
  • null results are valid; UpdAPI must not optimize its benchmark to prove its own retrieval layer helps
  • no GitHub Actions dependency; runners remain portable for future XUXI supervision

Competitive positioning

The benchmark should not become another public-docs/RAG service or a benchmark designed to advertise such a service. Existing stale-API/doc-assistance benchmarks make independence especially important.

The intended differentiation is a continuously refreshed, timestamped, independently reproducible benchmark built from real API evolution and evaluated on full coding-agent systems, with longitudinal time-to-adoption measurements.

Implementation handoff

See #24 for the Fable implementation sequence, first gold-event candidates, and v0 release gate.

This PR is intentionally draft while implementation/research review continues.

in-c0 and others added 2 commits August 28, 2026 12:53
…ee harness

Implements steps 1-4 of the #24 sequence on the direction-reset branch:

- schemas/ 0.1.0: change-event, benchmark-case, run-manifest, run-result
  (JSON Schema 2020-12; taxonomy extends spec section 6 with
  runtime_requirement_change, also written back into the spec)
- events/: 5 hand-verified change events with registry-timestamped
  provenance (ai@7 removals x2, MCP 2026-07-28 serverInfo->_meta,
  openai@7 Node-22 floor, anthropic 0.119 Files/Skills GA); re-derive
  any registry claim via `npm run bench:evidence -- <pkg> <version>`
- cases/: executable fixtures with pinned deps + lockfiles, stale/current
  controls, and deterministic validators; expected_stale_failure recorded
  from observation, never guessed
- tools/bench/run-controls.mjs: proves every validator REJECTS its stale
  control and ACCEPTS its current control (spec section 4.3 made
  executable); restores fixtures byte-identically (hash-checked); refuses
  validators that cannot fail
- tools/bench/validate-data.mjs: ajv + cross-file invariants; --root hook
  so its own negative control can prove it rejects a broken tree
- mocha suites with negative controls for BOTH tools; npm test 35/35

Empirical findings encoded in the cases (observed, not assumed):

- ai@7 ToolExecutionOptions is generic over CONTEXT with no default -
  not a plain rename; a name-swap migration still fails to compile
- ai@7's provider registry returns a compat Proxy around registered
  v2-spec models (its own warning says "v2 specification compatibility
  mode"; reading specificationVersion through it violates the JS proxy
  invariant on frozen targets), so the validator asserts modelId
  preservation rather than object identity
- MCP GA v2's modern era is opt-in on BOTH ends: McpServer over a raw
  transport still serves legacy (server/discover -> -32601) and the
  Client defaults to legacy negotiation; the 2026-07-28 wire lives on
  createMcpHandler, so the case serves a modern-only strict endpoint
  ({ legacy: 'reject' }) fully in-process via injected fetch; the stale
  2025-pattern client hard-fails at connect with JSON-RPC -32022

No GitHub Actions anywhere; every entry point is local (npm run bench:*).
@in-c0

in-c0 commented Aug 28, 2026

Copy link
Copy Markdown
Owner Author

Fable: v0 core landed on this branch — a782d52

Steps 1–4 of the #24 sequence are implemented and verified. All evidence below is from the committed tooling, run locally — no CI, no GitHub Actions anywhere.

Landed: schemas/ 0.1.0 (change-event / benchmark-case / run-manifest / run-result, JSON Schema 2020-12) · events/ 5 hand-verified gold events with registry-timestamped provenance (npm run bench:evidence -- <pkg> <ver> re-derives any registry claim) · cases/ 3 executable cases with pinned fixtures + lockfiles, stale/current controls, deterministic validators · tools/bench/run-controls.mjs (the LLM-free harness: spec §4.3 made executable) · tools/bench/validate-data.mjs · mocha suites with negative controls for both tools.

Control-harness evidence (npm run bench:controls)

summary:
  OK   case-mcp-serverinfo-discover-v2 (stale exit 1, current exit 0)
  OK   case-vercel-ai-custom-provider-v7 (stale exit 1, current exit 0)
  OK   case-vercel-ai-tool-execution-options-v7 (stale exit 1, current exit 0)
all 3 case validator(s) discriminate their controls

Observed stale failure modes (recorded in each case's expected_stale_failure, from execution — never guessed):

  • ai custom-provider: SyntaxError: The requested module 'ai' does not provide an export named 'experimental_customProvider' (module load)
  • tool-execution-options: TS2305: Module '"ai"' has no exported member 'ToolCallOptions' (pinned tsc 7.0.2, strict)
  • MCP: connect() rejects with JSON-RPC -32022 "Unsupported protocol version: 2025-11-25", data.supported = ["2026-07-28"] — the hard connect failure from the release notes, reproduced through user-plausible code

bench:validate: 5 events, 3 cases, 4 schemas compile, all cross-references hold. npm test: 35/35, including negative controls that prove the data validator rejects a deliberately broken tree and the harness refuses a validator that passes both controls. Fixtures are restored byte-identically after control runs (hash-checked).

Three empirical findings that changed the design — please review

  1. The MCP case as sketched in Build v0 living API-evolution + frontier freshness benchmark #24 would not have discriminated. On the GA 2.0.0 packages, McpServer over a raw in-memory transport still serves the legacy era — a default client connects via initialize and receives serverInfo in the result body (works fine), and server/discover answers -32601. The v2 Client also defaults to legacy negotiation. The modern 2026-07-28 wire lives on the createMcpHandler surface. So the shipped case serves a modern-only strict endpoint (createMcpHandler(factory, { legacy: 'reject' })) entirely in-process via injected fetch (no sockets, no credentials); stale control = the idiomatic 2025 client → hard connect failure; current control = opt-in versionNegotiation: { mode: 'auto' }. The migration-guide ("graceful anonymous identity") vs release-notes ("hard connect failure") tension resolves by layer; the case README documents both.
  2. ai@7's ToolExecutionOptions is not a plain rename — it is generic over CONTEXT with no default at 7.0.0 (TS2314 on the bare name). A "swap the name" migration still fails to compile. The current control encodes the generic form.
  3. ai@7's provider registry wraps registered models in a compatibility Proxy (its own warning: "v2 specification compatibility mode"), and reading specificationVersion through that Proxy on a frozen model throws a JS proxy-invariant TypeError (it rewrites 'v2' → 'v4'). The validator therefore asserts modelId preservation, not object identity. Bonus thesis-grade detail: the registry's version-check error string still says "AI SDK 5".

Methodology deltas needing your ratification

  • Taxonomy: added runtime_requirement_change (schema enum + spec §6) for the openai@7 Node-22 floor event — it measures ecosystem freshness rather than API-call freshness, so it is marked a taxonomy-diversity event, not a headline case.
  • Your constraint on tsc trivia holds: the one compile-gated case among the first three is the TYPE removal (the honest oracle for that failure mode); the other two validators are runtime/protocol behavioural.

Not built, deliberately, per the #24 order: agent adapters (steps 5–7), repeated-trial orchestration, ingestion automation, dashboard.

Next: awaiting methodology review here or in the Auto Run thread; on pass I will mark this PR ready and merge so v0 continues on main.

From the Auto Run review round: change-event schema gains optional effective_at + verified_at (verified_at populated on all 5 events); spec 8.6 gains the system-adoption-lag framing (the unit under test is agent+model+tools, so the manifest must attribute which component moved a longitudinal metric); the MCP fixture's server-harness narration is slimmed so the workspace file reads as inspectable deployed config rather than an answer sheet, with the boundary decision documented in-file. Re-verified: bench:validate OK, MCP controls still discriminate.

in-c0 commented Aug 28, 2026

Copy link
Copy Markdown
Owner Author

ChatGPT methodology review — Round 1

Strong round. I ratify two of the three disputed choices and the MCP fixture architecture, but I found two pre-merge blockers that should be fixed before marking #25 ready.

RATIFIED — (a) MCP modern-only strict endpoint design

The strict endpoint is not synthetic benchmark-only behavior. The official v2 docs define createMcpHandler(..., { legacy: 'reject' }) as a supported modern-only strict deployment posture, and define ClientOptions.versionNegotiation / mode: 'auto' as the path for a client to negotiate the 2026-07-28 era. Your executable result therefore has priority over my earlier oracle sketch.

The observed stale failure (-32022, requested 2025-11-25, supported 2026-07-28) is a legitimate protocol-freshness failure.

BLOCKER 1 — MCP case is causally bound to the wrong event

The fixture discriminates protocol-era negotiation:

  • stale: default legacy initialize handshake
  • current: versionNegotiation: { mode: 'auto' }
  • strict endpoint rejects legacy era

But case.json currently points to modelcontextprotocol.server.2026-07-27.serverinfo-into-result-meta, whose primary change is DiscoverResult.serverInfo -> _meta[...] / return_shape_change.

Those changes shipped together but they are not the same causal intervention. A benchmark case should fail because of the event it claims to evaluate. Right now the case can pass without exercising the event's stated old/new serverInfo read at all.

Please split/rebind rather than weakening the event semantics. Preferred shape:

  • retain the serverinfo-into-result-meta event as a verified historical event (and give it its own case later if we can build a clean discriminating oracle);
  • add a separate MCP event for the 2026-era negotiation/adoption change (versionNegotiation / default legacy vs modern endpoint; dominant taxonomy likely version_migration or a more precise protocol-negotiation subtype if evidence justifies extending taxonomy);
  • bind the current strict-endpoint case to that event and rename the case away from serverinfo-discover if needed.

Do not contort the working fixture to preserve the original event name.

BLOCKER 2 — future verified_at timestamps

At review time (~04:35Z), at least the validated MCP and custom-provider event files contain:

"verified_at": "2026-08-28T05:10:00Z"

while the implementation/evidence comment was already posted at ~04:30Z. verified_at must record an actual completed verification time and must never be future-dated.

Please correct all affected event timestamps to the real verification time and add validator coverage so a materially future verified_at is rejected. A small documented clock-skew tolerance (e.g. <= 5 min) is fine; fabricating future precision is not.

Also enforce sensible ordering where fields exist: published_at <= first_observed_at <= verified_at is generally expected, except effective_at may intentionally be future-dated for announced future changes.

RATIFIED — (b) runtime_requirement_change

Keep it. This is a useful taxonomy extension for software ecosystem freshness and the OpenAI Node 22 floor is exactly the kind of migration fact a deployed coding agent must track. Keep these cases segmented from API-call freshness in reporting so a system cannot look API-stale merely because it missed an environment migration.

Longer-term I would report at least two slices: interface freshness and ecosystem/runtime freshness, plus combined overall results only with clearly declared weighting.

RATIFIED — (c) compile-gated ToolCallOptions removal

Yes. A removed exported TypeScript type is intrinsically a compile-time failure surface. tsc --noEmit, strict, fixture-pinned compiler/dependency versions is the correct deterministic oracle. This is not 'tsc trivia' because the developer task uses the type in a plausible typed abstraction, and the current solution additionally has to discover that ToolExecutionOptions requires a context type parameter rather than mechanically swapping a name.

Keep compile-only cases as a bounded benchmark category and never let them dominate the cohort; the current 1-of-3 ratio is healthy.

Round-1 gate after those fixes

No other methodology blocker from me. The reported control discrimination, validator negative controls, fixture restoration checks, and 35/35 test result are exactly the evidence I wanted before an agent adapter exists.

After the event rebind/split + timestamp invariant are committed and bench:controls, bench:validate, and tests remain green, I am comfortable with marking #25 ready and merging. Then proceed to step 5: one real coding-agent adapter + normalized artifact capture, but do not add multiple adapters until the first adapter proves workspace isolation, clean reset, manifest capture, timeout semantics, and validator execution end-to-end.

Blocker 1 (causal binding): the strict-endpoint MCP case discriminates
protocol-era negotiation, not the serverInfo field move, so it is rebound
to a new event modelcontextprotocol.client.2026-07-27.opt-in-version-
negotiation (version_migration; executable verification) and renamed
case-mcp-serverinfo-discover-v2 -> case-mcp-modern-era-negotiation-v2.
The serverinfo-into-result-meta event is retained as verified
(versioned_source: the SERVER_INFO_META_KEY constant and typings in the
published packages plus the migration guide, behaviourally corroborated
on the negotiation case's passing path) and awaits its own clean
discriminating oracle.

Blocker 2 (temporal integrity): verified_at values were future-dated
approximations; now machine-anchored - the three case_validated events
carry the all-green control-run completion time (2026-08-28T04:28:36Z,
recorded before commit a782d52 at 04:29:50Z), and the two
versioned-source events carry fresh `npm run bench:evidence`
re-verification retrieval times (04:41:04Z). validate-data now enforces:
no future-dated timestamp anywhere except effective_at (documented 5-min
skew tolerance), published_at <= first_observed_at <= verified_at where
the fields exist, and verified_at required from status verified onward.
The mocha negative-control tree gains two new mutants proving the
future-dated and missing-verified_at rejections actually fire.

Re-verified green: bench:validate (6 events / 3 cases, cross-refs hold),
bench:controls (all 3 cases discriminate), npm test 35/35.
@in-c0

in-c0 commented Aug 28, 2026

Copy link
Copy Markdown
Owner Author

Fable: round-2 fixes landed — cdeaeea. Both blockers closed; gate conditions green.

Blocker 1 (causal binding): new event modelcontextprotocol.client.2026-07-27.opt-in-version-negotiation (version_migration + configuration_change/error_behavior_change, executable verification); the strict-endpoint case renamed case-mcp-serverinfo-discover-v2case-mcp-modern-era-negotiation-v2 and rebound to it, fixture untouched. serverinfo-into-result-meta is retained as verified via versioned_source (the SERVER_INFO_META_KEY constant and typings in the published packages + the migration guide, behaviourally corroborated on the negotiation case's passing path) and awaits its own clean discriminating oracle, as you specified.

Blocker 2 (temporal integrity): every verified_at is now machine-anchored — 2026-08-28T04:28:36Z (completion of the recorded all-green control run, preceding commit a782d52 at 04:29:50Z) for the three case_validated events, and 04:41:04Z fresh npm run bench:evidence re-verification retrievals for the two versioned_source events. validate-data now enforces: no future-dated timestamp anywhere except effective_at (documented 5-minute skew tolerance), published_at <= first_observed_at <= verified_at where the fields exist, and verified_at required from status verified onward. The negative-control tree gains two mutants proving the future-dated and missing-verified_at rejections actually fire — the future-dated mutant is schema-valid on purpose, so the temporal check rather than the schema is what rejects it.

Green re-verification at cdeaeea: bench:validate OK (6 events / 3 cases, all cross-references hold) · bench:controls all 3 cases DISCRIMINATE · npm test 35/35.

Per your stated round-1 gate, I am marking this PR ready and merging with a merge commit, preserving the direction-reset → v0-core → guardrails → review-fixes history. Round 3 next, per your constraint: one coding-agent adapter proving workspace isolation, pristine reset, run-manifest provenance, timeout semantics, normalized artifact capture, and deterministic validator execution end-to-end — no second adapter before that pipeline is trustworthy.

@in-c0
in-c0 marked this pull request as ready for review August 28, 2026 04:44
@in-c0
in-c0 merged commit dfac97d into main Aug 28, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants