diff --git a/docs/components/Transport.md b/docs/components/Transport.md index 615a18b7..4a670d51 100644 --- a/docs/components/Transport.md +++ b/docs/components/Transport.md @@ -27,7 +27,7 @@ bundle.scadabundle `manifest.json` is always plaintext so the import wizard can display source provenance and artifact counts before the operator supplies a passphrase. `BundleManifest` carries: `BundleFormatVersion`, `SchemaVersion`, `CreatedAtUtc`, `SourceEnvironment`, `ExportedBy`, `ScadaBridgeVersion`, `ContentHash` (`sha256:` of the raw content bytes), optional `Encryption` metadata, a `Summary` (artifact counts by type), and a `Contents` list (one `ManifestContentEntry` per artifact with its `dependsOn` edges). -`BundleFormatVersion` is an integer gate: the importer requires `BundleFormatVersion` to equal `ManifestBuilder.CurrentBundleFormatVersion` (currently `1`) and rejects any other value — higher or lower — with `ManifestValidationResult.UnsupportedFormatVersion`. `TransportOptions.SchemaVersionMajor` is not read during import. Unknown entity types in `Contents` produce a preview-row classification of "unsupported" rather than aborting the whole import. +`BundleFormatVersion` is an integer gate: the importer requires `BundleFormatVersion` to equal `ManifestBuilder.CurrentBundleFormatVersion` (currently `1`) and rejects any other value — higher or lower — with `ManifestValidationResult.UnsupportedFormatVersion`. There is no configurable schema-version option; both versions are code constants. Unknown entity types in `Contents` produce a preview-row classification of "unsupported" rather than aborting the whole import. ### Encrypted vs plaintext bundles @@ -229,7 +229,6 @@ After import, template changes propagate to deployed instances through revision- | Key | Default | Description | |-----|---------|-------------| | `SourceEnvironment` | `"scadabridge"` | Environment label stamped in `manifest.json` and used in export filenames. | -| `SchemaVersionMajor` | `1` | Major schema version stamped in exported manifests. Not read by the importer; import version-gating uses `ManifestBuilder.CurrentBundleFormatVersion` directly. | | `BundleSessionTtlMinutes` | `30` | TTL for an in-progress import session. | | `MaxBundleSizeMb` | `100` | Upload size cap; enforced before any decompression. | | `MaxBundleEntryCount` | `4` | Maximum ZIP entries (a valid bundle has exactly 2). | diff --git a/docs/requirements/Component-Transport.md b/docs/requirements/Component-Transport.md index 5db7685a..b470aea2 100644 --- a/docs/requirements/Component-Transport.md +++ b/docs/requirements/Component-Transport.md @@ -498,7 +498,7 @@ The `manifest.json` file is always present in the ZIP root and is never encrypte | Field | Description | |---|---| -| `bundleFormatVersion` | Integer. Importer hard-refuses any value higher than what its `TransportOptions.SchemaVersionMajor` supports. Stays `1` through T18. | +| `bundleFormatVersion` | Integer. Importer hard-refuses any value other than the code constant `ManifestBuilder.CurrentBundleFormatVersion`. Stays `1` through T18. The schema and format versions are code constants by design — there is no `Transport:SchemaVersionMajor` option (removed 2026-10-22; it was validated but never read). | | `schemaVersion` | Semver string. Minor increments are additive-only and accepted by older importers. T18 bumped this `1.0 → 1.1` (adding the `sites`/`dataConnections`/`instances` content arrays); a pre-T18 importer lists those new entries as "skipped — unsupported in this version" since `ManifestValidator` gates only on `bundleFormatVersion`. | | `createdAtUtc` | ISO-8601 UTC timestamp of when the export was created. | | `sourceEnvironment` | The `SourceEnvironment` name of the exporting cluster (from `TransportOptions`). Displayed in the import wizard and required to be retyped at the confirm step. | diff --git a/src/ZB.MOM.WW.ScadaBridge.Host/appsettings.Central.json b/src/ZB.MOM.WW.ScadaBridge.Host/appsettings.Central.json index b5c25a7d..0f70cb4f 100644 --- a/src/ZB.MOM.WW.ScadaBridge.Host/appsettings.Central.json +++ b/src/ZB.MOM.WW.ScadaBridge.Host/appsettings.Central.json @@ -84,8 +84,7 @@ "MaxBundleSizeMb": 100, "MaxUnlockAttemptsPerSession": 3, "MaxUnlockAttemptsPerIpPerHour": 10, - "Pbkdf2Iterations": 600000, - "SchemaVersionMajor": 1 + "Pbkdf2Iterations": 600000 }, "Logging": { "MinimumLevel": "Information" diff --git a/src/ZB.MOM.WW.ScadaBridge.Transport/TransportOptions.cs b/src/ZB.MOM.WW.ScadaBridge.Transport/TransportOptions.cs index e8b197f0..6b6c9051 100644 --- a/src/ZB.MOM.WW.ScadaBridge.Transport/TransportOptions.cs +++ b/src/ZB.MOM.WW.ScadaBridge.Transport/TransportOptions.cs @@ -41,8 +41,6 @@ public sealed class TransportOptions public int MaxUnlockAttemptsPerIpPerHour { get; set; } = 10; /// Gets or sets the PBKDF2 iteration count used for passphrase key derivation. public int Pbkdf2Iterations { get; set; } = 600_000; - /// Gets or sets the major version of the bundle schema this instance produces and accepts. - public int SchemaVersionMajor { get; set; } = 1; /// /// Human-readable name of the cluster/environment producing bundles. Stamped diff --git a/src/ZB.MOM.WW.ScadaBridge.Transport/TransportOptionsValidator.cs b/src/ZB.MOM.WW.ScadaBridge.Transport/TransportOptionsValidator.cs index 43799b13..3e57ec6d 100644 --- a/src/ZB.MOM.WW.ScadaBridge.Transport/TransportOptionsValidator.cs +++ b/src/ZB.MOM.WW.ScadaBridge.Transport/TransportOptionsValidator.cs @@ -60,10 +60,6 @@ public sealed class TransportOptionsValidator : OptionsValidatorBase 0, - $"ScadaBridge:Transport:SchemaVersionMajor must be positive " + - $"(was {options.SchemaVersionMajor}); it is the major bundle-schema version this instance emits and accepts."); - builder.RequireThat(!string.IsNullOrWhiteSpace(options.SourceEnvironment), "ScadaBridge:Transport:SourceEnvironment must be a non-empty name; it is stamped into " + "BundleManifest.SourceEnvironment and the export filename."); diff --git a/tests/ZB.MOM.WW.ScadaBridge.Transport.Tests/TransportOptionsValidatorTests.cs b/tests/ZB.MOM.WW.ScadaBridge.Transport.Tests/TransportOptionsValidatorTests.cs index 552a691b..6c7104bd 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.Transport.Tests/TransportOptionsValidatorTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.Transport.Tests/TransportOptionsValidatorTests.cs @@ -132,13 +132,15 @@ public class TransportOptionsValidatorTests Assert.Contains("MaxUnlockAttemptsPerIpPerHour", result.FailureMessage); } - /// Verifies that a zero major schema version is rejected. + /// + /// Verifies that there is no configurable schema-version option: the bundle schema + /// version is the code constant ManifestBuilder.CurrentSchemaVersion, so an + /// option would be a validated no-op (review 2026-10-21 04/U1, 08/O3). + /// [Fact] - public void ZeroSchemaVersionMajor_IsRejected() + public void SchemaVersion_IsNotAConfigurableOption() { - var result = Validate(new TransportOptions { SchemaVersionMajor = 0 }); - Assert.True(result.Failed); - Assert.Contains("SchemaVersionMajor", result.FailureMessage); + Assert.Null(typeof(TransportOptions).GetProperty("SchemaVersionMajor")); } /// Verifies that a blank source environment is rejected.