Skip to content

fix(webmcp-audit): regenerate contract 1.40.0 and re-sync the WebMCP engine - #93

Merged
liady merged 3 commits into
mainfrom
claude/epic-bohr-r0eoz9
Nov 9, 2026
Merged

liady merged 3 commits into
mainfrom
claude/epic-bohr-r0eoz9

Conversation

@liady

@liady liady commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

What

Fixes the red main build and brings ax webmcp-audit back in line with ora.ai's own audit.

  • Contract 1.40.0: src/contract/types.gen.ts and version.ts are regenerated from production, which now serves 1.40.0. The scheduled "Contract drift vs production" job had been failing on 1.38.0.
    • openapi-typescript v6 rejected Ora's ScoringManifest.switches shape, a string property next to boolean additionalProperties. scripts/contract-gen.mjs now widens that index signature on its working copy only, and output stays deterministic.
  • "Couldn't verify" checks in the report: checks with status: "na" and naKind: "unverified" now get their own "Couldn't verify (N)" group in the terminal report, shown by default. Before, they were hidden among the skipped checks, so CLI users will see this change.
  • WebMCP engine re-sync: src/webmcp/vendor/ is re-copied from Ora's engine. The shim version stays 3.
    • New from Ora: the consequential-hint check, with the trust weights rebalanced to make room; the 2026-11-04 spec snapshot (outputSchema); declarative forms no longer counted as tools; static-signal hardening; and two new vendored files.
    • capture.ts now keeps consequentialHint and debugging in annotations, reads the top-level title and outputSchema, and counts imperative tools only, the same as Ora's capture server.
    • Before this, a page declaring consequentialHint scored lower through ax webmcp-audit than on ora.ai.
  • README: 19 checks becomes 20.

Why

The WebMCP draft added outputSchema on 2026-11-02, and Ora's engine moved on in the four weeks since the last sync without bumping the shim. So the version check could not catch the skew (AGENTS.md rules 11 and 12).

#49 (shim v1 vs v3) was already fixed in 0.10.1 and is not addressed here.

Checks

  • pnpm lint && pnpm typecheck && pnpm test pass locally: 263 passed, 2 live tests skipped. pnpm build, smoke, verify:pack and smoke:webmcp (local Chromium) also pass.
  • Behavior change is covered by a test: the mapping functions in capture.test.ts, the unverified grouping in model.test.ts and terminal.test.ts, and the live test, which now also asserts title, outputSchema, consequentialHint and debugging.

Known: capture.live.test.ts fails on nativeApi here because the container's Chrome 153 ships WebMCP natively. It failed the same way before this change. CI's real-browser job may hit the same failure on Chrome 153 or later.


Generated by Claude Code

Production ora.ai now serves contract 1.40.0, so the scheduled contract
drift job was red against the 1.38.0 artifacts. Regenerated with
pnpm contract:gen. New optional fields: naKind "unverified" on na checks,
scanId / scoringVersion / rulesUrl / scoringRevision on results, plus the
scoring rules and deep-check schemas.

The 1.40.0 spec declares ScoringManifest.switches with a string property
beside boolean additionalProperties. That is valid JSON Schema but
openapi-typescript v6 emits an index signature that does not cover the
declared property, which TypeScript rejects. contract-gen now widens such
an additionalProperties to also accept the declared property schemas, on
the copy used for type generation only, so the output stays deterministic
and compiles.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NWyUpHag7bt1zdBaUZ9TBH
Contract 1.40.0 marks an na check with naKind "unverified" when it applies
but could not be checked (a bot shield answered, the server wanted
credentials, a request went unanswered). The report used to fold those
into the hidden "skipped" (not applicable) group. They now get their own
"Couldn't verify" group, shown by default, and their own count in the
section tally. They stay out of the passed/total counts, as ora skips them
without a deduction.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NWyUpHag7bt1zdBaUZ9TBH
Re-copies src/webmcp/vendor/ from ora main (8cd44519, contract 1.40.0) so
`ax webmcp-audit` measures a page the way ora's worker does. The shim
version stays "3", as it is upstream.

Engine changes that came in:
- checks: the new consequential-hint check (trust, weight 3), with the
  annotation checks moved 5/5 -> 4/4 and hint-vs-observed 4 -> 3; spec
  snapshot 2026-11-04 and WEBMCP_RUNTIME_COMPATIBLE_SPEC_SNAPSHOTS.
- types: consequentialHint and debugging annotations, the tool's
  top-level title, outputSchema, the consequential-hint check id.
- shim: records each tool's title and outputSchema, and reads each
  declarative form's fields (with caps) for its synthesized schema.
- capture-verdict: declarative forms no longer count as tools
  (verdictWithoutForms).
- static-signals: word-bounded modelContext entry points, a
  `.modelContext` read plus `.registerTool(` as a marker, inline scripts
  filtered by type, bounded chunk-reference parsing. The new helpers that
  need cheerio or htmlparser2 are dropped, as before.
- new: declarative-schema.ts (the form schema derivation) and
  script-type.ts (isJavaScriptScriptType), both used on the capture path.
- projection and security-challenge: unchanged upstream.

capture.ts now mirrors capture-server.ts again: mapAnnotations keeps
consequentialHint and debugging, mapShimTools reads the top-level title
and outputSchema, declarative tools are capped and get the engine's
derived schema, the verdict counts imperative tools only, and the inline
scripts pass C reads are filtered with the vendored isJavaScriptScriptType
(cdp.ts now returns each inline script's type attribute).

README says 20 checks; AGENTS.md rule 11 lists the new vendored pieces
and the wider static-signals deviation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NWyUpHag7bt1zdBaUZ9TBH
@liady
liady requested a review from a team as a code owner November 9, 2026 12:17
@liady
liady merged commit 4868b46 into main Nov 9, 2026
11 checks passed
liady added a commit that referenced this pull request Nov 14, 2026
## What

This regenerates `src/contract/types.gen.ts` and
`src/contract/version.ts` from production ora.ai, which now serves
contract 1.41.0 (`BUILT_AGAINST` moves from 1.40.0 to 1.41.0). The only
shape change is that partner keys can now have a daily usage limit as
well as the monthly one: `GET /api/usage` gains a `day` period next to
`month`, and the `usage_limit_reached` 429 can carry `period: "day"`.
CLI users stop getting the stale-contract warning. A daily-limit refusal
already renders as "...for the day", because `src/api/shared.ts` prints
`period` as given, so no code change is needed. The rest of the diff is
regenerated description text and the `contractVersion` literals.

## Why

The scheduled "Contract drift vs production" job has failed on `main`
every day since 2026-11-10, because ora.ai shipped 1.41.0 after #93
regenerated against 1.40.0. Regenerated with `pnpm contract:gen`.
Nothing is hand-edited (AGENTS.md rule 2).

## Checks

- [x] `pnpm lint && pnpm typecheck && pnpm test` pass locally: `pnpm
test:ci` ran 263 tests, all passed, and skipped the 2 live tests. `pnpm
build`, `pnpm smoke` and `pnpm verify:pack` also pass.
- [ ] Behavior change is covered by a test: no behavior change. The new
fields are additive and only appear in generated types. The 429 message
path that reads `period` is already covered for the monthly case.

---
_Generated by [Claude
Code](https://claude.ai/code/session_01NWyUpEjizn6zSU5ewC9Wis)_

Co-authored-by: Claude <noreply@anthropic.com>
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