comp: re-baseline comp.proto to canonical CoMP V1 (breaking) - #9
Conversation
Re-align proto/comp/v1/comp.proto to a 1:1 mirror of IAB Tech Lab CoMP V1 (finalized 2026-04-28, CoMP-1.0.md). The prior snapshot mirrored a pre-final draft with a separate License surface. - Remove the License message, LicenseUse enum, and Package.license; canonical V1 has no License object. - Fold licensing into Scope: add ause (AllowedUse enum), pricetype (PriceType enum), pricetier, unitprice, cur (default "USD"), country (repeated int32, ISO-3166 numeric), licensedur (days). - Add Package.reporturl. - Add per-media taxonomy cattax (default 9), cat, language to Text/Video/ Image/Audio. - Remove non-CoMP RAMP-invented fields: Text.authority, Text.originality, Image.alt, Image.caption, media c2pa, Retrieval.ratelmt. - Add RETRIEVAL_AUTH_OTHER = 4. Request-side model (AISystem/AISystemUse, Function/SubFunction/AuthMethod/ ScopeType/ContentType) unchanged. Regenerated Go + TS SDKs. Accepted breaking change pre-v1 freeze of the CoMP profile.
…ypes Vendor the 8 worked examples from the IAB Tech Lab CoMP V1 specification (CoMP-1.0.md) as testdata and add a conformance gate that unmarshals each request/response payload into the generated comp.v1 root type with default protojson options (unknown-field rejection on), then re-marshals and asserts every spec value is preserved. Examples are pinned to the spec-file content blob on main (the release tag 1.0-202604 carries only a boilerplate README, not the specification); the provenance and pin are recorded in the testdata README.
…vision Link comp.proto and both CoMP profile docs (ext-comp.mdx, extension-profiles.mdx) to the content-addressed CoMP V1 spec blob (aa8c796be7a9bcfa1189a1cf6c1ec50aa67a0f5f, main commit 880238e) instead of the moving blob/main ref, so the source revision is trackable. The 1.0-202604 release tag does not contain CoMP-1.0.md (it was added to main after the tag), so the tag is unusable as a provenance pin. Also correct the profile docs to V1: "Content Monetization Protocols" (not "Metadata Protocol"), CoMP V1 (not v2.0), nested ext.comp object, and licensing via Scope (drop the removed License object / LicenseUse).
890d308 to
0ef2e50
Compare
…ture The 8 verbatim IAB CoMP V1 worked examples never populate the commercial block the re-baseline exists to add (ause, pricetype, pricetier, unitprice, cur, country, licensedur) or the per-asset language/update fields, so a rename/retype/renumber of any of them would round-trip green. - Add testdata/comp_v1_synthetic/ (RAMP-authored, kept separate from the blob-pinned verbatim set) with commercial_terms.package.json exercising the full commercial block + packager/reporturl + Text.update/Text.language. - Add TestCompV1SyntheticCoverageRoundTrip: same adversarial round-trip as the verbatim gate, plus an anti-vacuity floor (requiredSyntheticCoverage) that asserts each fixture still carries the fields it exists to cover. - Factor the shared round-trip into jsonFilesIn + roundTripExample so the new test adds no duplication; replace the hand-rolled itoa with strconv.Itoa.
… V1 surface The re-baseline updated this page's intro prose but left its field tables describing the removed pre-final model, so the same profile was documented two contradictory ways. - Remove the deleted License model (comp.license[].use/duration_months/ maxword/revshare), the comp.revshare :::note, and comp.retrieval_ratelimit. - Correct the drifted enum value lists to the proto: retrieval_auth (0-4, incl. ssl/other), retrieval_type (html..newsml/other), scope_type (full_corpus..other). - Add the Commercial Terms section (ause/pricetype/pricetier/unitprice/cur/ country/licensedur), comp.report_url, and per-asset taxonomy (cattax/cat/language); add a CoMP-field column mapping each ext key to its proto field, and a note that CoMP V1 has no separate License object.
…xt media The synthetic anti-drift fixture pinned only Package/Scope commercial fields, leaving the request side and the Video/Image/Audio/Retrieval branches (and the google.protobuf.Struct ext field on every message) to whatever the verbatim IAB examples happen to populate — so those could be renamed/retyped/renumbered and still round-trip green. - Add full_request.aisystem.json: AISystemUse lid/aiauth/uri/scope/function/ subfn/resdis + ext at both levels. - Add media_assets.package.json: Video/Image/Audio assets and Retrieval, plus ext at the package, scope, asset, and retrieval levels. - Extend requiredSyntheticCoverage with anti-vacuity entries for both, so the added coverage cannot silently regress.
Add the JSONL push-feed page (ramp-ingest -> PushResources): record + term schema, all-or-nothing semantics, extension-profile handling, and a worked example. Wire it into the Protocol sidebar after Discovery Paths.
legendko
left a comment
There was a problem hiding this comment.
Headline verdict
The implementation core (proto + SDKs + conformance test) is correct, faithful,
and well-engineered. Approve the code. No Critical issues; no security or
layering regression; the breaking change is intentional, documented, and
buf-confirmed (see §4).
The documentation is not in conformance and must be reconciled before merge.
Several site pages still present the removed CoMP model as current, and the
branch introduced a broken intra-site anchor that ships silently (the
starlight-links-validator safety net the impl-note relied on does not exist in
this repo). Per the task mandate ("the implementation must be in full conformance
with the documentation; conflicts must be resolved"), these are in-scope and the
resolution is to update the docs (the V1 re-baseline is the intended change,
so the docs are what is wrong).
1. Consolidated issue list (orchestrator-validated severities)
Severity reconciles the subagents' grades with first-hand evidence. Where the
orchestrator changed a subagent's grade, the original is shown and justified.
HIGH
H1 — Documentation presents the removed CoMP model as current + a dead anchor ships silently.
Direct violation of the "full conformance with documentation" requirement.
Confirmed first-hand (grep + file reads + a real website build):
website/src/content/docs/protocol/licensing-terms.mdx:123— references removedcomp.license[].revshareand links/protocol/ext-comp/#license-on-offerext; this branch deleted that heading fromext-comp.mdx(it is now### Commercial Terms), so the anchor is dead.website/src/content/docs/protocol/standards-layering.mdx:13,137-139,170-171— documents removedLicense/LicenseUse/ratelmt/Text.authority/originality/Image.alt/caption/media-c2paas current, under a misleading "CoMP v2.0" label (these were a dropped pre-final draft, not a future v2).website/src/content/docs/protocol/ext-c2pa.mdx:265— claims CoMPVideo.c2pa/Image.c2pa/Audio.c2pastill exist. Not covered by impl.md's "PR #8" carve-out — overlooked.
Validation note (revised after the PR #8 cross-check — see §6a): the consistency
subagent called the dead anchor a "links-validator build break." Corrected
twice: the validator is not installed in the repo today, so today's website
build succeeds (76 pages) and the broken link is currently silent.
However, PR #8 adds starlight-links-validator to the build, and PR #8 was
confirmed not to fix the link — so once PR #8 reaches main the dead anchor
becomes a hard CI failure for whichever of {this branch, PR #8} merges second.
The impl-note's mitigation ("PR #8's starlight-links-validator will catch it") is
mechanically right about the validator's origin but wrong about the outcome: being
"caught" means a RED build, and the fix is in neither branch.
Resolution: update all three pages to the CoMP V1 surface and repoint/remove
the #license-on-offerext link in licensing-terms.mdx. PR #8 was confirmed (§6a)
to fix none of the three, so the "owned by PR #8" deferral is void.
H2 — reference/changelog.mdx not updated for a breaking change.
reference/changelog.mdx [is a] hand-maintained mirror of proto/CHANGELOG.md.
After meaningful proto changes, update both." proto/CHANGELOG.md
gained a breaking "Unreleased" entry (:3-29); the website mirror has none and
:74 keeps the pre-rebaseline "Package, Function, Scope as optional ext fields"
framing. Explicit instruction not followed. Resolution: mirror the Unreleased
entry into reference/changelog.mdx.
MEDIUM
M1 — No reserved for removed fields; field-number reuse is a binary-wire hazard.
comp.proto has zero reserved statements. buf breaking (run first-hand)
confirms type-changing tag reuse on shared wire types — e.g. Scope #2
max(int32)→ause(enum), #6 image(msg)→cur(string); Package #7
scope(msg)→reporturl(string). A lenient binary decode of an old comp.v1
message would silently misinterpret data.
Validation note: security subagent graded this High; downgraded to Medium
because (a) it is an accepted, documented pre-v1 break that buf breaking flags as
expected, (b) the canonical transport is name-keyed (comp.* ext keys / protojson),
so JSON consumers and the conformance gate are unaffected, (c) only the
already-reused numbers are affected and the sole genuinely-freed number is
Retrieval #4 (ratelmt). Resolution (cheap hygiene): add reserved for the
freed field names across messages and reserved 4; in Retrieval; add an
explicit "binary wire-incompatible" line to the changelog.
M2 — extension-profiles.mdx contradicts ext-comp.mdx on the ext-key shape.
extension-profiles.mdx:203 (modified by this branch) says CoMP rides "as a nested
object under ext.comp"; :208 gives comp.package/comp.scope/comp.retrieval.
The authoritative ext-comp.mdx uses flat scalar keys (comp.package_id,
comp.scope_type, comp.allowed_use, …). An implementer cannot tell whether to
write ext["comp.package_id"] or ext["comp"]["package"]["id"]. Resolution:
align extension-profiles.mdx to the flat comp.<field> model (see Q2).
M3 — comp-v1-profile-impl.md is inaccurate in three places.
(a) Defers the stale-doc fixes to PR #8 on the assumption its
starlight-links-validator makes them safe; PR #8 was fetched and confirmed (§6a)
to fix none of the three, and the validator it does add will instead fail CI on
the dead anchor. (b) :38 says the
stale refs are "comp.license[].revshare references in licensing-terms.mdx and
standards-layering.mdx" — but standards-layering.mdx has no revshare string
(its staleness is the v2.0 model), and ext-c2pa.mdx:265 is omitted entirely.
(c) :27 flags the int-vs-alpha-2 upstream inconsistency for country only, not
language, which has the identical issue. Resolution: correct the impl-note (or
treat it as superseded by this review).
M4 — New URL fields lack SSRF/fetch-safety guidance (downstream-advisory).
Package.reporturl (a POST/exfil sink), Package.licenseurl, Retrieval.endpoint
are documented with no security note, while the repo already specifies a rigorous
model for the analogous core License.uri (threat T-LIC-1,
threat-model.mdx:249-252). No fetcher exists in this repo, so this is a
downstream risk to document, not a vulnerability here. Resolution:
cross-reference T-LIC-1 from ext-comp.mdx / proto comments.
LOW
- L1 —
Video.language = 16sits aboveext = 15, breaking the file's "ext is terminal" convention (forced because 13/14 were taken bycattax/cat). Wire-correct and SDK-consistent; cosmetic. - L2 —
languagecomment "ISO-639-1 alpha-2" is self-contradictory with itsint32type. This is the corrected form of architectural F4: the type is faithful (spec declareslanguageasint,array— verified against the spec), so it is not a type bug; only the comment should note the upstream inconsistency, as thecountrycomment does. (Architectural F3/F4 graded High-UNVERIFIED → Low, resolved by the orchestrator's spec fetch.) - L3 —
proto/CHANGELOG.md:8links to mutable/blob/main/instead of the pinned blob URL used everywhere else; weakens the immutable-pin thesis. - L4 —
unitpriceisdouble(float money). Faithful to the spec (not a RAMP flaw); add a proto note that downstream billing must use decimal/minor-units. - L5 — testdata fixtures are not hash-verified against the pinned spec blob at test time; optional supply-chain hardening.
- L6 — DRY (documentary only): enum integer lists are hand-mirrored in
ext-comp.mdxwith noproto-comp.mdxgenerator; the spec pin is restated in 4 hand-maintained places. Add "keep in sync" notes; no abstraction needed.
2. "Does it break existing flow?" — determination
Yes, and it is correctly justified. The re-baseline is a deliberate breaking
change to the comp.v1 generated types. The task allows breaks that are "explicitly
explained why and stated that it is expected" — satisfied: proto/CHANGELOG.md
carries a breaking "Unreleased" entry, comp-v1-profile-impl.md marks it a
"buf breaking reports exactly
the documented deltas, all confined to comp/v1/comp.proto. No unexplained
break. RAMP core (ramp.proto) is byte-for-byte unchanged (0-line diff); the
Ed25519/JWS/RFC-9421 boundaries and the dispute chain are untouched. The one
hygiene gap is M1 (reserved).
3. Open questions — now answered by the PR #8 cross-check (§6a)
- PR #8 coordination / who fixes the stale docs (H1). ANSWERED: nobody yet.
PR #8 edits all three files but fixes none of the stale CoMP references (§6a).
The deferral is void — this branch (or a coordinated commit) must fix them. - Canonical ext-key shape (M2). ANSWERED: PR #8 does not address it. It
touches neitherext-comp.mdxnorextension-profiles.mdx. The in-repo
authority remainsext-comp.mdx(flatcomp.<field>); the reference
implementation is still the external tie-breaker.
6a. PR #8 cross-check (addendum, 2026-06-19)
Fetched and diffed locally (git fetch origin pull/8/head:pr8;
git diff origin/main...pr8). PR #8 is unrelated to CoMP: it is
feature/protocol-unification → main (open; 65 files, 36 commits) — a unified
error/response contract (ErrorDetail, DenialReason, response ver envelope),
BrokerService.Resolve, AccessPolicy removal, and descriptor-driven docs
tooling. It does not touch proto/comp/v1/comp.proto, gen/*/comp,
ext-comp.mdx, or extension-profiles.mdx — no git-level conflict with this
branch on the proto/SDK side.
Q1 — does PR #8 fix the stale CoMP docs? NO (verified against pr8):
licensing-terms.mdx— PR #8 swaps hand-typed tables for::proto-enum/
::proto-vocabdirectives; the stale line (now:120) still reads
comp.license[].revshareand links the dead#license-on-offerextanchor.standards-layering.mdx— PR #8's only edit is an unrelated
DELIVERY_METHOD_INLINE→DELIVERY_METHOD_DIRECTrename; the "CoMP v2.0" table
(:13,137-139,171) is untouched.ext-c2pa.mdx— PR #8 only de-links a "C2PA" word and fixes a spec-URL typo;
:265's removed-media-c2paclaim is untouched.
⇒ The impl-note's "left for PR #8" deferral (M3) is unfounded.
The validator — corrected again. starlight-links-validator is absent from the
repo today (silent broken link now), but PR #8 ADDS it: the new
.github/workflows/docs-ci.yml runs npm run build, which the workflow's own
comment says executes "the remark-proto guard … and starlight-links-validator"
("the PR gate the docs-drift tooling was missing"). Consequence: once PR #8 is on
main, the dead #license-on-offerext anchor fails CI for whichever of {this
branch, PR #8} merges second — a cross-PR breakage, and the fix lives in
neither branch. So H1 is more pressing, not less.
New forward-integration risk (Medium). PR #8's remark-proto guard makes the
build FAIL "on … a hand-typed enum table" and on unknown proto symbols. This
branch's ext-comp.mdx hand-types CoMP enum tables (DRY-L6), and
standards-layering.mdx:139 names the now-deleted LicenseUse symbol. After PR #8
merges, these may trip the guard. (Pending: the guard's exact detection scope —
CoMP enums live in comp.proto, whose descriptor PR #8's tooling reads.)
Recommendation: once PR #8's tooling is on main, re-run npm run build against
the merged tree and convert ext-comp.mdx's CoMP enum tables to ::proto-enum{}
directives to match the new convention.
Net effect on this report: no severity downgrades. H1 reinforced (becomes a
CI blocker post-PR-#8; fixed by neither branch). M3 reinforced (the PR-#8
deferral is unfounded). One Medium added (hand-typed CoMP enum tables vs PR #8's
descriptor guard). Spec-fidelity, SDK, conformance, layering, and security
conclusions are unchanged.
6b. New commit bfccd36 cross-check (addendum, 2026-06-19)
A 7th commit was pushed on top of the reviewed six (descendant of b8c1f2e):
bfccd36 docs: document the JSONL ingestion feed and its record schema. It adds
one new page (website/src/content/docs/protocol/jsonl-ingestion.mdx, +88) and one
Starlight sidebar entry (astro.config.mjs, after Discovery Paths). It is
unrelated to the CoMP re-baseline and resolves none of the findings above.
Validated:
- Touches no
comp.proto, nogen/*/comp, and none of the flagged doc files
(licensing-terms,standards-layering,ext-c2pa,ext-comp,
extension-profiles,reference/changelog). H1, H2, M1–M4 and the §6a items are
unchanged. - M2 neutral, not worsened: the page's "Extension profiles in the feed" section
says domain-profile data rides "underext" and links toext-comp+
extension-profilesrather than restating a key shape — it adds no third
flat-vs-nested description. - No new stale CoMP reference, no dead anchor: its internal links
(/protocol/discovery-paths/,/protocol/ext-comp/,/protocol/extension-profiles/)
all resolve. - Proto-symbol accuracy confirmed: every
ResourceEntry.*field,
IngestionSource/INGESTION_SOURCE_CMS_API,CatalogService.PushResources,
ext_critical,previews,resource_mutabilityit cites exists inramp.proto
— so the page is accurate and would pass PR #8'sremark-protosymbol guard. - Sidebar wired (no orphan page).
⇒ No severity changes; the report stands as written. (Out-of-scope note: this page
documents RAMP-core ingestion, a separate feature from the CoMP profile under
review.)
Bottom line: ship the code; reconcile the documentation (H1, H2) and the
doc/proto-hygiene fixes (M1–M2) before merge. PR #8 resolves none of the doc
issues (§6a) and will turn the dead anchor into a CI failure once its
link-validator lands — so the doc fixes must be made on this branch (or a
coordinated commit), not deferred.
|
@legendko Thanks Yaroslav — thorough review. Triaged everything against one line: does it concern the comp-profile re-baseline (files this branch owns), or not. Resolution per finding below; doc/comment/SDK changes are coming in a follow-up commit on this branch. Addressed (comp-profile scope):
Declined, with reasons:
Deferred — not comp-profile scope (these belong to other work):
Net: code core fixes + the conformance-affecting doc reconciliation (H2) land here; the three foreign stale pages and the PR-#8 coordination are tracked but deferred to their owners. |
… comment hygiene Addresses the in-scope findings from the review of the CoMP V1 re-baseline; out-of-scope items (foreign stale docs, PR #8 coordination) left to their owners. - changelog: mirror the breaking "Unreleased" CoMP V1 entry into the website reference changelog; fix the stale ramp-comp-v1 profile line (H2) - extension-profiles: flat `comp.<field>` ext-key shape to match the authoritative ext-comp page, not a nested `ext.comp` object (M2) - proto/ext-comp: SSRF/T-LIC-1 cross-refs on licenseurl/reporturl/endpoint (M4) - proto: note the deliberate Video.language tag-16 placement above ext (L1); record the upstream int-vs-prose `language` inconsistency on all media (L2); pin the mutable changelog spec link to the immutable blob (L3); decimal/ minor-units note on unitprice double (L4) - ext-comp: keep-in-sync note on hand-mirrored enum tables (L6); preserve the renamed #license-on-offerext anchor via an alias (H1 anchor side-effect) - regenerate Go + TS SDKs (comment-only delta, confined to comp) Conformance gate green; buf generate reproduces the SDKs.
The main->branch merge changed the compiled schema (CoMP V1 Scope/Package fields from PR #9) but gen/descriptor.binpb was not regenerated, so the drift gate failed and the docs build could not resolve the comp.* proto references in ext-comp.mdx against the stale descriptor. Regenerated with the pinned buf 1.66.1; both gates are descriptor-derived, so this fixes proto and docs together.
The main merge brought in the CoMP V1 docs (PR #9), which reference removed or external CoMP fields in prose; #8's descriptor-derived doc guard (absent on main) correctly flags them. Ignore the removed/external members kept for historical or contrast purposes (the type still exists): Package.license, Retrieval.ratelmt, Text.authority, Image.alt, and the CoMP media c2pa fields. Fix the two LicenseTerm references in jsonl-ingestion to the real lowercase field names (license, pricing) so they resolve and autolink.
Cascade latest main (incl. CoMP V1 / PR #9) and the #8 protocol-unification work down into the SDK-types branch. ramp.proto/comp.proto auto-merged cleanly (unification + the SDK-types money/enum/required changes coexist). Resolved the generated-artifact conflicts by regenerating, not by hand: - gen/descriptor.binpb: regenerated (buf 1.66.1). - gen/ts/comp/v1/comp_pb.ts: kept deleted — this branch dropped protobuf-es TS in favor of the Zod types export (buf.gen.yaml emits Go + connect-go + vocab only). - gen/go, gen/*/vocab, gen/ts/wire (Zod), gen/python/wire (Pydantic), and the validation corpus all regenerated from the merged proto.
Reconcile two parallel proto lines off #9: the unified error/response contract (this branch, #8) with the discovery offer-groups remodel (#11) and the WBA identity split (#16). Per-file conflicts resolved by tracing both sides' commit motivations and unifying. Unification decisions: - Agent<->Broker pair: adopted DiscoveryRequest/DiscoveryResponse (#11 rename). BrokerService.Resolve (#8) now takes/returns them and is discovery-only (offer_groups + absence_reason); per-transaction delivery stays on TransactionResponse (separate execute path). - idempotency_key (min_len:1, max_len:255, signer-scoped) preserved on DiscoveryRequest + TransactionRequest/UsageReport/DisputeRequest. - WBA split preserved intact: WBAFile, ResourceAttestation.keyid, KeyRevocationList; public_keys/invalidation_url/kid removed. - Error model preserved: ErrorDetail, ver field 1, PushResources, AccessPolicy/DELIVERY_METHOD_INLINE removed, DenialReason 12-18. - INV-4 reachability roots updated for new served documents (WBAFile, KeyRevocationList); conformance tests + doc-conformance denylist unioned across both sides. - gen/ regenerated (buf 1.66.1).
Reconcile two parallel proto lines off #9: the unified error/response contract (this branch, #8) with the discovery offer-groups remodel (#11) and the WBA identity split (#16). Per-file conflicts resolved by tracing both sides' commit motivations and unifying. Unification decisions: - Agent<->Broker pair: adopted DiscoveryRequest/DiscoveryResponse (#11 rename). BrokerService.Resolve (#8) now takes/returns them and is discovery-only (offer_groups + absence_reason); per-transaction delivery stays on TransactionResponse (separate execute path). - idempotency_key (min_len:1, max_len:255, signer-scoped) preserved on DiscoveryRequest + TransactionRequest/UsageReport/DisputeRequest. - WBA split preserved intact: WBAFile, ResourceAttestation.keyid, KeyRevocationList; public_keys/invalidation_url/kid removed. - Error model preserved: ErrorDetail, ver field 1, PushResources, AccessPolicy/DELIVERY_METHOD_INLINE removed, DenialReason 12-18. - INV-4 reachability roots updated for new served documents (WBAFile, KeyRevocationList); conformance tests + doc-conformance denylist unioned across both sides. - gen/ regenerated (buf 1.66.1).
Summary
Re-baseline
proto/comp/v1/comp.prototo a 1:1 mirror of IAB Tech Lab CoMP V1. The prior file mirrored a pre-final draft that carried a separateLicenseobject surface which does not exist in finalized CoMP V1.comp.v1generated types (pre-v1 of this profile).What changed
Licensemessage,LicenseUseenum, andPackage.license; canonical V1 has noLicenseobject.Scope: addause(AllowedUseenum),pricetype(PriceTypeenum),pricetier,unitprice,cur(default "USD"),country(repeated int32, ISO-3166 numeric),licensedur(days).Package.reporturl.cattax(default 9),cat,languageto Text/Video/Image/Audio.Text.authority/originality,Image.alt/caption, mediac2pa,Retrieval.ratelmt.RETRIEVAL_AUTH_OTHER = 4.Conformance (new permanent gate)
conformance/compexamples_test.goround-trips all 8 worked examples × {request, response} = 16 payloads from the spec through the generated types under strict (unknown-field-rejecting) protojson, then re-marshals and diffs. All 16 pass. An independent field-by-field audit confirms every object/field/type and all 13 integer List codes match the spec 1:1, with no missing fields and no invented extras.Provenance
Pinned to the content-addressed spec-file blob
aa8c796be7a9bcfa1189a1cf6c1ec50aa67a0f5fatmaincommit880238e(CoMP-1.0.md). Note: the1.0-202604release tag does not contain the spec (only a boilerplate README — the spec was added tomainafter the tag), so the blob pin is used instead.Notes (non-blocking, upstream)
Scope.country: the spec types itintbut the prose says "alpha-2 codes" — internally inconsistent upstream. Proto follows the declaredinttype. Worth an upstream clarification.publishedis modeled asint32rather than a named 3-value enum — faithful on the wire, a modeling choice.Review follow-up (this round)
A multi-agent review of the diff surfaced two real gaps (the proto re-baseline and generated SDKs themselves verified clean —
buf generatereproduces them byte-for-byte). Both fixes are scoped to comp-only files with zero overlap with PR #8.testdata/comp_v1_synthetic/dir (kept apart from the verbatim set) andTestCompV1SyntheticCoverageRoundTrip— same strict round-trip plus an anti-vacuity floor (requiredSyntheticCoverage) asserting each fixture still carries the fields it exists to cover. Coverage spans: the fullScopecommercial block (ause/pricetype/pricetier/unitprice/cur/country/licensedur) +packager/reporturl; the request side (AISystemUselid/aiauth/uri/scope/function/subfn/resdis); theVideo/Image/Audiomedia branches andRetrieval; per-assetupdate/language; and thegoogle.protobuf.Structextfield at every level. Also factored the shared round-trip helper and replaced a hand-rolleditoawithstrconv.Itoa.ext-comp.mdxprofile tables. The page's intro was updated to V1 but its body tables still documented the removedLicense/revshare/ratelmtmodel and drifted enum value lists. Rewrote the tables to the current proto surface: dropped the deleted model, correctedretrieval_auth/retrieval_type/scope_typevalue lists, and added the Commercial Terms section,comp.report_url, and per-asset taxonomy, with a CoMP-field column mapping each ext key to its proto field.Cross-PR note: two sibling stale
comp.license[].revsharereferences remain inlicensing-terms.mdxandstandards-layering.mdx— both are owned by PR #8, whosestarlight-links-validatorwill catch the now-removed#license-on-offerextanchor. Left for PR #8 to resolve to avoid interfering with that branch.