mirror of
https://github.com/sredevopsorg/deepseek-kubernetes-sandbox.git
synced 2026-11-03 01:13:24 +00:00
docs: align readmes, docs and agent guidance with current behavior (#37)
Remove obsolete layout/migration prose and legacy gateway-alias references, reconcile the required-check policy, fix version-label/RBAC/workspace/channel drift, and de-duplicate the example and gateway docs. Rename the minimal manifest to 10-sandboxtemplate.yaml and mount the dsh-home PVC's workspace subPath at /workspace so the documented persistence is real. Enforce numbered top-level manifests in check-examples.sh. Verified with make check, yamllint, shellcheck, a Markdown link/anchor scan, and git diff --check. Co-authored-by: SREDevOpsAgents <agents@sredevops.org>
This commit is contained in:
committed by
GitHub
parent
82ee0d0cdb
commit
24f23e09ae
@@ -2,8 +2,7 @@
|
||||
|
||||
Repository-wide documentation lives here. Example-specific material lives with
|
||||
its example under [`examples/<name>/docs/`](../examples/) — see the
|
||||
[agents-as-a-service architecture](../examples/dsh-agents-as-a-service/docs/architecture.md)
|
||||
for the deep-dive that used to live in this directory.
|
||||
[agents-as-a-service architecture](../examples/dsh-agents-as-a-service/docs/architecture.md).
|
||||
|
||||
If you are new, read the [root README](../README.md) first: it is image-first and
|
||||
gets a DSH Web container running before anything else.
|
||||
@@ -34,6 +33,8 @@ DSH discovers project skills from `<git root>/.dsh/skills/<name>/SKILL.md`
|
||||
| [dsh-agents-as-a-service README](../examples/dsh-agents-as-a-service/README.md) | The multi-tenant platform walkthrough: warm pool, claims, suspend/resume, gateway, exposure and troubleshooting. |
|
||||
| [dsh-agents-as-a-service architecture](../examples/dsh-agents-as-a-service/docs/architecture.md) | Container/sequence diagrams, ADRs, security and RBAC, failure modes and the evolution path. |
|
||||
| [gateway README](../examples/dsh-agents-as-a-service/gateway/README.md) | The gateway's HTTP/WebSocket API, configuration, auth (including SSO), and limitations. |
|
||||
| [optional hardening](../examples/dsh-agents-as-a-service/docs/optional-hardening.md) | Opt-in gVisor, nodeSelector, NetworkPolicy, provider keys and failed-Pod recovery. |
|
||||
| [exposure variants](../examples/dsh-agents-as-a-service/manifests/exposure/README.md) | The mutually exclusive Ingress and Gateway API + SSO exposure paths. |
|
||||
|
||||
## Project policies
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ examples/<name>/
|
||||
example directory;
|
||||
- an example has no `README.md` or no `manifests/` directory;
|
||||
- `manifests/` contains no top-level `*.yaml` files;
|
||||
- a top-level `manifests/*.yaml` is not named `NN-*.yaml`;
|
||||
- a `*.yaml` file sits at the example root instead of under `manifests/`;
|
||||
- `manifests/exposure/` exists without a `manifests/exposure/README.md` describing
|
||||
the variants;
|
||||
|
||||
@@ -30,7 +30,7 @@ branch; the PR is squash-merged, so individual branch commits are never part of
|
||||
`docs(scope): ...`, `build: ...`, `ci: ...`, `refactor: ...`, `test: ...`,
|
||||
`chore: ...`. Breaking changes use `feat(scope)!: ...` or a
|
||||
`BREAKING CHANGE:` footer.
|
||||
3. **CI must be green.** All required checks below must pass before merge.
|
||||
3. **CI must be green.** All applicable checks below must pass before merge.
|
||||
4. **Squash merge only.** `main` stays linear and protected; merged PRs are one
|
||||
commit each.
|
||||
5. **No direct pushes to `main`** or to a release branch. Both are protected.
|
||||
@@ -40,21 +40,20 @@ branch; the PR is squash-merged, so individual branch commits are never part of
|
||||
|
||||
## Required checks
|
||||
|
||||
| Check | Workflow / job | What it verifies |
|
||||
| --- | --- | --- |
|
||||
| `lint` | `ci.yaml` | `scripts/check-versions.sh` (version pins and markdown tokens), `scripts/check-examples.sh` (example layout), shellcheck, actionlint, yamllint, hadolint and documentation links. |
|
||||
| `python` | `ci-python.yaml` | Gateway ruff check/format and unit tests (`pytest` with coverage). Runs only when the gateway or this workflow changes. |
|
||||
| `manifests` | `ci-manifests.yaml` | `scripts/check-manifests.py` (manifest shape) and a server-side dry-run of every example manifest against the agent-sandbox CRDs. Runs only when manifests, check scripts or `versions.env` change. |
|
||||
| `pr-title` | `pr-title.yaml` | Conventional Commit PR title. |
|
||||
| `CodeQL` | `codeql.yml` | Static analysis for Python and GitHub Actions. |
|
||||
| `dependency-review` | `ci.yaml` | Dependency changes introduced by the PR (job `dependency-review`; runs on pull requests only). |
|
||||
| Check | Workflow / job | Required on every PR? | What it verifies |
|
||||
| --- | --- | --- | --- |
|
||||
| `lint` | `ci.yaml` | yes | `scripts/check-versions.sh` (version pins and markdown tokens), `scripts/check-examples.sh` (example layout and numbered manifests), shellcheck, actionlint, yamllint, hadolint and documentation links. |
|
||||
| `python` | `ci-python.yaml` | no (path-filtered) | Gateway ruff check/format and unit tests (`pytest` with coverage). Runs only when the gateway or this workflow changes. |
|
||||
| `manifests` | `ci-manifests.yaml` | no (path-filtered) | `scripts/check-manifests.py` (manifest shape) and a server-side dry-run of every example manifest against the agent-sandbox CRDs. Runs when manifest files, `scripts/check-manifests.py` or `versions.env` change. |
|
||||
| `pr-title` | `pr-title.yaml` | yes | Conventional Commit PR title. |
|
||||
| `Analyze (python)`, `Analyze (actions)` | `codeql.yml` | yes (both jobs) | CodeQL static analysis for Python and GitHub Actions. |
|
||||
| `dependency-review` | `ci.yaml` | yes | Dependency changes introduced by the PR (job `dependency-review`; runs on pull requests only). |
|
||||
|
||||
`python`, `manifests` and `build-amd64` use native `on.pull_request.paths`
|
||||
filtering, so PRs that do not touch the gateway, the manifests or the image
|
||||
definition skip them. The gateway image build and `/healthz` are no longer
|
||||
smoke-tested in a dedicated job: `/healthz` is covered by the gateway unit tests,
|
||||
the Dockerfile is linted by `lint` (hadolint), and the multi-arch image build is
|
||||
published by `build-gateway.yaml` on merge.
|
||||
definition skip them. The gateway image is built and published by
|
||||
`build-gateway.yaml` on merge; `/healthz` is covered by the gateway unit tests and
|
||||
the Dockerfile is linted by `lint` (hadolint).
|
||||
|
||||
`ci-image.yaml` (`build-amd64`) is the PR-side check for the main image: when
|
||||
`Dockerfile`, `.dockerignore` or `versions.env` change it builds `linux/amd64`
|
||||
@@ -64,9 +63,9 @@ the result (`--version`, non-root UID, `/workspace` + `DSH_HOME`, the
|
||||
container). The published multi-arch build still happens only in
|
||||
`build-main.yaml` on merge.
|
||||
|
||||
Because a skipped path-filtered check is not a passing check, only the always-on
|
||||
checks (`lint`, `pr-title`, `CodeQL`, `dependency-review`) should be enforced as
|
||||
required status checks; `python`, `manifests` and `build-amd64` are on-demand
|
||||
Because a skipped path-filtered check is not a passing check, require only the
|
||||
always-on set: `lint`, `pr-title`, both CodeQL `Analyze` jobs and
|
||||
`dependency-review`. Keep `python`, `manifests` and `build-amd64` as on-demand
|
||||
checks that skip when unrelated to the change.
|
||||
|
||||
The image build workflows (`_build-image.yaml`, `build-main.yaml`,
|
||||
@@ -109,7 +108,8 @@ Rollback is also a re-release, never a retag: see
|
||||
|
||||
## Tag protection
|
||||
|
||||
All release tags match `dsh-*` and are protected:
|
||||
Release tags follow `dsh-*` and are protected (the pre-scheme `v0.0.1` tag is
|
||||
historical and unmaintained):
|
||||
|
||||
- only maintainers (the release workflow) may create them;
|
||||
- they cannot be deleted or force-updated;
|
||||
@@ -123,11 +123,12 @@ respectively.
|
||||
|
||||
Configure these on the repository before relying on the workflow:
|
||||
|
||||
- [ ] **Branches → main**: require a pull request; require the checks `lint`,
|
||||
`python`, `manifests`, `pr-title`, `CodeQL`, `dependency-review`; require
|
||||
branches to be up to date; require conversation resolution; restrict direct
|
||||
pushes; allow only squash merges and enable "Automatically delete head
|
||||
branches".
|
||||
- [ ] **Branches → main**: require a pull request; require the always-on checks
|
||||
`lint`, `pr-title`, both CodeQL `Analyze` jobs and `dependency-review`
|
||||
(`python`, `manifests` and `build-amd64` are path-filtered and must not be
|
||||
required); require branches to be up to date; require conversation
|
||||
resolution; restrict direct pushes; allow only squash merges and enable
|
||||
"Automatically delete head branches".
|
||||
- [ ] **Branches → release/***: same protections, plus allow the release workflow
|
||||
to push tags.
|
||||
- [ ] **Tags → dsh-***: restrict creation/update/deletion to maintainers; a tag
|
||||
|
||||
@@ -47,8 +47,8 @@ docker build \
|
||||
| Arg | Default / source | Purpose |
|
||||
| --- | --- | --- |
|
||||
| `DSH_REPO` | `https://github.com/deepseek-ai/deepseek-harness.git` | Upstream DSH repository to clone. |
|
||||
| `DSH_VERSION` | `DSH_VERSION` in [versions.env](../versions.env) | Upstream DSH git tag/ref to package; recorded as `org.opencontainers.image.version`. |
|
||||
| `RELEASE_REVISION` | `RELEASE_REVISION` in [versions.env](../versions.env) | Repository revision suffix (`rN`); the release identity is `DSH_VERSION-RELEASE_REVISION`, recorded in the `io.sredevopsorg.release.revision` label. See [versioning](versioning.md). |
|
||||
| `DSH_VERSION` | `DSH_VERSION` in [versions.env](../versions.env) | Upstream DSH git tag/ref to package. The Dockerfile records it as `io.sredevopsorg.dsh.version` and (for local builds) `org.opencontainers.image.version`; published builds set the version label to the full release identity. |
|
||||
| `RELEASE_REVISION` | `RELEASE_REVISION` in [versions.env](../versions.env) | Repository revision suffix (`rN`), recorded in `io.sredevopsorg.release.revision`. The release identity is `DSH_VERSION` plus `-RELEASE_REVISION` when set. See [versioning](versioning.md). |
|
||||
| `PNPM_VERSION` | `PNPM_VERSION` in [versions.env](../versions.env) | pnpm version activated with corepack in both stages. |
|
||||
| `VCS_REF` | `git rev-parse --short HEAD` (via `make image`) | Source revision recorded for traceability. |
|
||||
| `NODE_BUILD_IMAGE` | `docker.io/node:24-trixie` | Build-stage base image. |
|
||||
@@ -90,9 +90,10 @@ includes `/app/node_modules/.bin`.
|
||||
the picker's browse backend lists `$HOME` when the dialog opens and labels that
|
||||
listing *Home*. With the image default (`/home/node`) that listing is outside a
|
||||
mounted volume; the example sandbox templates
|
||||
([minimal](../examples/minimal-single-tenant/manifests/sandbox-template.yaml),
|
||||
([minimal](../examples/minimal-single-tenant/manifests/10-sandboxtemplate.yaml),
|
||||
[agents as a service](../examples/dsh-agents-as-a-service/manifests/10-sandboxtemplate.yaml))
|
||||
set `HOME=/workspace` so the picker opens on the persisted agent workspace. `~`
|
||||
mount the same PVC's `workspace` subPath at `/workspace` and set `HOME=/workspace`
|
||||
so the picker opens on the persisted agent workspace. `~`
|
||||
and every tool that keeps caches or config under `$HOME` (`npm`/`pnpm`, `uv`,
|
||||
`git`, `gh`, DSH's global `~/.agents` instructions and skills) follow, so those
|
||||
dotfiles then live on the workspace volume too. `DSH_HOME` is separate and stays
|
||||
@@ -141,7 +142,7 @@ procedure.
|
||||
| --- | --- | --- |
|
||||
| Exposed port | `3080/tcp` | `EXPOSE 3080`; one port serves the UI, assets, API, SSE and WebSocket traffic. |
|
||||
| State volume | `/home/node/.dsh` | Declared with `VOLUME`; use a named volume (Docker) or PVC (Kubernetes). |
|
||||
| Working directory | `/workspace` | The agent workspace. Mount a volume here if agents should keep files; the agents-as-a-service example mounts the same PVC's `workspace` subPath here and points `HOME` at it, so DSH's folder picker opens on it. |
|
||||
| Working directory | `/workspace` | The agent workspace. Mount a volume here if agents should keep files; the shipped example templates mount the same PVC's `workspace` subPath here and point `HOME` at it, so DSH's folder picker opens on it. |
|
||||
| Stop signal | `SIGTERM` | `tini` forwards it to `dsh web`; allow a graceful shutdown period. |
|
||||
| User | `node`, UID/GID `1000` | The process is non-root. A PVC mounted at `DSH_HOME` must be writable by UID 1000. |
|
||||
|
||||
@@ -164,8 +165,8 @@ livenessProbe:
|
||||
periodSeconds: 15
|
||||
```
|
||||
|
||||
The shipped templates use exactly this shape; see
|
||||
[`examples/minimal-single-tenant/manifests/sandbox-template.yaml`](../examples/minimal-single-tenant/manifests/sandbox-template.yaml).
|
||||
The shipped templates use the same path and startup budget; see
|
||||
[`examples/minimal-single-tenant/manifests/10-sandboxtemplate.yaml`](../examples/minimal-single-tenant/manifests/10-sandboxtemplate.yaml).
|
||||
A `startupProbe` is important because plugin activation (or the first start of a
|
||||
large sandbox) can exceed a default liveness budget.
|
||||
|
||||
@@ -199,10 +200,7 @@ GitHub Container Registry:
|
||||
| --- | --- |
|
||||
| `dsh-v0.2.1-rc.5` | Current release identity. **Immutable**: once published it never moves. |
|
||||
| `latest` | Most recent release; points at the same digest as the current identity. |
|
||||
| `main` | Development channel rebuilt from every push to `main`; not a release, not for production. |
|
||||
|
||||
Tags published before the release-identity scheme remain published but are not
|
||||
updated; new deployments use the current identity.
|
||||
| `main` | Development channel rebuilt when image-definition files change on `main`; not a release, not for production. |
|
||||
|
||||
Release identities, channels and rollback rules are defined in
|
||||
[versioning](versioning.md). Tags are immutable, so production deployments should
|
||||
@@ -220,6 +218,7 @@ docker buildx imagetools inspect ghcr.io/sredevopsorg/deepseek-kubernetes-sandbo
|
||||
docker inspect ghcr.io/sredevopsorg/deepseek-kubernetes-sandbox:dsh-v0.2.1-rc.5 \
|
||||
--format '{{json .Config.Labels}}'
|
||||
# org.opencontainers.image.title / .version / .source
|
||||
# io.sredevopsorg.dsh.version / io.sredevopsorg.release.revision
|
||||
```
|
||||
|
||||
Release builds also publish SBOM and provenance attestations from the release
|
||||
|
||||
@@ -15,7 +15,7 @@ release identity = DSH_VERSION + optional "-" + RELEASE_REVISION
|
||||
|
||||
| Piece | Meaning |
|
||||
| --- | --- |
|
||||
| `DSH_VERSION` | The upstream DeepSeek Harness git ref being packaged, e.g. `dsh-v0.2.1-rc.5`. It mirrors upstream's own tag, which is what "mirrored-DSH scheme" means. |
|
||||
| `DSH_VERSION` | The upstream DeepSeek Harness git ref being packaged, e.g. `dsh-v0.2.1-rc.5`. It mirrors upstream's own tag. |
|
||||
| `RELEASE_REVISION` | An optional repository revision at that DSH ref: empty for the first release, `rN` (`N >= 2`) for a repository-only re-release. |
|
||||
|
||||
Examples:
|
||||
@@ -33,23 +33,14 @@ with an empty revision); a repository-only change at the same DSH ref increments
|
||||
## Why release identities are immutable
|
||||
|
||||
**Container tags are immutable** in this project: re-pushing a tag would silently
|
||||
change what an existing deployment runs. A DSH upgrade therefore produces a new
|
||||
base identity with an empty revision; a repository-only change at an
|
||||
already-released ref publishes `-rN`, where `r2` is the first re-release (the
|
||||
plain tag is conceptually revision 1 and is taken).
|
||||
change what an existing deployment runs. A fix therefore publishes a new identity;
|
||||
see the rules above.
|
||||
|
||||
The current identity is `dsh-v0.2.1-rc.5`, the first release at this upstream
|
||||
ref, so it carries no revision suffix. The identity is stored in
|
||||
[versions.env](../versions.env) and consumed everywhere: the Dockerfile label,
|
||||
the example manifests, the Makefile and the release workflow. Tags published
|
||||
before the release-identity scheme remain published but are not updated; new
|
||||
deployments use the current identity.
|
||||
|
||||
The gateway image moved from the repository-level `:gateway` tag to a nested
|
||||
package (`<repository>/dsh-agents-as-a-service/gateway`). The release workflow
|
||||
also republishes the legacy `<repository>:gateway` tag as a deprecated
|
||||
compatibility alias; it may be removed in a later release, so deployments
|
||||
should pin the nested package.
|
||||
[versions.env](../versions.env) and consumed everywhere: the Dockerfile labels
|
||||
(version and revision), the example manifests, the Makefile and the release
|
||||
workflow.
|
||||
|
||||
## Channels
|
||||
|
||||
@@ -57,7 +48,7 @@ should pin the nested package.
|
||||
| --- | --- | --- |
|
||||
| Release | `dsh-v0.2.1-rc.5` | The current immutable release identity. What production should pin (preferably by digest). |
|
||||
| `latest` | `latest` | Alias for the most recent release; moves only when a new release is published. |
|
||||
| `main` | `main` | Development channel, rebuilt from every push to `main`. Never treat it as a release; it exists so `main` can be tested. |
|
||||
| `main` | `main` | Development channel, rebuilt when image or gateway sources change on `main`. Never treat it as a release; it exists so `main` can be tested. |
|
||||
|
||||
The same channels exist for every published package, including the nested
|
||||
example component image.
|
||||
@@ -110,11 +101,12 @@ workflows with a literal version.
|
||||
matches [versions.env](../versions.env).
|
||||
6. The workflow builds and pushes multi-arch images for the main image and the
|
||||
example components (the identity tag plus `latest`), creates the GitHub
|
||||
Release from the git-cliff notes, records the published digests, and opens a
|
||||
`chore(changelog)` PR that refreshes `CHANGELOG.md` on `main`.
|
||||
Release from the git-cliff notes, and opens a `chore(changelog)` PR that
|
||||
refreshes `CHANGELOG.md` on `main`. The publish log shows each image manifest
|
||||
and digest.
|
||||
7. Merge the changelog PR. Verify:
|
||||
`docker buildx imagetools inspect <image>:<identity>` shows both platforms,
|
||||
and the GitHub Release references the tag and the digest.
|
||||
`docker buildx imagetools inspect <image>:<identity>` shows both platforms;
|
||||
the GitHub Release references the tag, and the workflow log shows the digest.
|
||||
8. Announce the identity and the digest; deployments pin the digest.
|
||||
|
||||
## Rollback
|
||||
|
||||
Reference in New Issue
Block a user