DevPlace CI / test (push) Failing after 31m42s
Community nodes (Phase 1 of plan.md): the protocol specification in services/nodes/spec.py as the single source of truth, GET /nodes/spec.json, a generated protocol docs page, the Community nodes API docs group, and the implementation plan plus the residential proxy research. The no-open-proxy rule is enforced in the spec (open_proxy cannot be set). Agent Skills: register the Skills API docs group, cascade skills on account deletion, add the nested CLAUDE.md, README and routes docs, and cover the parser, the fetcher (end to end against a mock origin), the data layer and the routes with 73 unit and 16 api tests. Tests made hermetic with the repo's existing patterns instead of ambient environment: embeddings tests set OPENROUTER_API_KEY via monkeypatch, the workspace tests install FakeBackend via runtime.set_backend, and the skills install tests use run_async. DockerCliBackend now returns 127 (command not found) when the CLI is missing instead of raising FileNotFoundError, so a host without docker answers with a clean error rather than a 500. The Providers tab empty state no longer names the Model routes tab. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
166 lines
8.0 KiB
Markdown
166 lines
8.0 KiB
Markdown
<!-- doc: quality_versioning.md | version: 1.0.0 | updated: 2026-10-11 -->
|
|
# Quality Versioning Playbook: App, Assets, Docs, and Git
|
|
|
|
Generic companion to `quality_software.md`. It covers how DevPlace
|
|
versions its application, its static assets, and its git history,
|
|
plus the one practice DevPlace does NOT have today and you should
|
|
adopt from day one: versioned markdown docs.
|
|
|
|
Honest baseline (researched 2026-10-11, do not assume otherwise):
|
|
|
|
- App version: single source `pyproject.toml`, auto-bumped patch on
|
|
every commit by a checked-in pre-commit hook. Real and working.
|
|
- Asset version: composed `{APP_VERSION}-{BOOT_ID}`, stamped into
|
|
every static URL, served immutable. Real and working.
|
|
- Git: trunk `master`, remote `production` branch, per-ticket
|
|
branches, CI gate on push/PR to master. Real and working.
|
|
- Tags: none. Changelog file: none. Markdown versioning: none.
|
|
These are gaps, and sections 4 and 6 below define what to do
|
|
instead of copying the gap.
|
|
|
|
## 1. App versioning: one source, auto-bumped
|
|
|
|
- One file owns the version (DevPlace: `pyproject.toml`
|
|
`project.version`, currently `1.0.x`). The running app reads it
|
|
live at boot (DevPlace: `config.APP_VERSION` via `tomllib`), so
|
|
the version in code and the version on disk can never drift.
|
|
- A checked-in pre-commit hook bumps the patch number on every
|
|
commit (DevPlace: `.githooks/pre-commit`, activated by
|
|
`git config core.hooksPath .githooks` in the install target).
|
|
Skips merge commits and commits that already touch the version
|
|
line, so a manual minor/major bump is never double-bumped.
|
|
- Semver discipline: patch is automatic (every commit), minor is a
|
|
manual commit when a user-visible feature lands, major is a
|
|
manual commit on breaking change. Minor/major bumps are ordinary
|
|
commits whose message says what the release contains.
|
|
- The version is visible at runtime: stamped into a meta tag
|
|
(DevPlace: `<meta name="asset-version">` in `base.html`) so any
|
|
page view, bug report, or screenshot names the exact build.
|
|
|
|
Hosting example: the control panel footer and every support ticket
|
|
show `v2.14.3`; support never asks "which version are you on".
|
|
|
|
## 2. Asset versioning: cache forever, deploy instantly
|
|
|
|
- Compose the asset version from app version plus boot id:
|
|
`STATIC_VERSION = {APP_VERSION}-{BOOT_ID}` where the boot id is a
|
|
deploy-provided marker with a wall-clock fallback.
|
|
- Stamp it into every app-owned static URL
|
|
(`/static/v<version>/...`) through one URL helper, and serve that
|
|
path immutable with a one-year `max-age`.
|
|
- Keep the reverse proxy in sync: the versioned-path location regex
|
|
must accept dots and hyphens, not digits only, or the immutable
|
|
header silently stops applying (this was a real production bug
|
|
class here, fixed once the version segment stopped being a bare
|
|
timestamp).
|
|
- Never hardcode a static path; every template and script builds
|
|
URLs through the one helper, so a version-shape change touches
|
|
one function.
|
|
|
|
## 3. Git workflow: trunk, tickets, production
|
|
|
|
- Trunk is `master`. All work lands there through small commits;
|
|
CI (serial full suite, coverage, failure screenshots) runs on
|
|
every push and PR to master and must be green before merge.
|
|
- One branch per ticket or task, named after the tracker
|
|
(`ticket-123`, `112-short-slug`). Short-lived: branch, commit,
|
|
merge, delete. No long-running feature branches.
|
|
- One `production` branch (or tag set, see section 6) marks what is
|
|
deployed. Development happens on master; promotion to production
|
|
is a deliberate merge, followed by deploy and live verification.
|
|
- Commit messages: imperative summary line under 72 chars, blank
|
|
line, body explaining why (not what, the diff shows what).
|
|
Optional trailers for attribution (`Co-Authored-By`) and session
|
|
links. Reverts say what behavior returned and why.
|
|
- Never rewrite published history: no amend/push-force, no rebase
|
|
of shared branches, no `reset --hard` on anything pushed. Fix the
|
|
working tree forward; a mistaken commit is corrected by a new
|
|
commit.
|
|
- Hooks live in the repo (`.githooks/`) and are wired by the
|
|
install target, so every clone gets the version bump and any
|
|
future checks with zero manual setup.
|
|
|
|
## 4. Markdown versioning: every doc carries its version
|
|
|
|
This is the rule DevPlace does not follow yet: **every markdown
|
|
file is versioned on every update.** Adopt it from the start; it
|
|
costs one line per edit and buys traceability for every claim a
|
|
doc makes.
|
|
|
|
Scheme (copy literally):
|
|
|
|
1. First line of the file is an invisible HTML comment:
|
|
`<!-- doc: <filename> | version: X.Y.Z | updated: YYYY-MM-DD -->`
|
|
It renders nothing and survives every markdown renderer.
|
|
2. Bottom of the file is a `Doc history` table with one row per
|
|
version: version, date, one-line change note.
|
|
3. Doc-semver: MAJOR for restructure or section renumbering, MINOR
|
|
for a new section or new rule, PATCH for wording, fixes, or
|
|
example updates. Every update bumps exactly one level and adds
|
|
exactly one history row.
|
|
4. The version bump and the content change ship in the same commit,
|
|
so `git log -p <doc>` and the history table always agree.
|
|
5. Cross-doc references name the section, not the version ("see
|
|
`quality_software.md` section 9"), so minor doc bumps never
|
|
cascade into other files.
|
|
|
|
Enforcement options, cheapest first: a pre-commit check that fails
|
|
when a staged `.md` lacks a matching version-line change (same
|
|
pattern as the app-version hook, inverted: docs must be touched by
|
|
hand, so the hook only verifies); a CI grep that every tracked
|
|
`.md` starts with the `doc:` comment; a unit test listing tracked
|
|
markdown files and asserting the header parses.
|
|
|
|
Hosting example: `docs/sla.md` at `3.1.0` and `docs/pricing.md` at
|
|
`5.0.2` evolve independently; a customer dispute cites "SLA v3.1",
|
|
not "the docs, at some point".
|
|
|
|
## 5. What gets a version vs what gets a timestamp
|
|
|
|
- Versioned (semver, comparable, citable): the app, each markdown
|
|
doc, API contracts, terms/SLA/pricing pages, database export
|
|
formats, agent tool catalogs.
|
|
- Timestamped (point-in-time, never compared): deploys (boot id),
|
|
backups, audit events, usage ledger rows, generated reports.
|
|
- Never versioned alone: a bare counter with no history row, a date
|
|
with no change note. A version you cannot diff is decoration.
|
|
|
|
## 6. Releases and tags: close the gap deliberately
|
|
|
|
DevPlace has no tags and no changelog file; promotion is tracked by
|
|
the `production` branch. For a hosting company, where customers and
|
|
auditors ask "what changed and when", close this gap:
|
|
|
|
- Tag every production promotion with an annotated tag
|
|
(`v2.14.0`, message = release notes summary). Tags are cheap,
|
|
immutable pointers; the branch can move, the tag cannot.
|
|
- Keep one `CHANGELOG.md` (itself doc-versioned per section 4)
|
|
with one entry per minor/major release: date, tag, added,
|
|
changed, fixed, security notes. Patch releases batch into the
|
|
next minor entry; no per-commit changelog spam.
|
|
- Release flow in order: land feature commits on master (CI green),
|
|
manual minor/major bump commit, merge master into production,
|
|
tag, deploy, verify live, write the changelog entry. A release
|
|
that is not verified live is not released.
|
|
|
|
## 7. Replication checklist for your hosting site
|
|
|
|
1. Single version source read live by the app; pre-commit hook
|
|
auto-bumps patch; minor/major are manual release commits.
|
|
2. Asset URLs carry `{version}-{boot-id}`, served immutable;
|
|
proxy regex accepts the full version alphabet.
|
|
3. Trunk `master`, ticket branches, `production` promotion target,
|
|
CI gate on master, no history rewrites, hooks in-repo.
|
|
4. Every `.md` starts with the `doc:` version comment and ends with
|
|
a history table; every update bumps; CI verifies the header.
|
|
5. Terms, SLA, pricing, and API contracts are versioned docs with
|
|
citable versions, not wiki pages.
|
|
6. Annotated tags plus one changelog for customer-facing releases;
|
|
release = merge, tag, deploy, verify live, changelog entry.
|
|
|
|
## Doc history
|
|
|
|
| Version | Date | Change |
|
|
|---------|------|--------|
|
|
| 1.0.0 | 2026-10-11 | Created from repo research: app auto-bump hook, asset composition, trunk/ticket/production git model, new markdown-versioning scheme. |
|