feat(company-monitoring): add identity_unresolved coverage state - #7063
Open
yzxcj797 wants to merge 10 commits into
Open
feat(company-monitoring): add identity_unresolved coverage state#7063yzxcj797 wants to merge 10 commits into
yzxcj797 wants to merge 10 commits into
Conversation
A company with no independent identity binding cannot be scanned — no provider query can be safely attributed to it — so it must never read as a quiet result. Reporting such a company as quiet is the false quiet the koala73#6002 stop conditions prohibit (koala73#7044). Both sources of truth carry the new state: the CompanyCoverageState proto enum (new number 7, no renumbering) with the generated client/server unions and the generated request validation pattern, and the convex coverageState union (awaiting_first_scan | identity_unresolved; absent still means resolved-and-scanned, with observationState carrying the result). Transitions, with the non-overlap semantics from the issue: - set when identity resolution fails: an X identity observation that lands demoted (conflict, account change, or expiry) marks the company identity_unresolved; - cleared when a binding is verified: an authoritative identity resolves the company (coverageState back to undefined); - reinstated on demotion: the official_link_lost / authority_lost path that fires when a held binding expires or loses its domain claim re-marks the company identity_unresolved, so a company that held a binding and lost it does not silently read as quiet; - every coverage flip advances the company row's own snapshotGeneration — that is the freshness signal company-scoped reads compare against, so a flip without the bump would stay invisible to snapshot-gated consumers (encoded in a test). The shared coverage contract accepts the state in both spellings, the OpenAPI injector publishes it with a description stating it is not a quiet result, and assertCoverageObservation keeps refusing it as a carrier of no_events_observed — the never-quiet guarantee is pinned by tests on the contract and on the demotion transition.
|
@yzxcj797 is attempting to deploy a commit to the World Monitor Team on Vercel. A member of the Team first needs to authorize it. |
…ved-coverage-7044
…ved-coverage-7044
26 tasks
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.
Implements #7044.
What
A distinct coverage state for a company with no independent identity binding. Such a company cannot be scanned — no provider query can be safely attributed to it — so it must never read as a quiet result; the #6002 stop conditions prohibit the false quiet.
Both sources of truth
CompanyCoverageStateproto enum:COMPANY_COVERAGE_STATE_IDENTITY_UNRESOLVED = 7(new number, nothing renumbered), carried into the generated client/server unions and the generated request-validation pattern.convex/schema.ts:coverageState: v.optional(v.union(v.literal("awaiting_first_scan"), v.literal("identity_unresolved")))— absent still means resolved-and-scanned, withobservationStatecarrying the result.Transitions (non-overlapping, per the issue)
demoted(family conflict, account change, or expiry) marks the companyidentity_unresolved(applyXIdentities→patchCompanyCoverageForIdentity).authoritativeidentity resolves the company (coverage back toundefined).official_link_lost→authority_lostpath (a held binding whose domain claim expired or lost authority) re-marks the companyidentity_unresolved, so a company that held a binding and lost it does not silently read as quiet.snapshotGeneration— the freshness signal company-scoped reads compare against — encoded in a test rather than assumed (the acceptance criterion's exact ask).Published surfaces
shared/company-monitoring-contract.ts: the state joins the coverage union, the validator set, and bothCOVERAGE_STATE_BY_INPUTspellings;assertCoverageObservationstill refusesidentity_unresolved+no_events_observed(the never-quiet guarantee), now pinned by an explicit test.scripts/openapi-inject-company-monitoring-contract.mjspublishes the state with a description stating it is not a quiet result; the three committed OpenAPI artifacts are regenerated through the injector.Tests
companyMonitoringXIngestion.test.ts: demotion reinstatesidentity_unresolvedwith the generation bump (asserting the before/after delta), and an authoritative identity clears a previously-unresolved company — 26/26 green (24 existing untouched).tests/company-monitoring-contract.test.mts: the state is valid withunknownobservation but can never carryno_events_observed; both filter spellings normalize — 30/30.tests/company-monitoring-openapi-contract.test.mjs: 7/7 after injector regeneration.tsc --noEmitclean, biome clean on all touched files.Local-environment note: the OpenAPI injector's YAML patcher does exact line matches, so a Windows CRLF checkout makes it fail; the three target artifacts were LF-normalized before running it (its own idempotency test then passes). CI on LF checkouts is unaffected.