Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand All @@ -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.

Expand Down Expand Up @@ -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

Expand All @@ -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.
59 changes: 59 additions & 0 deletions docs/main-protection.md
Original file line number Diff line number Diff line change
@@ -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.
41 changes: 26 additions & 15 deletions docs/manual-smoke-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Loading