feat(stressmodel): generate the satellite network as a fleet of occurrences - #308
Merged
Merged
Conversation
…rences Add a fleet form to the stress-model generator (cmd/stress-model -fleet): four spacecraft blocks carry the as-built values as defaults, each orbital plane is 'part sats : Block[N] ordered', and only every sixteenth unit states values of its own, as a member subsetting the plane's fleet. The spacecraft, ground segment, requirements, mode machine, ring, inter-plane and downlink connectors are those of the single-definition form, whose output is unchanged. Stats gains Definitions and Units so the forms compare. At 12 800 satellites the fleet declares 11 667 elements against 2 354 827 and validates in 0.57 s and 185 MB rather than 301 s and 20.1 GB. The guide chapter on modeling fleets shows both forms, the stress-test record and the performance notes carry the measurements, including what the current runtime pays to instantiate, check and read the occurrences, and BenchmarkFleetInstantiate and BenchmarkFleetSatisfy time it. Co-Authored-By: jason.han <hanhuijun@gmail.com>
Contributor
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
… state link cardinality Block component details (array area, battery capacity, terminal data rate, …) are now defaults like the masses and serial numbers, so a diverging unit can redefine them; the crosslink terminal of every diverging unit states its data rate. The ring and inter-plane collection connectors declare [1] ends, and the guide, stress-test record and changelog say what a collection connector does and does not state about the per-pair topology. Fleet figures re-measured. Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…-stress-model Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…-stress-model Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md
…-end fix Co-Authored-By: jason.han <hanhuijun@gmail.com>
…-stress-model Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/satellite-network-stress-test.md # docs/project/spec-compliance.md # internal/stressmodel/satnet_test.go
…tellation Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
6 tasks
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…-stress-model Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
6 tasks
…-stress-model Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
…-stress-model Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
…-stress-model Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
…-stress-model Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…-stress-model Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
…-stress-model Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
…-stress-model Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
…-stress-model Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
…-stress-model Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # README.md # docs/project/spec-compliance.md
This was referenced Sep 17, 2026
docs(roadmap): record E1, the fUML referee and the state-executor findings as landed on develop
#355
Merged
…-stress-model Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # mkdocs.yml # tests/stressmodel/satnet.go # tests/stressmodel/satnet_test.go
…n the current tree Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ages Co-Authored-By: jason.han <hanhuijun@gmail.com>
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
First of two pull requests implementing one definition, many occurrences from
docs/project/large-model-scaling-design.md§6.This one rewrites the stress-test constellation in that form and measures what the current
runtime does with it; the second (shared derived defaults and verification over distinct shapes
in
internal/exec/runtime) is #324, stacked on this branch.Merge order: PR #308 first, then Part B (#324).
tools/cmd/stress-model -fleetgenerates the satellite network as a fleet:instead of
part def Sat0 :> Spacecraft { … }…Sat12799. The spacecraft (subsystems,components, budgets, connections, mode machine), the ground segment and the three requirements
are the ones the single-definition form declares, and every as-built value a block states is a
defaultso a diverging unit can redefine any of it; that form's output is byte-for-byteunchanged. Fleet mode composes with the split of
tests/stressmodel/split.goand the CLI's-split-planes: the fleet declares its planes inside the network, soSatelliteNetwork{Fleet: true}.Split()writes the library and the constellation as twodocuments, and their statistics add up to the whole file's.
StatsgainsDefinitions,UnitsandAssertions—Requirementsstays the number of requirement usages,Assertionsthe number ofsatisfyassertions, which in fleet form is three per block plus three per diverging unit — sothe two forms compare:
part defper satellitepart defper satelliteWhere the implementation differs from the design. §6 has the per-unit data in a value table
the fleet binds to. Two things stop that today, both documented in the guide chapter and the
stress-test record rather than worked around:
bind sats.comms.crosslinkTerminal.serialNumber = serialNumbersonto a feature thatalready has a block-level default is reported as a binding conflict (the default and the table
are both values of the same feature), and a feature without a default has nothing for the
non-diverging units to inherit.
The closest conforming form — a member subsetting the fleet (
part unit16 :> sats { … }) foreach unit that diverges, inheriting everything else from the block — is what the generator
emits. The runtime places subsetting units as the leading members of
sats(sats#(1)isunit0,sats#(2)isunit16,sats#(3)onward read the block's defaults); the collectionkeeps its declared size. Units between the diverging ones carry their block's catalog ID and
as-built values: a fleet in which every unit restates its values is the per-satellite form
again, so the stride is the fidelity the fleet form gives up until a per-occurrence
dataset/binding mechanism exists. The guide states this where it introduces the stride.
The links are not the same topology. The single-definition form writes every pair: ring
i → i+1closing each plane, slotiof one plane to slotiof the next, satelliteitostation
i mod G. A connector end is a feature chain, not an expression (sats#(1).comms.crosslinkTxis not an end), so the fleet form cannot state those pairs without naming every occurrence; it
declares one connector over each collection instead —
connect [1] sats.comms.crosslinkTx to [1] sats.comms.crosslinkRx, one per adjacent pair of planes, one per plane and station — whose[1]ends say each link joins one satellite to one satellite or station, not which. The runtime
realizes such a connector as one link whose ends hold the collections (
network.plane0.ring.aisevery transmitter of the plane), whatever the end multiplicities declare. The guide chapter and
the stress-test record say so; the fleet figures below are for that model, not for a pairwise one.
What the current runtime does with the fleet (measured; #324 changes this). Instantiation
still creates an object with a value slot per feature for every occurrence, and materialization
of the created network is bounded by
maxMaterializeBudget. Asatisfywhose subject is acollection (
plane0.sats) is rejected — the subject must denote one object — so the assertionstarget each block's configuration and each diverging unit. A usage whose multiplicity lower
bound exceeds 1 000 cannot be materialized, so the fleet is laid out as 32 planes of 400 rather
than 8 of 1 600.
Measurements
Intel Xeon Platinum 8559C, 8 CPUs, 31 GiB RAM, no swap, Linux amd64, Go 1.25.0,
GOMAXPROCS=8,on this branch (current
developplus the fleet generator). Wall issysmlwall-clock,allocated is
runtime.MemStats.TotalAlloc, RSS is/usr/bin/timemaximum resident set. Sameplane/station layout in each pair of rows.
-validate:part defper satellitepart defper satelliteThe stress-test record's earlier 12 800-satellite figure (318 s / 44.0 GiB / 20.6 GB) was taken
with a different plane/station split and is kept beside these, labelled as such.
Current runtime on the fleet form:
-instantiatethe network-satisfy, 324 assertions%evalofplane<i>.sats.dryMass, all 8 planes-instantiatethe network-satisfy, 2 412 assertions%evalofplane<i>.sats.dryMass, all 32 planesgo test ./tests/stressmodel -run '^$' -bench Fleet -benchmem -benchtime 3x:Recorded in
docs/project/satellite-network-stress-test.md(new section) anddocs/internals/performance.md;docs/guide/modeling-fleets.mdis the new guide chapter, linkedfrom the guide index and the
mkdocs.ymlnav.How it was verified
tests/stressmodel/satnet_test.go:TestFleetValidatesloads a 2 × 32 fleet strictly withno diagnostics, checks that the number of
satisfyverdicts isStats.Assertionsand everyone holds, and reads inherited values (
sats#(3).catalogId,sats#(3).plane,sats#(3).comms.crosslinkTerminal.dataRate,sats#(3).eps.solarArray.area), diverging values(
unit0,unit16,sats#(1),sats#(2),unit16.comms.crosslinkTerminal.dataRate) andsatelliteCountthrough the instantiated network, and checks the block details are writtendefault =and the collection connectors declare[1]ends;TestFleetScaleschecks thatmore occurrences add no definitions, that only diverging units add declarations, that more
planes add definitions and links, and that the fleet source is far smaller than the
single-definition source;
TestFleetFilesValidatevalidates the two-document split of a fleet,compares its summed statistics with the whole file's and checks every verdict holds.
tests/stressmodel/bench_test.go:BenchmarkFleetInstantiate,BenchmarkFleetSatisfy.develop's for thetest layouts: identical.
gofmt -l .prints nothing;go build ./...,go vet ./...(root andtoolsmodules),go test ./...,go test -race ./...pass.OPENSYSML_REQUIRE_TRAINING_CORPUS=1 OPENSYSML_REQUIRE_PILOT_CORPORA=1 go test -count=1 ./tests/corpus— training 100/100 clean,
training_examples_expected.txtunchanged and empty; pilot ratchetsunchanged;
go test -count=1 ./tests/identity -run TestPilotLibraryXMIwith the pilot XMIpresent passes.
make docs-check(links, internal-label scan) passes;make docs-countsregenerated the testcounts for the new tests;
python3 scripts/changelog.py checkpasses.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