feat(public-surface): add rule codes, a suggested bump, and gateable findings - #498
Merged
Merged
Conversation
…findings certify_public_surface diff verdicts now carry stable rule codes per change (export-removed, param-type-narrowed, ..., signature-unprovable, export-added) and a suggestedBump (major/minor/patch). The eight breaking-classed codes are registered findings (source public-surface) emitted in findings[], so an enforcement.policy can gate individual rules; signature-unprovable is never breaking-classed. The false 'sibling repos are also checked' disclosure now says in-repo only. The accept baseline and the consumed/unconsumed split are deferred. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Round-1 review fixes: - withhold suggestedBump (null, with a reason) when any change is potentially-breaking or no classifiable-language file was assessed - register signature-unprovable as a warning finding, so removing a type annotation cannot hide a narrowing from a policy - remediation uses a function replacement ($$ paths stay intact); finding messages name the rule instead of repeating every reason - a rename's finding points at the post-change file - tests: exact codes per rule, export-renamed, name-level exports, parameter codes through the handler, mixed breaking+unprovable - spec/docs match the code; CLI types findings; archived proposal notes the narrowing; deferred parts move to add-public-surface-acceptance-baseline Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ified Round-2 verification fixes: - the handler only reads TS/JS/Python files, so a diff that changed only Go/Rust/Java/... code reached the classifier empty and suggested patch; changed code files in an unclassified language now withhold the bump (docs and config files do not) - a signature-unprovable finding says it triggers a rule, not breaks it Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Round-3 verification fixes: - a changed code file counts as unassessed when the canonical language map knows its language and it is not TS/JS/Python (Vue, Svelte, shell, PHP, ...), plus extensions the map lacks (.pyi, .hxx, .mm, ...); tests, Terraform, Bicep, and config files do not count - a rename counts its old path too (lib.go -> lib.txt) - tests for Vue, .pyi, shell, rename, _test.go, Terraform, config, and an untracked .go file; spec and docs wording plus a scenario Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Round-4 verification fixes: Cython (.pyx/.pxd), C++ template and CUDA headers, Groovy, Razor, ERB, CoffeeScript, Perl, PowerShell, Zsh/Fish, batch, Solidity, and other code extensions the language map lacks now withhold the bump; tests for .pyx and the Bicep exclusion. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Status
LGTM. CI is green on
91291e0ca, including Windows unit tests and Windows smoke. Four parallel adversarial reviews and three verification rounds found no gate bypass; every confirmed finding is fixed. The last verification round found no defect in the main behavior, and its two low-severity gaps (extra code extensions, an untested Bicep exclusion) are fixed with tests.What was missing
certify_public_surfaceclassified breaking changes with prosereasonsonly. There was no stable rule identity, soenforcement.policycould not gate "block export removals but not type narrowings", and the tool emitted no registered governance finding at all.breakingbut not what version bump that implies.What it does
ruleCodesfrom a closed set:export-removed,export-renamed,export-visibility-reduced,export-added,param-removed,param-required-added,param-became-required,param-type-narrowed,return-type-narrowed,signature-unprovable.suggestedBump:majorwhen any change is breaking; withheld (null, withsuggestedBumpWithheld) when any change is potentially-breaking or no signature-classifiable file was assessed; otherwiseminorwhen an export was added, elsepatch.error) andsignature-unprovable(severitywarning) are registered inFINDING_CODE_REGISTRY(sourcepublic-surface, defaultadvisory).publicSurfaceFindingsemits one finding per such code per changed export infindings[], so the caller that runs the tool can gate a rule.signature-unprovableis never breaking-classed. A bump is never offered on unproven evidence. The disclosure now says consumers are in-repo only, including under federation.openlore certify-public-surface --base <ref>prints the bump and each change's rule codes.Round-1 review fixes
suggestedBump: patch/minoron unproven evidence (potentially-breaking, or changed Go/Rust/Java/… files the classifier never reads)null) with a reasonsignature-unprovableis a registeredwarningfinding$$/$&in a path corrupted the remediation (String.replacepatterns)$$routesignature-unprovablepath,export-renamed, name-level exports, parameter codes through the handler, a mixed breaking+unprovable change, and an exact finding snapshotenforcegates itopenlore enforce)"add-public-surface-acceptance-baselinein To-buildRound-2 verification fixes
patch.gochange and a docs-only changesignature-unprovablefinding said it "breaks" a ruleRound-3 verification fixes
.hxx, and.pyichanges still suggestedpatchlib.gotolib.txthid removed Go code_test.go, Terraform,package.json, and an untracked.gofile in a real git repositoryRound-4 verification fixes
.pyx/.pxd,.inl, CUDA, Groovy, Razor, ERB, Perl, PowerShell, …) still suggestedpatch.pyx.bicepfile does not withhold the bumpProof
src/core/analyzer/public-surface.test.ts: each signature rule fires its code; a potentially-breaking change never carries a breaking code;suggestedBumpfor breaking, additive, and potentially-breaking-only diffs.src/core/services/mcp-handlers/public-surface.test.ts: codes for removed, visibility-reduced, added, and narrowed changes on file-content fixtures; aminorbump and no findings for an additive diff, and a withheld bump with onesignature-unprovablewarning finding for a potentially-breaking diff; one registered finding per breaking code, and per-rule gating (export-removed→ blocking leavesparam-type-narrowedadvisory); the disclosure no longer claims sibling repos are checked.2026-09-13-refine-public-surface-certification(ADDPublicSurfaceRuleCodesAndSuggestedBump).openspec validate --specs --strict: 16/16.Notes
Known classifier gaps that already exist on
main(removed overloads, generator parameters, narrowed type aliases, Go parameter changes, and the return-type rule being backwards for callers) are filed as a separate task; the bump is withheld where the classifier cannot assess a change.Narrowed from the proposal. Deferred: the
--acceptbaseline with required justifications and decision anchoring, thebreaking-consumed/breaking-unconsumed-in-indexsplit with the federation consumer union, and running the tool insideopenlore enforce(it needs a base ref).The MCP tool description and
tools/listpayload are unchanged; the response grows byruleCodesper change,suggestedBump, andfindings.🤖 Generated with Claude Code