You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
POST /reports/compare compares exactly two sections. Real questions are scope-level: two campuses ("how does Building A's project differ from Building B's?"), two packages ("Underground vs Core & Shell — where do shared divisions diverge?"), two issuances of the same package, or a package's live state vs its last issuance. Today an agent must discover the shared sections itself and orchestrate N calls — and nothing reports the membership delta (sections present in only one scope), which for packages is half the answer.
Section pairing: resolve each scope to its member sections (project TOC via project_specs, package via package_specs, revision via package_revision_specs), pair by canonical section number (lib/section-number.ts grammar), report the membership delta (onlyIn per scope) as first-class output.
Why
POST /reports/comparecompares exactly two sections. Real questions are scope-level: two campuses ("how does Building A's project differ from Building B's?"), two packages ("Underground vs Core & Shell — where do shared divisions diverge?"), two issuances of the same package, or a package's live state vs its last issuance. Today an agent must discover the shared sections itself and orchestrate N calls — and nothing reports the membership delta (sections present in only one scope), which for packages is half the answer.What
POST /reports/compare-scope(separate operationId — the per-section endpoint stays untouched):sources= exactly two scope refs, each{ projectId }|{ packageId }|{ revisionId }(revision refs need feat(reporting): frozen revision trees as comparison sources — polymorphic compare refs + freeze-time origin embedding (ADR required) #392's frozen loader).project_specs, package viapackage_specs, revision viapackage_revision_specs), pair by canonical section number (lib/section-number.tsgrammar), report the membership delta (onlyInper scope) as first-class output.{ rows, aligned, identical, differing }+alignedBy) — token-conscious by design, the full matrix stays behind the per-section endpoint (drill-down refs echoed per row).alignmentoption plumbed through;differencesfilter analog (only sections with differences).OpenAPI ↔ MCP contract lockstep
New endpoint + schemas ⇒
openapi.yamlAND a newcompare_scopesMCP tool (tierread) incontract-map.tsin the same PR; contract gates enforce parity.Prior art / cross-links
Non-goals
Acceptance
Sequenced after #392.