Files
devplacepy/quality_versioning.md
T
retoorandClaude Sonnet 5.5 f55c7ee5f4
DevPlace CI / test (push) Failing after 31m42s
Add community node protocol spec, Agent Skills, and make the failing tests hermetic
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>
2026-10-14 07:13:25 +02:00

8.0 KiB

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.