From 11d00b944209ba4025f2613dde34a279d2ee80e2 Mon Sep 17 00:00:00 2001 From: Mikhail Chusavitin Date: Wed, 29 Apr 2026 09:54:23 +0300 Subject: [PATCH] Document read-only submodules policy --- audit/internal/schema/hardware_test.go | 45 +++++++++++++++++++ bible-local/README.md | 2 +- bible-local/architecture/system-overview.md | 4 +- ...026-04-29-read-only-embedded-submodules.md | 39 ++++++++++++++++ bible-local/decisions/README.md | 1 + 5 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 bible-local/decisions/2026-04-29-read-only-embedded-submodules.md diff --git a/audit/internal/schema/hardware_test.go b/audit/internal/schema/hardware_test.go index 2a09844..d92b20a 100644 --- a/audit/internal/schema/hardware_test.go +++ b/audit/internal/schema/hardware_test.go @@ -44,3 +44,48 @@ func TestHardwareSnapshotMarshalsNewContractFields(t *testing.T) { t.Fatalf("missing event_logs payload: %s", text) } } + +func TestHardwareSnapshotMarshalsStorageTelemetryFields(t *testing.T) { + powerOnHours := int64(12450) + writtenBytes := int64(9876543210) + readBytes := int64(1234567890) + lifeRemainingPct := 91.0 + + payload := HardwareIngestRequest{ + CollectedAt: "2026-03-15T15:00:00Z", + Hardware: HardwareSnapshot{ + Board: HardwareBoard{SerialNumber: "SRV-001"}, + Storage: []HardwareStorage{ + { + SerialNumber: stringPtr("DISK-001"), + Model: stringPtr("TestDisk"), + PowerOnHours: &powerOnHours, + WrittenBytes: &writtenBytes, + ReadBytes: &readBytes, + LifeRemainingPct: &lifeRemainingPct, + }, + }, + }, + } + + data, err := json.Marshal(payload) + if err != nil { + t.Fatalf("marshal: %v", err) + } + text := string(data) + for _, needle := range []string{ + `"storage":[{`, + `"power_on_hours":12450`, + `"written_bytes":9876543210`, + `"read_bytes":1234567890`, + `"life_remaining_pct":91`, + } { + if !strings.Contains(text, needle) { + t.Fatalf("missing %q in payload: %s", needle, text) + } + } +} + +func stringPtr(v string) *string { + return &v +} diff --git a/bible-local/README.md b/bible-local/README.md index 5e4e75b..c75a83b 100644 --- a/bible-local/README.md +++ b/bible-local/README.md @@ -10,4 +10,4 @@ Generic engineering rules live in `bible/rules/patterns/`. | `architecture/system-overview.md` | What bee does, scope, tech stack | | `architecture/runtime-flows.md` | Boot sequence, audit flow, service order | | `docs/hardware-ingest-contract.md` | Current Reanimator hardware ingest JSON contract | -| `decisions/` | Architectural decision log | +| `decisions/` | Architectural decision log, including read-only submodule policy | diff --git a/bible-local/architecture/system-overview.md b/bible-local/architecture/system-overview.md index 67073fb..51e06c7 100644 --- a/bible-local/architecture/system-overview.md +++ b/bible-local/architecture/system-overview.md @@ -58,6 +58,8 @@ Fills gaps where Redfish/logpile is blind: - `bee` should populate current component state, hardware inventory, telemetry, and `status_checked_at`. - Historical status transitions and component replacement logic belong to the centralized ingest/lifecycle system, not to `bee`. - Contract fields that have no honest local source on a generic Linux host may remain empty. +- Embedded submodules such as `internal/chart/` and `bible/` are read-only for `bee` feature work. +- If the UI needs extra information, `bee` must emit it through the standard audit JSON contract rather than patching `chart`. ## Tech stack @@ -101,7 +103,7 @@ Fills gaps where Redfish/logpile is blind: | `iso/builder/` | ISO build scripts and `live-build` profile | | `iso/overlay/` | Source overlay copied into a staged build overlay | | `iso/vendor/` | Optional pre-built vendor binaries (storcli64, sas2ircu, sas3ircu, arcconf, ssacli, …) | -| `internal/chart/` | Git submodule with `reanimator/chart`, embedded into `bee web` | +| `internal/chart/` | Git submodule with `reanimator/chart`, embedded into `bee web`; update by submodule pointer only, never by local `bee`-specific edits | | `iso/builder/VERSIONS` | Pinned versions: Debian, Go, NVIDIA driver, kernel ABI | | `iso/builder/smoketest.sh` | Post-boot smoke test — run via SSH to verify live ISO | | `iso/overlay/etc/profile.d/bee.sh` | tty1 welcome message with web UI URLs | diff --git a/bible-local/decisions/2026-04-29-read-only-embedded-submodules.md b/bible-local/decisions/2026-04-29-read-only-embedded-submodules.md new file mode 100644 index 0000000..929d75e --- /dev/null +++ b/bible-local/decisions/2026-04-29-read-only-embedded-submodules.md @@ -0,0 +1,39 @@ +# Decision: Treat embedded submodules as read-only + +## Context + +`bee` embeds external git submodules such as: + +- `internal/chart/` — `reanimator/chart`, a generic read-only viewer for Reanimator JSON snapshots +- `bible/` — shared engineering rules and contracts + +These repositories are reused by other projects. A local feature request in `bee` +must not be solved by silently changing shared submodule behavior. + +The concrete failure mode here was attempting to add project-specific storage +telemetry presentation by editing `internal/chart/`. That couples a shared viewer +to one host application's needs and creates hidden cross-project regressions. + +## Decision + +Embedded submodules are read-only from the point of view of `bee`. + +- Do not implement `bee`-specific behavior by editing `internal/chart/`. +- Do not implement `bee`-specific behavior by editing `bible/`. +- If `bee` needs new data in the report, produce it in the standard audit JSON + emitted by `bee` itself. +- `chart` must continue to consume the canonical snapshot as an external viewer, + without host-specific forks. +- Updating a submodule pointer to an upstream commit is allowed. +- Carrying local unmerged submodule commits as part of a `bee` feature is forbidden. + +## Consequences + +- Audit/report features must be expressed through the contract in + `bible-local/docs/hardware-ingest-contract.md`. +- `bee` owns collection, normalization, and serialization of storage telemetry in + `hardware.storage[]`. +- `chart` remains a pure visualization module that reads the snapshot it is given. +- If a capability is genuinely missing in a shared submodule, it must be proposed + and landed upstream as a generic change first, then pulled into `bee` via a + normal submodule update. diff --git a/bible-local/decisions/README.md b/bible-local/decisions/README.md index 38b7485..a9251e0 100644 --- a/bible-local/decisions/README.md +++ b/bible-local/decisions/README.md @@ -6,3 +6,4 @@ One file per decision, named `YYYY-MM-DD-short-topic.md`. |---|---|---| | 2026-03-05 | Use NVIDIA proprietary driver | active | | 2026-04-01 | Treat memtest as explicit ISO content | active | +| 2026-04-29 | Treat embedded submodules as read-only | active |