diff --git a/.github/workflows/standards-checks.yml b/.github/workflows/standards-checks.yml index 2658d3f..d04a73a 100644 --- a/.github/workflows/standards-checks.yml +++ b/.github/workflows/standards-checks.yml @@ -18,3 +18,5 @@ jobs: python-version: "3.13" - name: Enforce synchronized NikaS UI v2.2 mirror run: python scripts/check_nikas_ui_standard.py + - name: Verify the revision-pinned repository contract mirror + run: python scripts/check_repository_contract_mirror.py diff --git a/.nikas-repository-contract-source.json b/.nikas-repository-contract-source.json new file mode 100644 index 0000000..e539e6e --- /dev/null +++ b/.nikas-repository-contract-source.json @@ -0,0 +1,8 @@ +{ + "contract_version": "1.0", + "canonical_repository": "NikaSir/ha-contract-generated-ui", + "canonical_path": "docs/NIKAS_REPOSITORY_CONTRACT.md", + "local_path": "NIKAS_REPOSITORY_CONTRACT.md", + "sha256": "ea0f62f74e6880bc5d9de2199232a5e4c561ef4ba6c2d12039affed2e78f5dcc", + "canonical_revision": "78150ef18514ace061ba60fbd509e05f4810ba05" +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1d72b96..8a6c052 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,6 +9,12 @@ Thank you for contributing. 3. Base changes on the repository's default branch unless the repository documents a different workflow. 4. Update documentation and changelog information when behavior, configuration, entities, APIs, or installation steps change. 5. Run the repository's validation and tests before requesting review. +6. Identify the production artifact actually registered by the integration and + record the inspected revision, version/cache bindings and applicable + [NikaS Repository Contract](NIKAS_REPOSITORY_CONTRACT.md) results. +7. Distinguish profile validity, automated product checks and HA/iPhone + acceptance. A missing or stale result is unverified; a listed test or source + keyword alone is not behavioural evidence. ## Engineering requirements @@ -18,6 +24,12 @@ Thank you for contributing. - Treat `unknown`, `unavailable`, timeout, and stale data as explicit states when they affect system behavior. - Avoid silent failure. Errors that affect correctness or safety should be observable. - Keep dependencies minimal and justified. +- Preserve source, accepted-sample time and quality with operational values; + missing data cannot become zero, false, healthy status or command confirmation. +- Test reconnect after cancelled requests, timers and animation frames. Keep + existing UI nodes stable during telemetry updates. +- Preserve the existing mandatory CI checks and approved product layout when + adopting shared tooling. Record remaining gaps explicitly. ## Commits diff --git a/GOVERNANCE.md b/GOVERNANCE.md index 457afba..c1997a4 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -12,7 +12,10 @@ Projects under the `NikaSir` account use a maintainer-led governance model. ## Traceability -Significant changes should be traceable through issues, pull requests, commits, changelog entries, and release tags as appropriate. +Significant changes should be traceable through issues, pull requests, source +commits, changelog entries and versioned validation evidence. NikaS publication +uses reviewed `main` changes; GitHub Releases and automatic release tags are not +created. Historical tags are not changed by tooling adoption. ## Repository autonomy diff --git a/NIKAS_REPOSITORY_CONTRACT.md b/NIKAS_REPOSITORY_CONTRACT.md new file mode 100644 index 0000000..2941cd1 --- /dev/null +++ b/NIKAS_REPOSITORY_CONTRACT.md @@ -0,0 +1,209 @@ +# NikaS Repository Contract v1.0 + +Status: normative engineering contract for adoption through reviewed pull requests. +Authority: `NikaSir/ha-contract-generated-ui`. +Companion standards: NikaS Specialized Panel UI Standard v2.2, Navigation +Contract v1.2, and Shell v2.1. This document does not replace their requirements +or declare existing implementations compliant. + +## 1. Purpose and scope + +Every maintained NikaS repository must describe what it actually supplies, +which requirements apply, what has been verified, and how the verified change +reaches Home Assistant. The description and its evidence are versioned with the +source they describe. + +A repository may have several roles: standards authority, integration, +panel, service, or explicitly unfinished scaffold. Applicability follows its +active components and capabilities, not its name or a convenient repository +label. Retained historical files are not runtime artifacts unless the active +setup or load graph actually reaches them. + +Each integration remains autonomous at runtime. Shared validators, schemas and +build-time source may be reused during development or CI. A running panel must +not depend on another NikaS repository, an older panel installation, or a remote +script to supply its shell, navigation or domain logic. + +## 2. One factual description of delivery + +The machine-readable profile records: + +- repository identity and the exact source revision inspected; +- active integration domains and manifests; +- each actually registered production entrypoint and its registration evidence; +- related integration, UI and cache versions with their separate bindings; +- applicable normative documents and the observed versions/hashes; +- publication channel and real CI workflows/checks; +- behavioural, browser and device acceptance evidence, or its absence. + +During this first adoption stage, profiles are maintained centrally under +`deployments/repository-contracts/`. A profile is an inventory of a particular +source revision; it does not overwrite the consumer's existing contract or +silently upgrade its standard version. Consumer-local profiles and required +gates are introduced through subsequent focused migration PRs. + +Profile paths must remain inside the inspected repository. A profile must not +execute arbitrary shell commands or load device/integration code to obtain +facts. Unsupported static expressions produce an explicitly unverified result. +Do not guess the target from an old filename, comments, or a declaration that +is not connected to the active registration. + +The validator itself has a versioned source and schema. Updating the tool or +normative baseline is a reviewed change; no floating external implementation +may silently change an existing CI requirement. + +## 3. Production and versions + +Registration, static URL mapping, shipped file and validation target must agree. +CI validates the code Home Assistant actually loads, including reachable local +dependencies. A syntax check of a historical base file is insufficient. + +Integration and UI versions are independent. Each must agree with its own +manifest, runtime exposure, registration and cache bindings. A behaviour change +requires the appropriate version/cache update under the existing product policy. +Do not renumber integrations merely to introduce repository tooling. + +Specialized production panels retain the existing requirement for one autonomous +bundle. Reachable historical imports are a compliance failure even when a factual +profile accurately records them. Refactoring a chain must preserve approved +behaviour and layout; deleting still-imported files is not a migration. + +Builds must be reproducible. CI rebuilds and checks for a diff or uses an +equivalent deterministic check. Static validation of registration is separate +from proof that the browser loads and operates the panel. + +## 4. Data quality + +Every operational value has a source, value, accepted-sample time and quality. +Implementations must distinguish valid zero/false from missing, unknown, +unavailable, malformed, and preserved stale values. + +- Transport, freshness and completeness are independent facts. +- Old cache may be shown with its age/quality; it must not become a fresh green + reading because another measurement updated. +- A partial aggregate is unknown or explicitly partial, never a complete total + obtained by replacing missing contributions with zero. +- Bootstrap data cannot indefinitely override newer authoritative state. +- An unchanged HA state may still have fresh telemetry. `last_updated` alone + does not establish the age of the last accepted device exchange. +- A selected operating mode does not establish physical execution, such as + compressor operation or active heating. + +The two-level connection plaque is used only where requested. This contract +does not add it to StarLine or Home now, invent device selectors for a single +system, or change approved product terminology. + +## 5. Commands and confirmation + +The backend validates capability, target, current mode and session before a +write. The frontend reflects the same capability and busy state. Product-specific +requirements for explicit Apply and confirmation remain in force. + +Missing information cannot authorize a command. Stale queued intentions must +not be reused after the operation/session that created them has ended. Duplicate +submissions are prevented without leaving controls permanently locked. + +Successful service dispatch is not proof of physical execution. An unknown or +unavailable readback cannot confirm a requested zero/off state. Timeout and +failure remain observable; the UI must not invent success or automatically retry +a consequential write unless the product contract explicitly provides for it. + +Read-only integrations and scaffolds remain read-only. Telemetry refresh is not +a hidden equipment command. Event inputs that can change state require a +documented, enforced source-trust model. + +## 6. Lifecycle and stable interface + +Each request, timer, animation frame, subscription and lock has a defined owner, +cancellation rule and reconnect path. Detach/attach of the same component must +restore operation. Cancelled work cannot leave a permanent loading flag, frame +identifier or command lock. Late responses cannot replace newer accepted state. + +Mount the application shell and stable device controls once. Telemetry changes +patch their content and attributes; they do not recreate the shell, images or +controls. Preserve focus, scroll, selection and valid zoom bounds. Existing +phone/tablet/desktop acceptance requirements remain applicable. + +## 7. Evidence and result semantics + +Profile/schema validity and product compliance are separate results. A valid +inventory with known defects is not a compliant implementation. + +| Result | Meaning | +|---|---| +| `pass` | This specific check has sufficient matching evidence and passed. | +| `fail` | A concrete requirement is contradicted by inspected source or evidence. | +| `not_verified` | Applicable, but evidence is absent, stale, ambiguous or unsupported. | +| `not_applicable` | Excluded by the component's actual capability and a recorded reason. | + +Strict compliance fails if any applicable requirement is `fail` or +`not_verified`. A malformed profile is an input error. The checker produces its +report before returning a nonzero status, so failures remain reviewable. + +No automatic waivers, expected-failure-to-success conversion, or previous-gap +baseline can turn a missing requirement into `pass`. Open audit findings remain +open until closure evidence is recorded. Merely listing a test or finding a +keyword in source is not behavioural evidence. + +Evidence identifies the checked revision, relevant artifact hashes, scenario, +runner/environment and result. Evidence from an older revision cannot silently +certify the current production. Automated source checks, behavioural tests, +browser checks, and acceptance on HA/iPhone are distinct claims. + +## 8. Required scenario families + +Use small behavioural tests that reproduce a failure or protect a public +contract. Required families depend on the component: + +1. Data: missing/null/unknown/unavailable, real zero/off, stale cache, partial + responses and conflict between an old bootstrap and newer state. +2. Commands: wrong mode/session/capability produces zero writes; duplicate + submission; unconfirmed readback; successful verified execution. +3. Lifecycle: detach/attach during a request, cooldown and animation frame; + late response; disconnect and recovery. +4. UI: stable node identity/focus/scroll during telemetry, correct return route, + cold load and applicable viewport acceptance. +5. Publication: registered artifact equals validated artifact; version/cache + coherence; reproducible build; required checks really execute. + +Protocol and hardware scenarios use verified device-specific mappings. A similar +device profile is not evidence of compatible commands. Synthetic tests must not +dispatch commands to live equipment. + +## 9. CI and publication + +Preserve existing mandatory checks when adding the contract. Give jobs unique +names across workflows. Do not use a single ambiguous `validate` context for +several independent checks. + +An aggregate gate must run even after dependency failure and explicitly require +all mandatory dependencies to have succeeded. Skipped, cancelled and missing +results are not success. `needs` connects jobs within a workflow; cross-workflow +checks require separate required contexts or another verified aggregation. + +The common GitHub baseline is a PR to `main`, required applicable checks, +conversation resolution, and protection from force push and deletion. Installing +a document or CI file does not itself configure GitHub branch protection; +settings need separate readback verification. Do not remove an existing required +check to make a migration mergeable. + +NikaS publication remains reviewed commits/PRs and `main` through HACS where +applicable. GitHub Releases and automatic release tags are not created. Existing +historical publication objects are not deleted as part of tooling adoption. + +## 10. Adoption sequence and completion + +1. Review the canonical contract, schema, validator and central profiles. +2. Run strict inspection against exact source revisions. Keep every failure and + unverified requirement visible; a tooling test pass is not fleet readiness. +3. Introduce consumer-local profiles and CI in focused PRs; preserve earlier + checks. Close product gaps with their own small tested changes. +4. Promote strict compliance to a required check for each repository once its + applicable gaps are closed and its job name/trigger has been verified. +5. Complete the applicable HA/iPhone acceptance and record the accepted revision. + +This first package implements the common contract and inspection mechanism. It +does not assert that all 17 consumers have migrated, change their equipment +commands or approved layouts, or change their GitHub settings automatically. +Completion is measured separately for tooling, consumer adoption, product +compliance and device acceptance. diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 82a9854..fa33356 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -6,6 +6,12 @@ Describe the change and the problem it solves. Explain how the change was tested and include relevant environment details. +For integration/panel or delivery changes, identify the actual registered +production entrypoint, integration/UI/cache versions and checked source revision. +State separately: profile validity, strict compliance, and any HA/iPhone +acceptance. List failed or unverified applicable requirements and their tracking +items; do not describe a tooling-only pass as product readiness. + ## Compatibility and migration Describe any breaking changes, migration steps, configuration changes, or compatibility impact. Write `None` when not applicable. @@ -18,3 +24,7 @@ Describe any breaking changes, migration steps, configuration changes, or compat - [ ] No credentials, tokens, keys, recovery codes, personal data, or other secrets are included. - [ ] Error, `unknown`, `unavailable`, timeout, and stale-data behavior was considered where relevant. - [ ] Breaking changes are explicitly documented. +- [ ] Validation covers the artifact Home Assistant actually loads. +- [ ] Missing/stale data and unconfirmed commands remain distinguishable from valid zero/off/success. +- [ ] Applicable reconnect and stable-DOM scenarios were checked, or are explicitly recorded as unverified. +- [ ] Existing required checks and main/HACS publication policy are preserved. diff --git a/README.md b/README.md index 6c24b0c..99ebd1f 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,10 @@ The goal is to keep contribution, support, security, issue, pull-request, reposi ## Defaults and shared standards provided +- `NIKAS_REPOSITORY_CONTRACT.md` — mirror of the canonical repository contract + for factual delivery, data quality, commands, lifecycle and validation evidence. + Canonical schema, tooling and adoption registry are maintained in + `NikaSir/ha-contract-generated-ui`; see the contract's adoption sequence. - `CONTRIBUTING.md` — contribution and change-control rules. - `SECURITY.md` — responsible vulnerability reporting. - `SUPPORT.md` — support and diagnostic expectations. diff --git a/REPOSITORY_STANDARD.md b/REPOSITORY_STANDARD.md index d044831..84d938f 100644 --- a/REPOSITORY_STANDARD.md +++ b/REPOSITORY_STANDARD.md @@ -30,7 +30,24 @@ Apply a ruleset targeting `main` with the following baseline: 6. Do not require signed commits until a signing workflow is deliberately adopted. 7. Do not require a fixed approval count for a single-maintainer repository unless an additional reviewer is actually part of the project. -When the bootstrap workflow is present, use its `validate` job as a required status check. When Hassfest/HACS/test jobs are added, promote them to required checks only after they have proved stable. +Give every required job a unique name across workflows, such as +`repository-checks`, `hacs`, `hassfest` and `nikas-strict-compliance`. Preserve +existing required checks during migration. Rename jobs and update required +contexts together so no old name is left waiting indefinitely. + +A result for one generic `validate` context must not stand for several +independent workflows. If using an aggregate gate, run it after failed or +skipped dependencies and explicitly require every mandatory result to be +`success`. Cross-workflow jobs need separate required contexts or another +verified aggregation mechanism. Check path filters before making a job required. + +The [NikaS Repository Contract](NIKAS_REPOSITORY_CONTRACT.md) distinguishes +profile validity from strict product compliance. During adoption, strict +inspection reports actual failures and unverified requirements. It becomes +required for a consumer once those applicable gaps are closed and its trigger +and job name have been verified. This does not waive a standard or remove an +existing check. A document in this defaults repository does not automatically +configure another repository's branch protection. ## Security diff --git a/scripts/check_repository_contract_mirror.py b/scripts/check_repository_contract_mirror.py new file mode 100644 index 0000000..c927c49 --- /dev/null +++ b/scripts/check_repository_contract_mirror.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +"""Check the reviewed local mirror identity and content digest.""" + +import hashlib +import json +from pathlib import Path +import re + +ROOT = Path(__file__).resolve().parents[1] +metadata = json.loads((ROOT / ".nikas-repository-contract-source.json").read_text()) +assert metadata["contract_version"] == "1.0", "Unexpected repository contract version" +assert metadata["canonical_repository"] == "NikaSir/ha-contract-generated-ui" +assert metadata["canonical_path"] == "docs/NIKAS_REPOSITORY_CONTRACT.md" +assert re.fullmatch(r"[0-9a-f]{40}", metadata["canonical_revision"]), "Pin the reviewed canonical revision" +assert metadata["local_path"] == "NIKAS_REPOSITORY_CONTRACT.md" +document = (ROOT / metadata["local_path"]).read_bytes() +assert hashlib.sha256(document).hexdigest() == metadata["sha256"], "Repository contract mirror digest mismatch" +assert document.startswith(b"# NikaS Repository Contract v1.0\n") +print("Repository Contract v1.0 mirror matches its reviewed, revision-pinned digest.")