This is the multi-page printable view of this section. Click here to print.
OpenSpec
- 1: Specifications
- 1.1: Architecture diagram
- 1.2: Bazel resource scheduling
- 1.3: Openspec cli
- 1.3.1: openspec-cli Specification
- 1.4: Owned dns
- 1.4.1: owned-dns Specification
- 1.5: Power profile
- 1.5.1: power-profile Specification
1 - Specifications
1.1 - Architecture diagram
1.1.1 - architecture-diagram Specification
Purpose
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.
Requirements
Requirement: Owner-local Mermaid diagram source
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.
Scenario: Publish the diagram
- WHEN the documentation site is built
- THEN
:docs_assetspackages 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
Scenario: Render without host or network inputs
- 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
Requirement: Diagram content reflects the deployed topology
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.
Scenario: Consult the host-bot architecture
- 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
Requirement: Legible diagram layout
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.
Scenario: Render the maintained layout
- 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
Requirement: Appearance is owned by the shared theme
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.
Scenario: Render another diagram with the theme
- WHEN any diagram renders through
mermaid_svgor themmdctarget - THEN a rounded node renders rounded and a square node stays square
- AND its edge labels use bordered plates
Scenario: Read an edge annotation
- 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
1.2 - Bazel resource scheduling
1.2.1 - bazel-resource-scheduling Specification
Purpose
Reduce resource contention from independent Bazel builds on host-bot through conservative per-invocation scheduling defaults.
Requirements
Requirement: Reduced 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.
Scenario: Build or test reads the managed defaults
- WHEN a new Bazel build or test invocation loads the managed user configuration without overriding its resource settings
- THEN it receives
--jobs=4and--local_resources=cpu=HOST_CPUS*0.25
Scenario: Independent workspaces build concurrently
- WHEN separate Bazel servers build in multiple workspaces
- THEN each receives its own scheduling budget, without sharing an aggregate limit
1.3 - Openspec cli
1.3.1 - openspec-cli Specification
Purpose
Keep Host Bot’s user-facing OpenSpec CLI installation reproducible through its checked-in Ansible deployment.
Requirements
Requirement: Managed OpenSpec CLI installation
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.
Scenario: Provision the CLI
- WHEN the Host Bot deployment runs with OpenSpec absent
- THEN it installs the configured version and exposes
~/.local/bin/openspecto the managed user
Scenario: Repeat the deployment
- WHEN the configured OpenSpec version is already installed
- THEN the npm task leaves the package unchanged
1.4 - Owned dns
1.4.1 - owned-dns Specification
Purpose
Define Host Bot DNS management through the owner’s tf root,
including canonical declarations, scoped credentials, and offline source checks
before adopting live records.
Requirements
Requirement: Owner-local DNS configuration
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.
Scenario: Inspect the preparatory configuration
- 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
Scenario: Inspect adopted source defaults
- 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
Scenario: Reconcile existing DNS records
- 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
Requirement: Scoped DNS execution and offline checks
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.
Scenario: Validate the Terraform source
- 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
Scenario: Prepare an operational Terraform invocation
- 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
1.5 - Power profile
1.5.1 - power-profile Specification
Purpose
Keep the host’s selected power profile reproducible through its owning Ansible configuration while retaining an explicit desired profile.
Requirements
Requirement: Managed host power 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.
Scenario: Selected profile differs
- WHEN the active profile differs from the declared profile
- THEN deployment selects and persists the declared profile
Scenario: Automatic selection is enabled
- WHEN the active profile matches but selection is automatic
- THEN deployment persists the declared profile with manual selection
Scenario: No profile is active
- WHEN Tuned reports that no profile is active
- THEN deployment selects the declared profile instead of failing on that expected query result
Scenario: Desired state already matches
- WHEN the active profile matches and selection is manual
- THEN deployment does not repeat the profile-selection command
Scenario: Query fails unexpectedly
- WHEN querying the active profile or selection mode fails unexpectedly
- THEN deployment reports the failure instead of concealing it