diff --git a/README.md b/README.md index 00d032b..1b26287 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Container Platform defines the contract for an **Online Shop** release composed The project does not build application code or operate a Kubernetes cluster. Its target workflow turns images published to Docker Hub into a versioned release bundle pinned by digests for review, validation and promotion to the SRE Platform. -> **Status:** Release contract v1 is defined; a digest-pinned baseline candidate and profile inventory are available for review. Offline and opt-in registry metadata checks, PR checks, Compose rendering and an opt-in runtime runner are available; required-check rules are owner-configured. Runtime evidence remains subject to recorded live results; SRE handoff remains planned. +> **Status:** Release contract v1, baseline/inventory records, offline/registry checks, PR checks and Compose rendering/runtime smoke are implemented. One hosted baseline smoke run passed; legacy eligibility remains negative. The active main-protection ruleset and owner-confirmed Required check labels are recorded; pending-check blocking remains unverified. SRE handoff remains planned. ## Why this platform exists @@ -39,7 +39,7 @@ The two paths into the SRE Platform have different roles: - Docker Hub is the data path: Kubernetes nodes pull the approved images from `dmitryzhuravlev/online-shop-*`. - Container Platform is the release-control path: it identifies the exact image digests that are approved together as one Online Shop release. -The diagram describes target relationships. Offline, opt-in Docker Hub metadata, PR checks and Compose rendering are implemented; required-check configuration remains an owner action. Runtime evidence is reported separately; SRE handoff remains planned. +The diagram describes target relationships. Offline, opt-in Docker Hub metadata, PR checks and Compose rendering are implemented; the active main-protection ruleset requires the three PR checks. Runtime evidence is reported separately; SRE handoff remains planned. ## Responsibilities @@ -55,7 +55,7 @@ The diagram describes target relationships. Offline, opt-in Docker Hub metadata, 1. CI Build Platform builds and publishes individual Online Shop images to Docker Hub. 2. A full release manifest records immutable digests and per-component source/build references under the contract, with explicit legacy gaps and separate third-party dependency rules. 3. Container Platform validates the manifest and the published image references through pull-request checks. -4. A release PR may represent approval only after authorized review and all documented mandatory checks pass; merge alone is not validation. These gates are not implemented yet. +4. A release PR may represent approval only after authorized review and all documented mandatory checks pass; merge alone is not validation. Checks and main protection are configured; release authorization remains a separate decision. 5. A promotion change updates the SRE Platform's GitOps configuration to the exact digests from that release. 6. Argo CD applies the GitOps change, and GKE pulls the same images from Docker Hub. @@ -115,7 +115,7 @@ Add `--registry` to inspect immutable manifest/config bytes and declared platfor ## Pull request checks -[GitHub Actions validation](docs/pull-request-validation.md) runs tests/package checks on Python 3.11 and 3.13 and a stable release check. New candidates receive opt-in registry validation; merged release files are immutable. No candidate changes produces an explicit successful result. The historical legacy baseline remains a negative regression fixture. Workflow availability does not configure required merge checks or grant release approval. +[GitHub Actions validation](docs/pull-request-validation.md) runs tests/package checks on Python 3.11 and 3.13 and a stable release check. New candidates receive opt-in registry validation; merged release files are immutable. No candidate changes produces an explicit successful result. The historical legacy baseline remains a negative regression fixture. [Main protection](docs/main-protection.md) records read-only observations, owner settings and the PR enforcement checklist; green CI alone does not prove protected merges or grant release approval. ## Compose configuration @@ -125,4 +125,4 @@ Add `--registry` to inspect immutable manifest/config bytes and declared platfor [Bounded runtime smoke](docs/runtime-smoke.md) requires explicit `--execute`, consumes the rendered candidate snapshot and cleans up its unique Compose project. It checks service process state and a synthetic catalog/cart/checkout flow. Inspection-only baseline execution preserves legacy ineligibility. See the recorded live outcome and limitations; runtime success is separate from release approval and deployment authorization. -[Manual hosted smoke](docs/manual-smoke-workflow.md) adds a dispatch-only workflow with sanitized evidence and best-effort scoped recovery. Its first hosted baseline run remains pending default-branch workflow registration and owner dispatch; it is not a mandatory PR check. +[Manual hosted smoke](docs/manual-smoke-workflow.md) is registered and has a [successful baseline dispatch](https://github.com/DimitryZH/container-platform/actions/runs/40046455406): 12 exact-image services, readiness, five semantic assertions and verified cleanup. Inspection-only preserved validation exit 1 and 12 legacy failures. Runtime smoke is not a mandatory PR check or release approval; live cancellation recovery remains unverified. diff --git a/docs/main-protection.md b/docs/main-protection.md new file mode 100644 index 0000000..f82ba1a --- /dev/null +++ b/docs/main-protection.md @@ -0,0 +1,59 @@ +# Main protection: owner setup and verification + +Workflow availability, passing CI and enforced merge requirements are separate facts. Repository settings are changed manually by the owner, not by this documentation change. + +## Confirmed configuration: 2026-10-24 + +Read-only API inspection confirmed repository branch ruleset [main-protection](https://github.com/DimitryZH/container-platform/rules/25802975), ID `25802975`, with the same rules returned by the effective-rules endpoint for `main`. + +| Setting | Confirmed value | +|---|---| +| Enforcement | `active` | +| Target | `~DEFAULT_BRANCH`, currently `main`; no exclusions | +| Bypass actors | Empty; current API caller's bypass permission is `never` | +| Require a pull request | Enabled | +| Required approving reviews | **0** | +| Conversation resolution | Enabled (`required_review_thread_resolution: true`) | +| Required checks | The three exact names below, from GitHub Actions | +| Branch must be up to date | Enabled (`strict_required_status_checks_policy: true`) | +| Force pushes | Blocked (`non_fast_forward`) | +| Branch deletion | Blocked (`deletion`) | +| Ordinary update restriction / branch lock | Not configured; normal PR merges remain possible | + +Required checks: + +- `Tests and package (Python 3.11)` +- `Tests and package (Python 3.13)` +- `Release check` + +Manual runtime smoke is not required. Code-owner review and last-push approval requirements are off; allowed merge methods are merge, squash and rebase. No rules were changed by this documentation update. + +The owner confirmed in the merge section of [PR #18](https://github.com/DimitryZH/container-platform/pull/18) that all three checks were labelled **Required** and successful before this documentation follow-up (revision `99e7ff4888e966f2edb92b690836da84df95dc65`). This owner UI observation and the read-only active-rule/effective-rule inspection establish configured requirements; green CI alone would not establish them. New commits still require their own successful checks. + +**Verification limit:** pending-check blocking was not separately observed. The PR remains Draft; Draft blocking is not evidence of blocking by a pending required check. Live cancellation recovery also remains unverified. + +The earlier read-only observation on 2026-10-24 returned `protected: false`, classic-protection HTTP 404 and empty ruleset/effective-rule lists. That pre-configuration observation is superseded by the confirmed active ruleset above. If future API access is denied or unavailable, record the state as **unverified**, rather than inferring that rules are absent. + +## Maintaining the owner-managed rule + +Keep `main-protection` Active with the table's settings and an empty bypass list. Do not enable ordinary-update restrictions that prevent PR merges, add manual runtime smoke as a required check, or add a merge-queue requirement (`merge_group` is unsupported by the current workflows). + +Zero approvals supports the solo-maintainer process; maintainer self-review is not independent approval. Review workflow, policy, inventory and validator changes carefully: PR-authored checks are not tamper-proof against their author. An administrator's ability to edit/remove rules is separate from a configured merge bypass; do not describe the empty bypass list as protection against authorized settings changes. + +See GitHub's [available rules](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets) and [ruleset setup](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/creating-rulesets-for-a-repository). + +## If the UI offers classic branch protection + +Use an exact `main` branch protection rule with PRs required. If the approval dropdown starts at one, leave the separate **Require approvals** checkbox off to express zero approvals; keep the PR requirement enabled. Enable conversation resolution, the same three required checks and strict/up-to-date checking. Enable **Do not allow bypassing the above settings** (administrator enforcement); leave PR bypass actor lists empty. Leave **Allow force pushes**, **Allow deletions**, branch locking and update/push restrictions off. See [classic protection settings](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches). + +The current configuration uses the confirmed ruleset above, not this classic alternative. If the owner changes models later, record the actual target/enforcement state, check names, approval count and bypass actor/mode. Do not claim a no-bypass equivalent while an administrator exemption remains enabled; avoid unexplained overlapping rules. + +## Owner checklist on the documentation PR + +1. Confirm the saved active rule applies to `main`; read back checks, up-to-date/conversation requirements, zero approvals, deletion/force-push restrictions and the empty bypass list. Update this observation with the actual configuration if it differs. +2. In the PR checks/merge section, confirm **each exact name above is marked required**, comes from GitHub Actions and passes on the current PR revision. Green optional checks alone do not establish enforcement. +3. Check for unresolved conversations or an out-of-date branch and verify the corresponding merge requirement, if naturally present. A Draft PR's merge restriction is a separate blocker, not evidence that branch protection works. Do not merge or mark Ready merely to perform this inspection. +4. If a pending required check is naturally observed after rule activation, record whether the merge section blocks on it. Do not manufacture failures or direct-push to `main`. If pending-check blocking was not observed, explicitly retain that limitation. +5. Record the PR URL/revision, rule state, three check outcomes and any visible bypass permission. Keep issue #17 and the milestone open until enforcement evidence and the changes are accepted. + +The active rule and owner-confirmed Required labels are now recorded. Pending-check blocking and live cancellation recovery remain unverified; neither follows from green CI or Draft blocking. Issue/milestone acceptance and any merge remain owner decisions. diff --git a/docs/manual-smoke-workflow.md b/docs/manual-smoke-workflow.md index 9fcc3bc..6a3bc4a 100644 --- a/docs/manual-smoke-workflow.md +++ b/docs/manual-smoke-workflow.md @@ -24,26 +24,37 @@ The runner retains its normal interruption cleanup. A minimal pre-mutation hook Best-effort recovery and upload cannot be guaranteed after forced cancellation, repeated interruption, job timeout, Engine failure or runner loss. Cancellation recovery has offline adapter coverage but has not been verified by a live cancellation experiment. Ephemeral-host disposal is separate from verified application cleanup. A successful ordinary run must contain successful runner cleanup plus verified workflow resource absence. -## Hosted acceptance: pending registration +## Hosted acceptance -As of 2026-10-23, this workflow is absent from the default branch's registered workflows. GitHub [requires the dispatch workflow to exist on the default branch](https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#workflow_dispatch). No hosted runtime dispatch has been performed; prior local runtime evidence does not satisfy this criterion. No temporary PR/push runtime trigger or substitute workflow is used. +The workflow is registered on the default branch. One actual [workflow_dispatch run](https://github.com/DimitryZH/container-platform/actions/runs/40046455406) completed successfully on `main`. -After owner review and merge register the workflow on `main`: +| Evidence | Observed result | +|---|---| +| Tested commit | `58241e3db4c8a2e15ec9a675be425e42d89759f9` | +| Candidate | `releases/baseline-2026-10-18.json`, release ID `baseline-2026-10-18-001` | +| Candidate byte SHA-256 | `4c4dcb50b8cbe6f8bd9955766d6149b12cb3f31c693705bb0f6aa1390227e9d9` | +| Profile / mode | `aml-online-shop-compose-v1`, explicit inspection-only | +| Services | All 12 running with the candidate's exact repository/digest references | +| Readiness / semantics | Readiness and all five catalog/product/cart/add-remove/synthetic-checkout assertions passed | +| Runtime | Exit 0, 47.627 seconds | +| Runner cleanup | `success` | +| Workflow cleanup | `verified_absent` for the exact project's containers, networks and volumes | +| Offline validation | Exit 1 with 12 `legacy_ineligible` failures | +| Evidence | Valid sanitized `compose-smoke-evidence/report.json`; published job summary verified during the original review | -1. Dispatch the baseline with explicit inspection-only: +On 2026-10-24, the run metadata and successful job steps were rechecked. The artifact was still available (expiry `2026-10-31T00:45:23Z`), downloaded again and verified against the tested commit's Git blob, exact image set, assertions, cleanup and retained legacy failures. Summary verification above refers to the original review, not a newly claimed summary download. After retention expiry, distinguish this recorded verification from whatever primary evidence remains accessible; do not claim a fresh artifact inspection without actually downloading it. - ```text - gh workflow run manual-smoke.yml --repo DimitryZH/container-platform --ref main -f candidate=releases/baseline-2026-10-18.json -f profile=aml-online-shop-compose-v1 -f inspection_only=true - ``` +This is evidence for one selected demo flow, not production readiness, performance, provenance, release approval or deployment authorization. Historical negative/local observations remain in [runtime smoke evidence](runtime-smoke.md). Live cancellation recovery remains unverified. [Main protection](main-protection.md) and milestone closure are separate owner decisions; runtime smoke is not a required PR check. -2. Find and inspect the actual dispatch run: +## Future manual dispatch and evidence review - ```text - gh run list --repo DimitryZH/container-platform --workflow manual-smoke.yml --event workflow_dispatch --limit 5 - gh run view RUN_ID --repo DimitryZH/container-platform - gh run download RUN_ID --repo DimitryZH/container-platform --name compose-smoke-evidence - ``` +For a deliberate future run (not required merely to refresh this documentation): -3. Confirm the intended tested SHA, candidate hash and exact images, all 12 service records, semantic assertions, runtime exit 0, successful runner cleanup, verified workflow resource absence and retained validation exit 1 with 12 legacy failures. Confirm artifact and summary availability. Record a concise hosted observation tied to the run URL; keep issue #15 open until this evidence is reviewed. +```text +gh workflow run manual-smoke.yml --repo DimitryZH/container-platform --ref main -f candidate=releases/baseline-2026-10-18.json -f profile=aml-online-shop-compose-v1 -f inspection_only=true +gh run list --repo DimitryZH/container-platform --workflow manual-smoke.yml --event workflow_dispatch --limit 5 +gh run view RUN_ID --repo DimitryZH/container-platform +gh run download RUN_ID --repo DimitryZH/container-platform --name compose-smoke-evidence +``` -No hosted success, cancellation recovery or milestone completion is claimed before those checks occur. +Confirm the intended tested SHA, candidate hash and exact images, all 12 service records, semantic assertions, runtime exit 0, successful runner cleanup, verified workflow resource absence and retained validation exit 1 with 12 legacy failures. Confirm artifact and summary availability, and record the specific run URL. Never infer release eligibility from runtime success. diff --git a/docs/pull-request-validation.md b/docs/pull-request-validation.md index 41823ed..1ce291d 100644 --- a/docs/pull-request-validation.md +++ b/docs/pull-request-validation.md @@ -55,8 +55,10 @@ Orchestration JSON version 1 includes the overall result/exit, discovery result, ## Owner-configured merge protection -This change supplies workflow checks; it does **not** configure required checks or protect merges. The owner should configure a `main` ruleset/branch protection requiring pull-request review and all three stable checks above. Require the PR branch to be current with the base before merging, or introduce an explicitly designed merge-queue workflow later; `merge_group` is not supported here. Review ownership should cover workflows, validator/orchestration, schema, inventory, package helper and tests. Configure owner review requirements separately; no CODEOWNERS identities or rulesets are created automatically by this task. +The [main protection guide](main-protection.md) records the current read-only settings observation, exact owner configuration and enforcement checklist. The confirmed active `main-protection` ruleset targets the default branch `main` and requires PRs, **zero approving reviews** for the solo-maintainer process, resolved conversations, all three stable checks above, an up-to-date branch, no force pushes/deletion and no bypass entries. Do not enable ordinary-update restrictions that prevent normal PR merges. Manual runtime smoke is optional and must not be a required check. `merge_group` is not supported. -Only `pull_request` executes PR code, never `pull_request_target`. Jobs use GitHub-hosted unprivileged runners and `contents: read`; there are no registry/cloud credentials, new secrets, write-token/comment jobs, OIDC permissions or privileged workflow handoffs. The workflow tests code supplied by the PR author, including workflow/validator changes: it is **not independent tamper-proof enforcement**. Approval and required owner review/rules remain essential. Fork workflow approval or Actions organization policies may require owner action before jobs run. +A maintainer's self-review is not independent approval. The active ruleset is confirmed read-only, and the owner confirmed all three checks labelled Required and successful on PR #18. Green check runs alone would demonstrate CI execution, not configured requirements. Pending-check blocking must remain unverified unless it was actually observed after activation. No repository protection setting is changed by these documentation updates. -Checks establish regression behavior and selected candidate eligibility under implemented policy, not application compatibility, container-release approval or SRE deployment authorization. Compose integration, image publication, promotion and legacy exceptions remain outside this change. +Only `pull_request` executes PR code, never `pull_request_target`. Jobs use GitHub-hosted unprivileged runners and `contents: read`; there are no registry/cloud credentials, new secrets, write-token/comment jobs, OIDC permissions or privileged workflow handoffs. The workflow tests code supplied by the PR author, including workflow/validator changes: it is **not independent tamper-proof enforcement**. Maintainer review and configured merge rules remain separate requirements; zero-approval solo review does not establish independent approval. Fork workflow approval or Actions organization policies may require owner action before jobs run. + +Checks establish regression behavior and selected candidate eligibility under implemented policy, not container-release approval or SRE deployment authorization. The separate [manual smoke workflow](manual-smoke-workflow.md) records bounded integration evidence; it is not a required PR check. Image publication, promotion and legacy exceptions remain outside these checks. diff --git a/docs/roadmap.md b/docs/roadmap.md index 3f7732b..9cbdcfa 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -33,7 +33,7 @@ The platform must remain focused on image-release composition and validation. It - define the promotion and rollback semantics at a repository level; - define MVP non-goals and trust boundaries. -Artifacts: [architecture](architecture.md), [canonical contract](release-contract.md), [v1 schema](../schemas/release-v1.schema.json), and [non-deployable example](../examples/release-v1.example.json). Offline validation and opt-in registry metadata verification are implemented; PR validation workflows are available; owner-required checks and integrations remain separate work. +Artifacts: [architecture](architecture.md), [canonical contract](release-contract.md), [v1 schema](../schemas/release-v1.schema.json), and [non-deployable example](../examples/release-v1.example.json). Offline validation and opt-in registry metadata verification are implemented; PR checks and main protection are configured; bounded integration evidence is recorded separately, while release approval and SRE handoff remain separate decisions. ### Target outcome @@ -65,7 +65,7 @@ Baseline artifacts proposed for review: [discovery and limitations](baseline.md) **Goal:** Turn the release contract into deterministic policy checks. -The [offline CLI](offline-validation.md) implements strict JSON/schema checks, immutable local inventory evaluation and traceability eligibility with automated tests. [Opt-in Docker Hub metadata verification](registry-verification.md) adds bounded manifest/config integrity and platform checks. Milestone closure remains a separate owner decision; PR gates and integration validation remain future work. +The [offline CLI](offline-validation.md) implements strict JSON/schema checks, immutable local inventory evaluation and traceability eligibility with automated tests. [Opt-in Docker Hub metadata verification](registry-verification.md) adds bounded manifest/config integrity and platform checks. PR workflows and bounded integration evidence are now available; milestone closure remains a separate owner decision. ### Scope @@ -87,9 +87,9 @@ Invalid, incomplete, mutable, or unavailable releases cannot be presented as val **Goal:** Make release validation repeatable and prove that the published images compose into an application. -[Pull request checks](pull-request-validation.md) provide tests/package and new-candidate validation. [Offline Compose rendering](compose-rendering.md) provides deterministic configuration from digest-pinned candidates. An [opt-in bounded runtime runner](runtime-smoke.md) is available; its live result and limitations are recorded separately. Required-check settings are owner-configured; runner availability does not complete this milestone or prove baseline runtime compatibility. +[Pull request checks](pull-request-validation.md) provide tests/package and new-candidate validation. [Offline Compose rendering](compose-rendering.md) provides deterministic configuration from digest-pinned candidates. The [opt-in bounded runtime runner](runtime-smoke.md) has local and hosted evidence for a selected demo flow. [Main protection](main-protection.md) is confirmed active with the three required checks and owner-confirmed Required labels on PR #18. Pending-check blocking remains unobserved; neither green CI nor Draft blocking proves that behavior. -A [manual hosted workflow](manual-smoke-workflow.md) is prepared; hosted baseline acceptance remains pending workflow registration on the default branch and an actual owner dispatch. It adds no mandatory runtime PR check and does not close this milestone. +The [manual hosted workflow](manual-smoke-workflow.md) is registered; [run 40046455406](https://github.com/DimitryZH/container-platform/actions/runs/40046455406) passed all 12 exact-image services, readiness, five semantic assertions and verified cleanup. Inspection-only retained validation exit 1 and 12 legacy failures. Live cancellation recovery remains unverified. Runtime smoke is optional, and this evidence does not close the milestone or grant release approval. ### Scope