Skip to content

docs(specs): per-feature design specs covering every source file #97

Closed

Description

@entelecheia

Context

The project uses agent-hub design specs: Markdown files with id, type and paths frontmatter; the hub names the covering spec when a task touches those paths, and AGENTS.md requires updating the owning spec with a change to a contract it states.

  • verified 2026-11-09: the three files in docs/specs/ have no frontmatter, so no code is covered. Only fleet/monitoring and tenant have any design record.
  • verified: the tenant spec contradicts itself (sshpiper listed out of scope, then shipped in feat(tenant): one SSH port for all tenants through sshpiper #80/feat(tenant): one SSH port for all tenants through sshpiper (#80) #81; sync "daily" vs every 2 minutes since v0.17.0); the fleet spec still reads "approved for implementation" and lacks --skip-unreachable, apply-pending, Prometheus reload, doctor disk thresholds and the exporter firewall guard.
  • docs/specs/2026-10-03-rollout-verification.md is a one-off deployment checklist.

Implementation starts only on the owner's go-ahead.

Decisions

  • Specs describe current behaviour (living documents), one per feature, at docs/specs/<id>.md. Dated design files are folded into them; history stays in git and the linked issues.

  • Every non-test Go file, scripts/*, .goreleaser.yaml and the workflows are covered by exactly one spec. Shared files belong to the spec that owns their contract.

  • Allowed types: goal (one), architecture (one), module, submodule; non-goal specs set parent.

  • verified-against is stamped by a person (ahub specs stamp), never by an agent.

  • 2026-11-09: partition table amended to what ahub accepts: status: active; host-base, ssh-access, security, users, docker-nvidia, gpu-allocation, cloudflared, monitoring-exporters and doctor-schedule use parent: architecture with depends-on: [engine] (a module cannot be the child of a module); paths are listed per file. Basis: ahub specs check in PR docs(specs): per-feature design specs covering every source file #107.

Design

Each spec: frontmatter (id, type, title, status, parent, paths) then Purpose → Contracts and invariants → Behaviour (Check/Apply, CLI) → Distro support → Safety → Tests that pin it → Open decisions.

id type parent paths
rootfiles goal - (none) scope, users, non-goals
architecture architecture rootfiles cmd/rootfiles/main.go, internal/ui/**
cli-runtime module architecture internal/cli/{root,runtime,output,provenance,native_system}.go
engine module architecture internal/module/{module,preflight,package_commands}.go, internal/cli/{apply,check,status}.go
config module architecture internal/config/{config,loader,validate,fingerprint,snapshot,detector}.go, internal/config/profiles/**, internal/cli/configcmd.go
distro-rocky module architecture internal/config/distro.go, internal/module/{ssh_rocky,security_rocky}.go, internal/exec/rpm.go
exec-packages module architecture internal/exec/{runner,apt,package_manager}.go, internal/module/packages.go
state-rollback module architecture internal/state/**, internal/exec/backup.go, internal/cli/{rollback,backup}.go
host-base module engine internal/module/{locale,system,storage}.go
ssh-access module engine internal/module/{ssh,access,network}.go
security module engine internal/module/security.go
users module engine internal/module/{users,accounts,lifecycle,quota}.go, internal/cli/{user,userlife}.go
docker-nvidia module engine internal/module/{docker,daemonjson,nvidia}.go
gpu-allocation module engine internal/module/{gpu,mig}.go, internal/cli/gpu.go
cloudflared module engine internal/module/cloudflared.go, internal/cli/tunnel.go
monitoring-exporters module engine internal/module/{monitoring,monitoring_exporters,monitoring_firewall,monitoring_guard}.go, internal/module/assets/**, internal/config/{monitoring,monitoring_validate}.go
monitoring-hub submodule monitoring-exporters internal/module/monitoring_hub.go, internal/config/monitoring_discovery.go
doctor-schedule module engine internal/module/doctor.go, internal/cli/{doctor,schedule}.go
self-update module architecture internal/cli/upgrade.go, scripts/*, .goreleaser.yaml, .github/workflows/**
fleet module architecture internal/fleet/**, internal/cli/fleet.go, internal/module/fleet_sudo.go
tenant module architecture internal/tenant/**, internal/module/{tenant,tenant_piper}.go, internal/cli/tenant.go

Changes

  • New docs/specs/<id>.md for every row; git mv the tenant and fleet design files to tenant.md / fleet.md and update them; monitoring parts of the fleet spec move to monitoring-exporters / monitoring-hub; delete 2026-10-03-rollout-verification.md after folding its verification table into fleet and distro-rocky.
  • Update links (README, docs/tenant.md, AGENTS.md architecture line).
  • AGENTS.md: one line pointing to docs/specs/ as the owner of contracts.

Acceptance criteria

  • AC1: ahub specs check exits 0 (no errors; warnings listed in the PR).
  • AC2: ahub specs covers <file> names exactly one spec for every non-test Go file, scripts/*, .goreleaser.yaml and .github/workflows/* (script over git ls-files, output in the PR).
  • AC3: the tenant and fleet contradictions listed in Context are resolved.
  • AC4: every spec states the open items from the 2026-11-09 audit issues that touch its paths, linking the issue.

Tasks

  • T1: goal + architecture specs, partition table final (AC1)
  • T2: module specs for engine, config, cli-runtime, state, exec, distro
  • T3: module specs for host-base, ssh-access, security, users, docker-nvidia, gpu, cloudflared, monitoring, doctor, self-update
  • T4: convert fleet and tenant, retire the rollout checklist (AC3)
  • T5: coverage script and audit links (AC2, AC4)

Out of scope

  • Stamping verified-against (the owner does it after review).

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions