Repository navigation
fix(grpc): verification RPCs naming no subject evaluate over the held population - #1618
Merged
Merged
Conversation
…ulation After Instantiate, VerifyRequirement naming no subject must run a definition-owned verification case on every object the model holds, as the REPL's %requirement does after %instantiate and as VerifySatisfaction already does; it reports the case inconclusive instead. Co-Authored-By: jason.han <hanhuijun@gmail.com>
Contributor
Author
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
… population VerifyConstraint, VerifyRequirement and RunAnalysis with no subject named now evaluate on the runtime holding the objects Instantiate created, under its lock, as Instantiate and VerifySatisfaction do: a definition-owned verification case runs once per held object, a type-owned constraint is checked on the held object carrying it, and a case a definition owns runs as a feature of the held object of that definition. A named subject keeps its own worker. A run over the population that would pass the held-objects bound is RESOURCE_EXHAUSTED, as Instantiate is; VerificationVerdict carries the error it reports so surfaces can classify it, and the `this` read keeps the cause in its error chain. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ate prints A definition's `satisfy r;` decided over the objects a session holds named a nested object by its feature alone (`fleet.cheap`) while %validate named the same object `fleet.cheap[1]`. The runtime now spells a carrier's path as the validation walk spells the object it reaches — one shared segment spelling, a collection's element indexed — and the REPL, the CLI's -satisfy and the gRPC satisfy verdict's instance_path label the object by it. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…rmance case Co-Authored-By: jason.han <hanhuijun@gmail.com>
…t label Co-Authored-By: jason.han <hanhuijun@gmail.com>
…llection gathers The indexed path ends in the declaration the object materializes where it differs from the feature holding it, as carrierLabels names it; a repeated part keeps its indexed segment. Co-Authored-By: jason.han <hanhuijun@gmail.com>
…SOURCE_EXHAUSTED A verification case run reports its own failure in the verdict rather than the call's error, so a run over the held population that passed the held-objects bound answered an error verdict; exhaustedRun reads the verdicts' errors as the call's, as the requirement sweep already did. Co-Authored-By: jason.han <hanhuijun@gmail.com>
The preview's writes are restored from a snapshot and the runner the runtime had goes back on, as the REPL's preview does; over the held population both outlived the request. Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ld-population Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # docs/project/spec-compliance.md
Co-Authored-By: jason.han <hanhuijun@gmail.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.
What and why
The gRPC service keeps the objects
Instantiatecreates alive across requests in a held runtime (heldObjects), andVerifySatisfactionsweeps that population.VerifyRequirementwith nosubject_symbol_idinstead built a fresh worker runtime holding nothing: afterInstantiate test::fleet, it answered a definition-owned verification caseinconclusive: needs an object of test::Definition: none is instantiatedwhileVerifySatisfactionon the same model reported the casepasson each held object. The REPL is the reference surface:%instantiate fleetthen%requirement test::costReqprints one requirement verdict (undecided, its subject unbound) and one case verdict per held object (passon IDs 2 and 3).Root cause:
Service.VerifyRequirement,VerifyConstraintandRunAnalysiswent throughnewVerifyContext→s.newRuntime, a worker of the request's own, socaseCarriers(sym, nil)swept the empty worker. The fix isverifyContext.overHeld: with no subject named and a population held, the request's context is the held runtime underheld.lock(ctx)(the samev.on(rt)patternsatisfyVerdictsuses),performOnkeeps theanalysis.Held(rt)contract, the explore path (exploreAnalysis, a background plan over fresh runtimes) is untouched, andRunAnalysissets and restores the held runtime's schedule (verifyContext.scheduled). A named subject keeps today's worker. A sweep over the population that would make one more object thanOPENSYSML_GRPC_MAX_HELD_OBJECTSallows isRESOURCE_EXHAUSTED, asInstantiateis:runtime.VerificationVerdictnow carries the error an error verdict reports (Err), andEvalContext.thisValuewraps its cause with%wsoerrors.Is(err, ErrInstanceLimitExceeded)reaches it.Wire shape: no proto change. The measured REPL output is one requirement verdict plus N case verdicts, which
VerifyRequirementResponse(verdict+ repeatedverification_verdicts) already carries;instancesnow carries every object a case verdict is about (runRoots, asRunAnalysisdoes).Second commit (
%satisfylabels): a definition'ssatisfy r;decided over held objects labelled a nested object(on test::fleet.cheap ID: 2)while%validate fleetlabelled the same object(on test::fleet.cheap[1] ID: 2). The runtime now spells a carrier's path once (heldSegments/indexedSegment, shared with the validation walk'sheldChildren;carrierFeatureskeepscarrierLabels' rule that a subsetting collection's object ends in its declaration), the REPL joins it in one place (objectPath, replacingfeaturePathandobjectVerdict's own join), the CLI's-satisfyfollows, and the gRPC satisfy verdict carries it asinstance_pathasValidateInstance's verdicts do (instancePath).Specification basis
SysML v2.1 Beta 2 §7.24 Verification Cases (§7.6.3: a usage nested in a definition is a feature of each object of it), §7.20.1 (the owner of a
satisfywith nobyis the satisfying feature). Moves the rows "A verification case a part definition owns is a feature of every object of that definition" and "Asatisfy r;stating nobyis about the objects of the type stating it" indocs/project/spec-compliance.md(status unchanged, ✅; implementation and test columns extended). Not stricter than the spec: no new diagnostic.Behaviour changes
VerifyRequirementwith nosubject_symbol_id, objects held: a definition-owned verification case runs once per held object of the definition and itsverification_verdictsname each object (instance_id,instance_type_id);instancescarries those objects. Before: oneinconclusive … needs an objectverdict. With nothing held: unchanged.VerifyConstraint/VerifyRequirementwith no subject, objects held: a constraint or requirement a definition owns is checked on the held object carrying it; over several carriers the verdict isundecidedwithFAILURE_REASON_AMBIGUOUS_SUBJECT(REPL%constraint/%requirementparity). Before: declared defaults on a fresh exemplar.RunAnalysiswith no subject, objects held: a case a definition owns runs as a feature of the one held object of that definition; over two it reports the runtime'serrorverdict naming both carriers (REPL%analysisparity). Before:inconclusive … needs an object.VerifyRequirement/VerifySatisfaction/ValidateInstance: a verification sweep over the held population that would passOPENSYSML_GRPC_MAX_HELD_OBJECTSisRESOURCE_EXHAUSTED(asInstantiate), the population unchanged. Before: anerrorcase verdict quotingthis names no object here: object limit exceeded.RunAnalysiswith no subject, objects held: a verification case whose run would pass the held-objects bound isRESOURCE_EXHAUSTED(the failure in the case's verdict as well as in the call's error). Before: anerrorverdict.RunAnalysistool_dry_runover the held population: the preview's writes and objects are undone and the runtime's tool runner put back, as the REPL's%toolpreview does. Before: the preview's performance stayed held and the dry runner stayed on the runtime.%satisfy, CLI-satisfy, gRPCVerifySatisfactionover a definition'ssatisfy r;: the object is labelledfleet.cheap[1]/cheap[1](indexed, as%validate), the gRPC verdict gaininginstance_path. Before:fleet.cheap, noinstance_path.How it was verified
grpc/held_population_verify_test.goTestVerifyRequirementWithoutASubjectSweepsTheHeldPopulation(fails on develop:costTest=inconclusive, 1 verdict), plusTestVerifyConstraintWithoutASubjectIsAboutTheHeldCarrier,TestRunAnalysisWithoutASubjectRunsOnTheHeldObject;grpc/robustness_held_population_test.goTestGRPCRobustnessHeldPopulation(bound → RESOURCE_EXHAUSTED, population unchanged, named subject unaffected); gRPC conformanceverify_requirement_held_populationandverify_requirement_no_object(newVerifyRequirementrunner withinstantiate,expected_status,expected_verification_verdicts).TestDefinitionOwnedCaseWithNoObjectNeedsOne(nothing held) unchanged and green.cmd/sysml/satisfy_label_test.goandreplTestSatisfyLabelsObjectsAsValidateDoes(same(on test::fleet.cheap[1] ID: 2)line from-satisfy/%satisfyand-validate/%validate); the existingruntimeTestReportedFeaturesEndInTheDeclarationkeeps the subsetting-collection declaration rule.grpc/held_population_preview_test.goTestToolPreviewLeavesTheHeldPopulationAsItWas(fails without the fix:held after the preview = 4 objects, want 3, dry runner left on);TestGRPCRobustnessHeldPopulationgainscase run at the bound.TestReportedFeaturesEndInTheDeclaration, fixed by keeping the declaration rule rather than editing the test.e19d9beb3; thespec-compliance.mdconflict took develop's citation column and kept the rows here):go build ./...,go vet ./...,gofmt -l .(empty): clean.go test -timeout 60m ./...: 123 packagesok, 0 failures (the default 10-minute package timeout is too short forcmd/sysmlandtests/codegenunder a parallel run on this machine, hence the flag).make test-shard SHARD=runtime(race, allocation bound):okin 1638 s, 88.0 % coverage; no bound raised.make docs-check,python3 scripts/check-doc-ids.py,python3 scripts/changelog.py check: pass.pssm-referee -check): reproduces the committed counts — pass 56, fail 6, not-expressible 34, differs-by-design 7 (103 tests). No movement.pilot-exec-diff, 514 cases): agree 229, kind-only 1, order-only 0, disagree 38, differs-by-design 5, pilot-unevaluated 167, pilot-silent 24, pilot-error 7, ours-error 10, ours-undetermined 17, both-error 16, nondeterministic 0 — identical to the committed baseline.GOOS=js GOARCH=wasm -tags sysml_prod -ldflags "-s -w", Gogzip.BestCompression): develope19d9beb322,455,061 B gz → head 22,457,220 B gz (+2,159 B, +0.01 %). Budget untouched.make docs-check(venv python) andscripts/check-doc-ids.pypass;python3 scripts/changelog.py checkpasses.Open decisions (found, left alone)
satisfysweeps (SatisfactionSubjectsover the surface's held roots) visit both objects while definition-owned case runs and checks (caseCarriers,conditionSubjectoverrootInstances) take the newest only — REPL and gRPC alike, andruntimeverification_runs_once_per_repeated_objectpins the newest-only rule. Which rule a sweep should follow is yours.%validatenames an element reached throughpart small : Component :> subsystemassubsystem[1], verdicts name itsmall(TestReportedFeaturesEndInTheDeclaration). Same on develop; aligning them moves either validation goldens or that rule.RunAnalysis/%analysisof a definition-owned case over two carriers nested under one held root (fleet.cheap[2]) runs once, on the first (cheap[1]), while two held roots are an ambiguity andVerifyRequirementsweeps both. REPL and gRPC agree; left as is.exploreschedule runs on runtimes of its own, one per linearization, holding nothing: the held population does not reach explored runs. Unchanged, documented in the wire contract.Checklist
make testandmake lintpass locallychanges/unreleased/<slug>.<section>.md, not as an edit toCHANGELOG.mdmake docs-countsrun if a gate count moved (compliance rows need nothing: the census is counted at docs build)F4,K5) in the body, docs, or changelog