9e57bfd451
**F41 — public-api baselines (M6 DoD bullet 5)**
`design/public-api/{crate}.txt` for all 9 workspace crates, generated
via `cargo +nightly public-api --simplified -p <crate>`. Per-crate
baseline sizes:
- mxaccess-codec: 2516 lines
- mxaccess-asb: 1258 lines
- mxaccess-rpc: 1273 lines
- mxaccess-asb-nettcp: 708 lines
- mxaccess: 542 lines
- mxaccess-galaxy: 374 lines
- mxaccess-callback: 170 lines
- mxaccess-compat: 123 lines
- mxaccess-nmx: 118 lines
`design/public-api/README.md` documents the update procedure
(install nightly + cargo-public-api, regenerate the affected baseline
on intentional API changes, commit alongside).
`.github/workflows/rust.yml` gains a `public-api` job that runs the
same diff against the committed baseline; drift fails CI with a
unified diff in the log so the PR author can either revert or
update the baseline.
**F44 reconciliation — multi-record DataUpdate codec**
Cherry-picked from the F44 sub-agent's worktree (commit `aec6a0c`):
`subscription_message.rs::parse_data_update` now loops over
`record_count` like `parse_subscription_status` does, accepting any
positive count. The .NET reference still hard-throws on
`record_count != 1`; the Rust codec deliberately diverges per the F44
evidence walk against `captures/094-frida-buffered-separate-writer/
frida-events.tsv:145` (a `0x33` DataUpdate body with `record_count = 2`,
inner_length = 23 (preamble) + 2 * 19 (records) = 61, post a
separate-session writer triggering two value changes inside one
`SetBufferedUpdateInterval(1000)` window).
Two new round-trip tests:
- `data_update_multi_record_round_trip` — synthesises a 2-record body,
parses, asserts both records decode to expected Int32 values.
- `data_update_capture_094_truncated_record_errors` — truncates the
capture-094 fixture mid-second-record, asserts CodecError::Decode.
New wire-byte fixtures under `crates/mxaccess-codec/tests/fixtures/m6-buffered/`:
- `094-line145-dataupdate-recordcount2.bin` (57 bytes, `0x33` multi-record)
- `094-line48-substatus-recordcount2.bin` (101 bytes, `0x32` multi-record)
R2 in `design/70-risks-and-open-questions.md` updated from
"single-sample (settled silently)" to "settled per option (a) — codec
relaxed; multi-record observed in production-stack tracing."
`design/followups.md`: F44's verdict updated to reflect the
contradiction-then-relaxation, with reference to the new tests +
fixtures.
Workspace 792 → 794 tests pass; clippy clean; rustdoc clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
93 lines
3.1 KiB
YAML
93 lines
3.1 KiB
YAML
name: rust
|
|
|
|
on:
|
|
push:
|
|
branches: [master, main]
|
|
paths: ['rust/**', '.github/workflows/rust.yml']
|
|
pull_request:
|
|
paths: ['rust/**', '.github/workflows/rust.yml']
|
|
|
|
defaults:
|
|
run:
|
|
shell: pwsh
|
|
working-directory: rust
|
|
|
|
jobs:
|
|
build:
|
|
name: build / test / clippy / fmt
|
|
runs-on: windows-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Install Rust toolchain
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
toolchain: '1.85'
|
|
components: rustfmt, clippy
|
|
|
|
- name: Cache cargo
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
workspaces: rust
|
|
|
|
- name: cargo fmt --check
|
|
run: cargo fmt --all -- --check
|
|
|
|
- name: cargo build --workspace
|
|
run: cargo build --workspace --all-targets
|
|
|
|
- name: cargo test --workspace
|
|
run: cargo test --workspace --no-fail-fast
|
|
env:
|
|
# MX_LIVE is intentionally NOT set — live tests require an AVEVA
|
|
# install + Galaxy DB which CI cannot provide. See design/60-roadmap.md
|
|
# validation strategy: live probes run on the maintainer's workstation,
|
|
# gated by `MX_LIVE=1` via `tools/Setup-LiveProbeEnv.ps1`.
|
|
MX_LIVE: ''
|
|
|
|
- name: cargo clippy --workspace -- -D warnings
|
|
run: cargo clippy --workspace --all-targets -- -D warnings
|
|
|
|
public-api:
|
|
name: cargo public-api drift check (F41)
|
|
runs-on: windows-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Install nightly toolchain
|
|
uses: dtolnay/rust-toolchain@nightly
|
|
|
|
- name: Install cargo-public-api
|
|
run: cargo install --locked cargo-public-api
|
|
|
|
- name: Diff each crate's public API against the baseline
|
|
shell: pwsh
|
|
working-directory: rust
|
|
run: |
|
|
$crates = @(
|
|
'mxaccess-codec', 'mxaccess-rpc', 'mxaccess-asb-nettcp',
|
|
'mxaccess-asb', 'mxaccess-galaxy', 'mxaccess-callback',
|
|
'mxaccess-nmx', 'mxaccess', 'mxaccess-compat'
|
|
)
|
|
$drift = $false
|
|
foreach ($crate in $crates) {
|
|
Write-Host "=== $crate ==="
|
|
$live = cargo +nightly public-api --simplified -p $crate 2>$null
|
|
$baseline = Get-Content "../design/public-api/$crate.txt" -Raw
|
|
$liveJoined = ($live -join "`n") + "`n"
|
|
if ($liveJoined -ne $baseline) {
|
|
Write-Host "::error file=design/public-api/$crate.txt::public API drift detected for $crate"
|
|
# Print a unified diff for the PR log.
|
|
$tmpLive = New-TemporaryFile
|
|
$tmpBaseline = New-TemporaryFile
|
|
Set-Content -Path $tmpLive -Value $liveJoined -NoNewline
|
|
Set-Content -Path $tmpBaseline -Value $baseline -NoNewline
|
|
git diff --no-index --color=never -- $tmpBaseline $tmpLive
|
|
$drift = $true
|
|
}
|
|
}
|
|
if ($drift) {
|
|
Write-Host "::error::Public API drift detected. Run 'cargo +nightly public-api --simplified -p <crate>' locally and update design/public-api/<crate>.txt to match the intended new surface."
|
|
exit 1
|
|
}
|