Skip to content

unverified: a package says why once, for what its own settings give up - #241

Merged
Kinflou merged 2 commits into
masterfrom
unverified/package-scope
Nov 10, 2026
Merged

Kinflou merged 2 commits into
masterfrom
unverified/package-scope

Conversation

@Kinflou

@Kinflou Kinflou commented Nov 9, 2026

Copy link
Copy Markdown
Member

A package can say why it gives up what its own settings give up, once, instead of every protocol repeating it.

handshake = "none"
unverified = {
    schema_agreement = "the gateway pins schemas by contract"
    encoding_agreement = "the gateway pins schemas by contract"
}

or unverified = "reason". (config.idp dictionaries are whitespace-separated, no commas.) Part of #222; proposal ComlineProject/docs#162.

Rules as implemented

  1. Where and gate. A top-level unverified key in config.idp, keyed or plain, under annotations.unverified.allowed; without it the build fails with the gate's message (settings::forbidden, naming the key).
  2. What it covers. Only causes that come from a package setting, and only for protocols that take that setting. A protocol with its own @handshake or @framing isn't covered for what that gives up; the format is only ever the package's. A guarantee with several causes is covered only if all of them come from the package. bounded_size is never package-origin. What a protocol takes is read before the package's handshake is frozen in (unverified::inherits), since after that it reads as the protocol's own.
  3. Scopes from the catalog. A keyed entry for a guarantee that doesn't allow Scope::Package is unverified::wrong-scope, naming the scopes the catalog gives it. Unknown keys are unknown-guarantee with did-you-mean, repeated keys duplicate-guarantee, an empty or non-string reason missing-reason (same checks as a protocol marker). A keyed entry no inheriting protocol gives up through a package setting is the not-given-up warning, reported on the package's first schema (config entries carry no spans).
  4. Coverage per protocol. A given-up guarantee is acknowledged by the protocol's own marker (plain covers all, keyed lists it) or by the package, for a package-origin cause. An unmarked protocol whose losses are all covered compiles; a keyed marker needn't list what the package covers (listing it is fine, no warning, and its reason wins); anything uncovered is the existing missing-marker / missing-guarantee, unchanged (a partly covered unmarked protocol's error names only what's uncovered).
  5. Frozen record. FrozenUnit::Unverified(set) is still what core works out, and is now also frozen for a protocol the package covers without a marker (consumers need to see it). Each protocol covered at package scope gets Property { name: "unverified_package", value: Dict(guarantee id -> reason) }: the package's acknowledgement restricted to what it covers for that protocol (a plain package form freezes as the dict with the plain reason). Protocols not covered get nothing new, so their frozen bytes don't change. No schema IR variant, no serde change. The compiler strips any unverified_package a schema wrote itself, so only it says what the package covers. The package's own unverified is frozen in the config units as a new trailing FrozenUnit::Unverified(ConfigValue) variant (config units are a separate enum; this is how HandshakeParams was added).
  6. Reasons. reason_for, reason_text, protocols() (so dependency acceptance messages) and inspect fall back to the package's reason for a guarantee the marker doesn't say. The marker's reason wins. Output for existing cases is byte-identical.
  7. Diff. Adding, removing or rewording unverified_package is reported as a ChangedAnnotation (a patch); what's given up still decides major and minor through the frozen set.
  8. Config key. unverified is accepted by the config interpreter (freezing.rs), the only place config keys are registered; the validator for the key is validator::check_package_unverified.

New codes

  • unverified::wrong-scope (error)
  • existing codes now also raised for the package entry: unknown-guarantee, duplicate-guarantee, missing-reason, not-given-up

Tests

In core/tests/package/unverified.rs: package handshake = "none" with keyed and plain acknowledgements; own @handshake not covered (and a forged unverified_package is ignored); bounded_size not covered, and a wrong-scope entry; unknown key, empty reason, duplicate; not-given-up warning; keyed marker listing only bounded_size; gate off; diff (reword, move to a marker, gave up/restored). In package/deps.rs: the acceptance message shows the package's reasons.

Also bumps comline-catalog to spec rev 508f813 (guarantee scopes) and updates the one inspect doc string in schemas/doc-model.json to match.

Kinflou added 2 commits November 10, 2026 03:45
config.idp takes an `unverified` key beside the settings that cause losses:

    handshake = "none"
    unverified = { schema_agreement = "the gateway pins schemas by contract" ... }

or a plain reason, covering every package-scope cause. It's under the same
gate as the annotation (annotations.unverified.allowed).

It covers only a cause that comes from a package setting, and only for a
protocol that takes that setting: one with its own @handshake or @framing
isn't covered for what that gives up. A protocol is acknowledged for what
its own marker covers and what the package covers for it, so an unmarked
protocol whose losses are all covered compiles, and a keyed marker needn't
list what the package covers. Anything else is the missing-marker and
missing-guarantee errors as before.

Keys are held to the catalog: a guarantee that doesn't allow package scope
(bounded_size) is unverified::wrong-scope, naming the scopes it allows;
unknown, repeated and reasonless entries are the protocol marker's errors;
a keyed entry no protocol gives up through the package is
unverified::not-given-up, a warning.

The given-up set is frozen as before, and now also for a protocol the
package covers without a marker. Each covered protocol also carries an
`unverified_package` property: the package's reasons for the guarantees it
covers for it. Nothing changes for one it covers nothing for. Reasons in
diagnostics, inspect and dependency acceptance read it when the marker has
none. The diff reports the property as a patch; the set decides the rest.

comline-catalog moves to the specification rev with guarantee scopes.
…n it's marked

A protocol only the package's `unverified` covers has no marker of its own, and
showed as verified while its guarantee rows said otherwise. The flag now follows
what's given up (the frozen set or any cause); its doc and the doc model's
description say so.
@Kinflou
Kinflou merged commit 9ea142e into master Nov 10, 2026
24 checks passed
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.

1 participant