1 - Architecture diagram

1.1 - architecture-diagram Specification

Describe the maintained architecture diagram owned by users/simeonwarren/host_bot. The diagram replaced the T3code page of the former central Drawio document. Infrastructure diagrams now live with their owning projects, with ownerless archived diagrams under infra/archive. The diagram describes checked-in configuration; it is not a live inventory or health check.

The project SHALL keep its architecture diagram as Mermaid source at t3code-architecture.mmd and SHALL render it through the repository’s mermaid_svg rule at //users/simeonwarren/host_bot:rendered. The project SHALL NOT commit a rendered SVG: //users/simeonwarren/host_bot:docs_assets SHALL take its srcs from :rendered so the documentation site publishes the build output, and the README SHALL reference that published path. The diagram SHALL use the shared //tools/mermaid:theme.json appearance rather than a package-local copy.

  • WHEN the documentation site is built
  • THEN :docs_assets packages the SVG produced by :rendered
  • AND the README image reference resolves to that packaged file
  • AND no rendered SVG is tracked in the source tree
  • WHEN the render action produces the SVG
  • THEN it uses the repository’s pinned Mermaid, headless Chrome, and font inputs
  • AND it loads no stylesheet, script, or font from a CDN
  • AND the document embeds the pinned handwriting face, so a viewer that loads no webfont still lays the labels out at their measured widths

The diagram SHALL group the remote actor and the shared Ingress in an Internet cluster, and SHALL show the remote actor reaching Ingress over HTTPS with mTLS. It SHALL nest the host-bot cluster inside the local infrastructure cluster, so the local actor, Vault, and the host’s services sit inside dc1.alwaldend.com rather than beside it, and the two nested cluster titles SHALL carry the dc1.alwaldend.com and host-bot.simeonwarren.users.alwaldend.com names respectively. It SHALL group Traefik, T3 Code, and Codex in the host-bot cluster, SHALL show the local actor reaching Traefik directly over HTTPS, Ingress forwarding to Traefik over Wireguard, and Traefik obtaining ACME certificates from Vault. It SHALL show T3 Code reaching GitHub for source and Codex reaching OpenAI and OpenRouter for inference, with those providers in a second Internet cluster because they are off-host. Both actors SHALL be labelled Actor. External service nodes SHALL carry their own hostnames.

Sources: diagram source and project documentation.

  • WHEN a reader opens the architecture section of the project README
  • THEN it displays the maintained diagram showing the ingress path, the in-host services, and the two external service dependencies

The diagram SHALL keep node labels short by naming each host once, in the cluster title that owns it, and SHALL NOT restate a hostname in both a cluster title and the nodes it contains. Node labels SHALL NOT wrap mid-token. The diagram SHALL keep subgraph titles clear of node outlines and edges: Mermaid centers a cluster title on the cluster’s top border, so a title that wraps extends into the cluster’s node area. The diagram source SHALL describe topology only and SHALL let the shared theme own appearance and spacing; a per-diagram directive is warranted only for a specific geometry need the theme cannot express.

Actors SHALL render as an ordinary rounded node carrying the shared theme’s hand-drawn stick figure beside the label, rather than as a bare glyph, a pill outline, or a Mermaid person shape. Mermaid’s person shape draws the head over the body box, so it is not used.

Sources: diagram source and theme.

  • WHEN the renderer draws the diagram
  • THEN every node outline is clear of headings, edges, and other nodes
  • AND no label is truncated or broken inside a hostname

Diagram appearance SHALL come from //tools/mermaid:theme.json rather than package-local copies or per-diagram appearance overrides, so node rounding and edge-label plates are consistent across every rendered diagram. The theme SHALL keep shapes semantic, so a rounded bracket node renders rounded while a square bracket node stays square; rounding SHALL NOT be forced on every node. The theme SHALL box edge labels by styling the label text, because Mermaid emits an empty label plate for unlabelled edges and styling that plate directly would draw a stray box.

Source: theme.

  • WHEN any diagram renders through mermaid_svg or the mmdc target
  • THEN a rounded node renders rounded and a square node stays square
  • AND its edge labels use bordered plates
  • WHEN the renderer draws an edge that carries a label
  • THEN the label renders on a bordered plate rather than directly on the edge line
  • AND an edge without a label draws no plate

2 - Bazel resource scheduling

2.1 - bazel-resource-scheduling Specification

Reduce resource contention from independent Bazel builds on host-bot through conservative per-invocation scheduling defaults.

The managed user Bazel configuration SHALL set four concurrent jobs and a local CPU scheduling budget of HOST_CPUS*0.25 for builds and tests. These defaults SHALL NOT be described as an aggregate host-wide resource cap.

  • WHEN a new Bazel build or test invocation loads the managed user configuration without overriding its resource settings
  • THEN it receives --jobs=4 and --local_resources=cpu=HOST_CPUS*0.25
  • WHEN separate Bazel servers build in multiple workspaces
  • THEN each receives its own scheduling budget, without sharing an aggregate limit

3 - Openspec cli

3.1 - openspec-cli Specification

Keep Host Bot’s user-facing OpenSpec CLI installation reproducible through its checked-in Ansible deployment.

Host Bot’s Ansible deployment SHALL install @fission-ai/openspec at an exact inventory-configured version under the managed user’s ~/.local prefix, with Node.js and npm provisioned through the existing host package backend. Repeated deployment with the same version SHALL preserve the installed version.

  • WHEN the Host Bot deployment runs with OpenSpec absent
  • THEN it installs the configured version and exposes ~/.local/bin/openspec to the managed user
  • WHEN the configured OpenSpec version is already installed
  • THEN the npm task leaves the package unchanged

4 - Owned dns

4.1 - owned-dns Specification

Define Host Bot DNS management through the owner’s tf root, including canonical declarations, scoped credentials, and offline source checks before adopting live records.

The tf root SHALL consume this owner’s canonical dnsconfig.json through the shared DNS Terraform module, preserving declared record identities and views. DNS resources SHALL default to disabled until the shared migration adopts them and SHALL retain enabled ownership after authorized adoption into the owner’s state. Reconciliation of adopted records with unchanged declarations SHALL propose no record additions, changes, replacements, or deletions.

  • WHEN the checked-in root is evaluated with default inputs before authorized adoption
  • THEN it reads this owner’s declaration and disables managed DNS records
  • AND the package contains the module and declaration inputs
  • WHEN the adopted host root is evaluated with its checked-in source defaults
  • THEN record ownership is enabled for the owner’s declared records and views
  • AND the package retains the canonical declaration and shared module inputs
  • WHEN the host root plans against its adopted state and unchanged declarations
  • THEN it proposes no record additions, changes, replacements, or deletions
  • AND records outside this owner’s declarations remain unchanged

The DNS wrapper SHALL select src_users_simeonwarren_host_bot through the repository AL flow and keep secret values in injected variables. DNS injection SHALL select the root’s existing Terraform stage label. Real DNS credentials and Vault policy grants SHALL be prerequisites for operational Terraform calls. RouterOS DNS credentials SHALL be isolated from unrelated RouterOS resources. The package SHALL expose a format test that does not authenticate to Vault or contact DNS providers.

  • WHEN the package format test executes
  • THEN it checks the packaged Terraform configuration without live credentials
  • AND existing non-DNS authentication and backend paths remain unchanged
  • WHEN the wrapper selects its Terraform stage labels
  • THEN it selects DNS credential injection through the owner AppRole
  • AND disabled DNS resources do not imply offline provider configuration

5 - Power profile

5.1 - power-profile Specification

Keep the host’s selected power profile reproducible through its owning Ansible configuration while retaining an explicit desired profile.

The host’s Ansible configuration SHALL declare balanced as its desired Tuned profile. Deployment SHALL enable and start the existing Tuned service and persist the declared profile with manual selection. Deployment SHALL avoid reselecting an already-correct profile in manual mode and SHALL report unexpected profile-query failures.

  • WHEN the active profile differs from the declared profile
  • THEN deployment selects and persists the declared profile
  • WHEN the active profile matches but selection is automatic
  • THEN deployment persists the declared profile with manual selection
  • WHEN Tuned reports that no profile is active
  • THEN deployment selects the declared profile instead of failing on that expected query result
  • WHEN the active profile matches and selection is manual
  • THEN deployment does not repeat the profile-selection command
  • WHEN querying the active profile or selection mode fails unexpectedly
  • THEN deployment reports the failure instead of concealing it