diff --git a/ADOPTING.md b/ADOPTING.md new file mode 100644 index 0000000..43ff244 --- /dev/null +++ b/ADOPTING.md @@ -0,0 +1,139 @@ +# ADOPTING.md — How to adopt this framework into an existing project + +> This is the guide you give to an agent (or human) that says: +> "Look at `~/daytoday/meta` and adopt its rules/patterns for this project." +> +> The framework lives at: `ssh://git@git.knownelement.com:29418/TSYSGroupCorporate/TSYSGroupAIOS.git` +> Template repo: https://git.knownelement.com/TSYSGroupCorporate/TSYSGroupAIOS + +--- + +## For a NEW project (greenfield) + +```bash +# Create from the Gitea template, clone, done: +tea repo create --owner --name --template-from TSYSGroupCorporate/TSYSGroupAIOS +# or clone directly: +git clone ssh://git@git.knownelement.com:29418/TSYSGroupCorporate/TSYSGroupAIOS.git +cd +make setup # install git hooks (= bash scripts/setup-hooks.sh) +make fast # verify baseline (= bash scripts/check-rules.sh --fast) +``` + +Then edit `AGENTS.md` (fill bracketed fields), override `scripts/test.sh`, and start work. + +--- + +## For an EXISTING project (brownfield — e.g. PFVCluster) + +Adoption is incremental. You don't rewrite the project — you overlay the +framework's enforcement layer and adjust the project's existing conventions to +match. Do these steps in order: + +### Step 1: Copy the enforcement layer + +```bash +cd ~/projects/ + +# Bring in the framework files that don't already exist. +# Get them from the meta repo: +META=~/daytoday/meta + +# Scripts, hooks engine, shared lib (the mechanical enforcement) +cp -n "$META/Makefile" . +mkdir -p scripts/lib +cp -n "$META/scripts/check-rules.sh" scripts/ +cp -n "$META/scripts/setup-hooks.sh" scripts/ +cp -n "$META/scripts/pre-commit" scripts/ +cp -n "$META/scripts/pre-push" scripts/ +cp -n "$META/scripts/docker-run.sh" scripts/ +cp -n "$META/scripts/garden.sh" scripts/ +cp -n "$META/scripts/lib/common.sh" scripts/lib/ +chmod +x scripts/*.sh scripts/pre-commit scripts/pre-push +``` + +### Step 2: Bring in the workflow files (if the project doesn't have them) + +```bash +cp -n "$META/STATUS.md" . # if the project's STATUS.md is a Discourse pointer, KEEP IT +cp -n "$META/WORKING.md" . +cp -n "$META/questions-v1.md" . +cp -n "$META/.env.example" . # only if the project doesn't have one +``` + +**Important:** if the project already uses Discourse as its SoR (like PFVCluster), +its existing `STATUS.md` may be a pointer stub to Discourse. In that case, do NOT +overwrite it — the project already has the right pattern. The template `STATUS.md` +is for projects that don't have one yet. + +### Step 3: Install git hooks and verify + +```bash +bash scripts/setup-hooks.sh # installs pre-commit + pre-push from scripts/ +bash scripts/check-rules.sh --fast # see what passes and what fails +``` + +### Step 4: Fix the failures (incrementally) + +`bash scripts/check-rules.sh --fast` will likely report failures — the project's existing code may not +pass shellcheck, or `.md` files lack Discourse pointers. **Fix these +incrementally; don't rewrite the project in one pass.** + +Common fixes: +- **shellcheck violations:** run `bash scripts/check-rules.sh` for details; fix warnings in the flagged files. +- **`:latest` image tags:** pin to a specific version in docker-compose / Dockerfile. +- **Container naming:** add `container_name:` to every service in docker-compose files. +- **Missing required files:** create `questions-v1.md`, `.env.example`, etc. +- **Discourse pointer-header:** for `.md` files that should be Discourse stubs, migrate content to Discourse and leave a pointer. For operational files (`AGENTS.md`, `STATUS.md`, etc.), add them to `PROJECT_DOC_EXEMPT`. + +### Step 5: Merge the project's AGENTS.md with the template + +Read both the project's existing `AGENTS.md` and the template's (`~/daytoday/meta/AGENTS.md`). +Merge by: +1. Keeping all project-specific content (VM paths, auth details, domain knowledge). +2. Adding the template's standard sections the project is missing (Quick Start, Systems of Record, Working Style, Key Commands, Enforcement Model). +3. Replacing any conflicting policy with the baseline (the template wins on cross-project conventions; the project wins on domain specifics). + +### Step 6: Configure project-specific env vars + +Set these in the project's `.env` or in the Makefile to customize checks: + +```bash +PROJECT_DOC_EXEMPT="AGENTS.md STATUS.md WORKING.md ..." # files that don't need Discourse pointers +PROJECT_DISCOURSE_HOST="community.turnsys.com" # Discourse instance +PROJECT_REQUIRED_FILES="..." # extra required files beyond the defaults +PROJECT_BANNED_SUFFIXES="py|js|ts" # banned production file types (optional) +``` + +### Step 7: Commit and push + +```bash +bash scripts/check-rules.sh # full audit should pass +git add -A +git commit -m "chore: adopt TSYSGroupAIOS framework (git hooks, rules engine, SoR policy)" +git push +``` + +--- + +## What NOT to change during adoption + +- **Don't rewrite existing code** that works. The framework enforces conventions going forward; fix existing violations incrementally via `bash scripts/check-rules.sh`. +- **Don't remove the project's Redmine/Discourse integration.** The framework *requires* it — the project already has it. Align the AGENTS.md prose to match. +- **Don't add `docs/JOURNAL.md`.** Redmine is the system of record for work; Discourse for docs. No JOURNAL.md. +- **Don't add Crush hooks.** The framework is harness-agnostic. Enforcement is git hooks + AGENTS.md prose only. + +--- + +## Quick reference: what the framework gives you + +| What | Files | Portable? | +|---|---|---| +| Git hooks (pre-commit/pre-push) | `scripts/pre-commit`, `scripts/pre-push` | Yes — any git, any agent | +| Rules engine | `scripts/check-rules.sh` | Yes | +| Shared bash library | `scripts/lib/common.sh` | Yes | +| Docker wrapper | `scripts/docker-run.sh` | Yes | +| Lifecycle scripts | `scripts/up.sh`, `scripts/down.sh` | Yes | +| Gardening | `scripts/garden.sh` | Yes | +| Policy document | `AGENTS.md` | Yes — any agent framework reads it | +| Global baseline | `BASELINE-PROMPT.md` | Yes — paste into any system prompt | diff --git a/AGENTS.md b/AGENTS.md index 616ddf6..52ca674 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -209,6 +209,9 @@ for the human's situational awareness during the session. - **Stop over-thinking.** Get to code and output faster. Explore with code; gather ground truth. Do not burn tokens reasoning about things a quick command answers. +- **Prefer Unix utilities** (awk, sed, grep, cut, tr) for file editing and + text processing over harness edit tools when feasible — deterministic and + exact where harness editors can be whitespace-fragile. - **Farm work out to deterministic tooling:** linters, LSPs, formatters, test runners. If an LSP is wired up, use it; otherwise pull a Docker image and lint inside it. @@ -331,11 +334,39 @@ vendor/ Vendored KNELShellFramework justification. A script that emits any diagnostic is a protocol violation. Non-bash scripts (PHP with `.sh` shebang `#!/usr/bin/php`, etc.) are exempt. +## TDD & Linting + +- **Red/green TDD for all code.** Mandatory (founder 2026-08-27). Interim + relaxation applies ONLY until the Ansible/IaC transition (week of 9/1); + from then on every playbook/script ships with its failing test first. + `scripts/test.sh` is the local gate; `tests/validation` + `tests/security` + run on sectestbed targets. +- **Linters on all code, as early as possible.** shellcheck zero-warning + (including info-level) is already enforced pre-commit. + +## IaC Codification (shadow tracking) — NON-NEGOTIABLE + +**Every manual/direct change to a fleet system must be codified same-day as +an AWX playbook item.** The fleet converges to 100% IaC (founder mandate, +2026-08-27, #454). + +- Made a manual change? Add a checklist item to #454 (or a child ticket) in + the same session — what changed, where, exact commands, and any quirks + (e.g. "needed udevadm trigger after NUT install"). +- Work is NOT "done" until the manual change is codified or explicitly + ticketed for codification. +- New manual fixes during incidents: fix first, codify immediately after. +- Playbooks live in this repo, tested through the `sectestbed-*` fleet. + ## Redmine Tracking Policy **Redmine is the system of record for all work.** Do not track status, checklists, or TODOs in repo files. Use Redmine tickets instead. +**Tracker discipline:** OAM/ops/feature/audit tickets use tracker **Support +(3)** — NOT Bug. The redmine-cli `create` defaults to Bug; always correct the +tracker after create (python escape hatch: `tracker_id=3`). [2026-08-27] + - **URL:** https://projects.knownelement.com - **Version:** Potential to Kinetic Ready (due 2026-09-30) - **Project:** Known Element Enterprises - Technology & Facility Services (id 55) diff --git a/BASELINE-PROMPT.md b/BASELINE-PROMPT.md new file mode 100644 index 0000000..a15aff9 --- /dev/null +++ b/BASELINE-PROMPT.md @@ -0,0 +1,141 @@ +# Global Baseline Prompt + +> The canonical set of working principles for every agent (AI or human) across +> every project. This is the source of truth; project `AGENTS.md` files inherit +> and specialize it. Derived from the owner's operating notes, deduplicated and +> stripped of project-specific detail. +> +> **Phase context:** we have exited the "move fast and loose" phase. This is +> production infrastructure — it is in production right now. The bar is the bar. + +--- + +## 1. You are an employee, not a lone genius + +- **Stop over-thinking.** Get to code and output faster. Explore with code; gather ground truth. Do not burn tokens reasoning about things a quick command can answer. +- **Ask questions early.** Use a git-tracked `questions-v(N).md` file (see §9) that the human reviews inline. Questions, answers, and the reasoning behind decisions are often more important than the code. Capture and synthesize them to Discourse/Redmine. +- **Don't ruminate or self-debate** at length in context — gather data from the human, from code, or both, and proceed. +- **You are not alone.** Ask for guidance when you need it. + +## 2. Token efficiency is a hard constraint + +- The owner has a quota. Burning tokens to parse huge code blocks or reason about easily-answerable questions is unacceptable. +- **Farm work out to deterministic tooling:** linters, LSPs, formatters, test runners — run them, read their output, don't reason about what they can tell you. +- If an LSP is wired up for the language (code or docs), use it. If not, pull a Docker image and lint inside it. Prose linting belongs in a Docker image too. +- Use `STATUS.md` as a durable, git-tracked scratchpad for high-fidelity tactical notes (see §8) so context doesn't have to be re-derived. +- Use sub-agents as **subcontractors** for well-defined parallel deliverables (see §12), not as staff augmentation. + +## 3. Systems of record (do not duplicate) + +- **Redmine is the single system of record for ALL project work** — tickets, tasks, schedules, Gantt, dependency modeling. Use the `redmine-cli` tool. Gitea issues are not used. +- **Discourse is the single system of record for documentation.** It is all Markdown. Use the `discourse-cli` tool. Do not author long-form docs in gitea. +- **Git-tracked `.md` files should be stubs** that point to the relevant Discourse URL. Short operational files that must live next to code (e.g. `AGENTS.md`, `STATUS.md`) are the exception. +- Engineering already works this way. Operations now does too. +- **Cross-referencing is mandatory.** Every Redmine ticket links to its Discourse doc; every Discourse doc links to its Redmine ticket(s); every commit references `[#NNN]`; every PR links to both Redmine and Discourse. Keep them in sync at all times. +- **Code, docs, and tests must be kept in sync at all times.** When you change code, update the corresponding docs (Discourse) and tests in the same commit. Never leave them out of sync. + +## 4. Infrastructure change approval workflow + +For infrastructure (operations) work, agents do NOT execute changes +without explicit human approval. The workflow is: + +1. **Prepare:** Agent creates scripts, configs, and a plan. Documents + the exact changes, blast radius, and rollback procedure in a + Redmine ticket. +2. **Review:** Human reviews and approves (or rejects) via Redmine. +3. **Execute:** Agent applies the change ONLY after approval. +4. **Verify:** Agent verifies the change worked and documents results + in Discourse. + +This applies to all production infrastructure: network configs, host +tuning, VM settings, DNS records, switch configs, etc. Read-only +audits and probes do NOT require approval — only changes that alter +system behavior. + +Code projects (software development) follow normal git/PR workflow and +do not require per-change Redmine approval. + +## 5. Git workflow + +- **Use the `tea` CLI for pull requests.** +- **Work smart off master** generally. Branches on the workstation are encouraged for moving fast, exploring ideas, and avoiding stash churn. +- **Once work leaves the workstation, it goes through a PR.** +- Branching strategy is open to per-project discussion. +- **Commits and PRs must cross-link** to Redmine tickets (`[#NNN]` in subject or body) and Discourse docs (in PR body). + +## 6. CI/CD — shift left, keep in lockstep + +- Strong preference that the **local workstation can run the same CI/CD** that the hosted infrastructure runs. Maintain them in lockstep across all projects. +- **The further left CI/CD runs, the better.** Catch it before push, before PR, before merge. +- We have a mix of developers and agents, some inside the hosted security boundary, some on beefy workstations. CI/CD must work for all of them. + +## 7. Docker and Kubernetes for everything + +- Use Docker and Kubernetes for everything — a cluster of 1 or 100 is the same. Don't presume scale. Containers are containers; k8s is k8s. +- **All development work happens in containers** — custom, off-the-shelf, or a mix. `docker pull` freely without asking. +- **Container naming: never use Docker's default.** Always name with a project prefix (e.g. `-`). +- Use Docker Compose with hook scripts to bring services up/down (lifecycle scripts). See `~/projects` for established examples. +- **Host hygiene is inviolable.** The host runs only `git`, `docker`, and standard Unix utilities (`awk`, `sed`, `grep`, `cut`, `tr`, `jq`, `find`, `xargs`, etc.). No language runtimes or package-managed tools beyond the base OS. + - **One-off utility needed?** `docker pull` a pinned image and run it ephemerally. Do not install on the host. + - **Broadly useful tool?** Create a Redmine ticket requesting the human add it via the system package manager. Do not install it yourself. + +## 8. Infrastructure-as-Code testing + +- When working on IAC, test against the corresponding **`sectestbed-` VM**. These are snapshot-able to a known base state (Tailscale-joined, Beszel-registered, SSH keys in place). The base state evolves; the delta of tested code shrinks over time. +- A new functional-area VM starts in that ultra-basic base state and has roles applied on top. +- **`preprod-` VMs** are for testing upgrades to new vendor software versions — they carry a snapshot of current prod. Snapshot/rollback semantics are work-stream-specific and need explicit discussion. +- Compliance mitigations may need to flow through both `sectestbed-` and `preprod-` testing, in lockstep. Redmine Gantt and dependency-relationship modeling are heavily used here. +- **Portability and reproducibility by anyone** — do not require AWX as a prerequisite (optional nice-to-have; not mandatory for bootstrap). + +## 9. STATUS.md — scratchpad, not system of record + +- **STATUS.md is a durable, git-tracked scratchpad for token efficiency.** It is not the system of record (Redmine is). +- The agent fully owns STATUS.md; the human only consumes it. +- Use it for high-fidelity tactical notes as you work — input for commit logs, PRs, and Redmine updates. +- The harness todo tool is fine for tracking *current* work; STATUS.md is the durable cross-session record. +- **STATUS.md has an Inbox section.** When the human tosses new work mid-task in another conversation turn, do NOT pivot. Log it in the Inbox. If it's materially different, spin up a Redmine ticket. + +## 10. Questions file — `questions-v(N).md` + +- **NEVER use a harness "question"/"ask user" tool** (structured prompts, + modal forms, tabbed questions, etc.). Ever. They are banned across every + project. They are not portable across harnesses, they don't version + history, and they bypass the git-tracked record. This is non-negotiable. +- **All questions go in the git-tracked `questions-v(N).md` file.** Write + the question; the human edits the answer inline in the same file. This + preserves history, works under every harness, and keeps reasoning next + to the answer. Version up (`questions-v2.md`, …) when a round lands. +- Capture questions in a versioned file: `questions-v1.md`, `questions-v2.md`, … +- The human reviews and edits it inline. Version it when a round of answers goes in. +- Synthesize resolved Q&A into Discourse (decisions/rationale) and Redmine (work items). + +## 11. Belt-and-suspenders protocol enforcement + +- Enforce the rules in **two layers**: prose policy in `AGENTS.md` and mechanical enforcement in git `pre-commit` / `pre-push` hooks. Harness-specific hooks (e.g. Crush `PreToolUse`) are avoided — keep enforcement portable so it works under any agent framework. +- Never rely on memory or prose alone. + +## 12. Gardening — keep docs from sprawling + +- Run a routine **gardening loop.** Agents are disciplined with code but tend to sprawl `.md` files everywhere. +- Keep docs, code, and tests in sync at all times. +- `scripts/garden.sh` reports `.md` sprawl and files that should be migrated to Discourse. + +## 13. Sub-agents as subcontractors + +The owner has a quota; the driving context is the expensive one. The biggest +token cost is prefix mutation, not per-call work — so keep the driving prefix +stable and push volatility into side-channels (sub-agents, STATUS.md). + +- **Mandate:** use sub-agents for any non-trivial search, audit, parallel review, or large-output read. **Never read 10+ files sequentially** — batch them into 2-3 agent calls. +- **Self vs. delegate:** read the 3-4 files you will immediately edit yourself (you need their content in-context for the edit anyway); dispatch agents for everything else. +- **Output contract:** request **distilled findings only**, never raw file contents. Specify the output format in the prompt. A sub-agent that returns a 500-line file dump has failed the contract. +- **Parallelize independent work; chain dependent work** (one agent's distilled summary feeds the next). +- **Why:** keeps the main context lean and preserves the cached prompt prefix. + +This is scoped, contract-style work with a clear handback — not staff augmentation. + +## 14. TDD and linting + +- **Red/green TDD for all code.** Write the failing test first. +- **Linters on all code, as early as possible.** Be token-efficient — let deterministic tools find the issues. +- **Prefer Unix utilities (awk, sed, grep, cut, tr, etc.) for file editing and text processing** over built-in harness edit tools when feasible. Harness edit tools can be unreliable with whitespace/indentation; Unix tools are deterministic and exact. diff --git a/PATTERNS.md b/PATTERNS.md new file mode 100644 index 0000000..1d60f8d --- /dev/null +++ b/PATTERNS.md @@ -0,0 +1,247 @@ +# Cross-Project Pattern Extraction + +**Scope:** 18 projects surveyed across two machines: +- **Local (`ultix-streaming`):** 12 infra/stack projects — `dotfiles`, `EngineeringWorkstation`, `EngStack`, `football`, `hermes-rceo-streaming`, `KNEL-AIMiddleware`, `KNELIAC`, `netbird`, `PFVCluster`, `TSYSDevStack-SupportStack-Cloudron`, `WorkstationStack`, `TSYSDevStack-SupportStack-LocalWorkstation`. +- **Remote (`ultix-offstage`):** 6 personal/business projects — `CharlesNWybleResume`, `rceo-automation-espanso-private`, `RCEO-PersonalAssistant`, `ReachableCEO-Profile-FullTimeEmployment`, `RevGen-TimeForMoney`, `ThreeYearPlan`. + +This document records the patterns that recur, the inconsistencies between them, +and the decisions the repo makes to drive inconsistency to zero. + +--- + +## 1. AGENTS.md — recurring structure + +A canonical section set emerges from the 12 files that have one (8 local + 4 remote): + +| Section | Prevalence | +|---|---| +| Git commit & push policy | 12/12 | +| Project overview / context | 11/12 | +| Key commands / build cheat sheet | 10/12 | +| Repository layout (ASCII tree) | 9/12 | +| Status / journal maintenance | 9/12 | +| Conventions & naming | 8/12 | +| DO / DON'T | 7/12 | +| Validation / testing | 7/12 | +| Key files reference | 6/12 | +| Quick start / onboarding | 5/12 | + +**Decision:** the template's `AGENTS.md` ships all ten sections in a fixed order, +so every project has the same skeleton. Filler is bracketed for replacement. + +--- + +## 2. Shared cross-project preferences (the house style) + +These recur strongly and are baked into the template: + +1. **Auto-commit + push is mandatory and non-negotiable.** Stated with ALL-CAPS force in nearly every file. The template states the override-once and lets the hooks enforce it. +2. **Atomic commits — one logical change per commit.** Universal. +3. **Conventional-commit format** (`feat:`/`fix:`/`docs:`/…). Universal, but the **💘 Crush attribution footer is inconsistent**: mandated only by `football` and `KNELIAC`; absent on the remote entirely. **Decision:** the template mandates the footer once, in the AGENTS.md commit block. +4. **Docker-only host hygiene.** The single most consistent convention across *both* machines (`KNEL-AIMiddleware`, `EngStack`, `LocalWorkstation`, `RCEO-PersonalAssistant`, `ThreeYearPlan`, `CharlesNWybleResume`). **Decision:** the template's `check-rules.sh` enforces host hygiene via the Docker-only rule (no `:latest` tags, container naming) and `scripts/docker-run.sh` provides the canonical container wrapper. The Crush-specific `enforce-bash.sh` hook was removed for harness portability; the policy lives in AGENTS.md prose. +5. **Sub-agents encouraged.** Explicit in `football`, `ThreeYearPlan`, `RCEO-PersonalAssistant`. **Decision:** standard section in the template. +6. **No secrets in git (infra genre).** Inverted on the remote private repos (`RCEO-PersonalAssistant` deliberately commits credentials). **Decision:** the template keeps the infra stance (`.env` gitignored) as the default; private repos may opt out. + +**Inconsistencies the template resolves:** +- `shellcheck` is mandated by `PFVCluster` and `football` but unmentioned elsewhere → the template mandates it for all shell, via Docker. +- "Keep the host clean" is phrased four different ways → one canonical phrasing. +- Auto-commit override language varies in strength → stated once, authoritatively. + +--- + +## 3. Git hooks — the biggest gap, now standardized + +**Finding:** custom git hooks are essentially unused. Only **3 of 18** projects have any: + +| Project | Hook | Mechanism | Installer | +|---|---|---|---| +| `football` | `pre-commit` (4-check SDLC gate: shellcheck, unit tests, coverage, doc-sync) | `core.hooksPath githooks/` | `scripts/setup-githooks.sh` | +| `KNEL-AIMiddleware` | `pre-push` (block on dirty tree) | `core.hooksPath .githooks/` | **none** (manual `git config`) | +| `RCEO-PersonalAssistant` | `pre-commit` (fast audit) + `pre-push` (full Docker tests) | **copy** into `.git/hooks/` | `scripts/setup-hooks.sh` | + +Three different install mechanisms; one project has no installer at all. + +**Decision:** the template uses the **copy** approach (most portable: works on any clone, no config mutation, idempotent) with a single `scripts/setup-hooks.sh`, and combines both policy philosophies: +- `pre-commit` = fast audit with a **hot-path bypass** for `STATUS.md` / `JOURNAL.md` / `WORKING.md` (so frequent status commits stay frictionless) — proven in RCEO. +- `pre-push` = full audit (incl. `scripts/test.sh`) — proven in RCEO — plus the dirty-tree gate — proven in KNEL-AIMiddleware. + +--- + +## 4. Crush hooks — an entirely untapped capability (except one project) + +**Finding:** Crush `hooks` are used by **exactly one project** — `RCEO-PersonalAssistant`. Every other `crush.json` (and most projects have none) defines only `lsp`/`mcp`/`options`, never `hooks`. All process enforcement elsewhere is prose in AGENTS.md — manually enforced, violable. + +RCEO's crush.json wires five `PreToolUse` hooks that form a behavioral guardrail layer complementing the git hooks: + +| Hook | Matcher | Effect | +|---|---|---| +| `block-todos.sh` | `^todos$` | bans the todos tool; WORKING.md is the only tracker | +| `enforce-bash.sh` | `^bash$` | blocks banned commands + host language toolchains | +| `enforce-rules.sh` | `^(edit\|write\|multiedit)$` | blocks banned file types; TDD reminder on source edits | +| `audit-before-git.sh` | `^bash$` | runs the fast audit before any `git commit`/`git push` | +| `exit-protocol.sh` | `.*` | blocks stopping while WORKING.md has unchecked tasks | + +**Decision:** the Crush hooks were studied as the proof-of-concept and their *policies* (ban todos, Docker-only, banned file types, audit before git, exit protocol) were ported into AGENTS.md prose and `check-rules.sh` mechanical checks. The harness-specific `crush.json` + `hooks/` layer was **deliberately removed** for portability — the user is shifting away from Crush to OpenWebUI/Hermes, so all enforcement is git hooks + prose only. + +--- + +## 5. The rules engine — `check-rules.sh` + +RCO's `check-rules.sh` is the best reusable artifact found. Its core abstractions: + +- A `check()` accumulator classifying each rule as **pass / warn / fail**, with `FAIL > 0 ⇒ exit 1` and `WARN` non-fatal. +- A `--fast` mode (used by pre-commit) that silences per-check output and skips slow checks. +- Self-checking categories: shellcheck, Docker image pinning (no `:latest`), required-files manifest, doc freshness (STATUS.md/JOURNAL.md touched today), git state, hooks-installed, WORKING.md completion, unresolved `CNW:` markers. + +**Decision:** the template's `check-rules.sh` generalizes this — language-specific checks (Go test coverage, gofmt) are dropped or made opt-in via `PROJECT_*` env; universal checks (shellcheck, image pinning, required files, doc freshness, hygiene, WORKING.md, CNW markers, merge-conflict markers) are kept. The `check()` accumulator and `--fast`/`--quiet` flags move into `scripts/lib/common.sh` so any script can reuse them. + +--- + +## 6. Scripts — driving the shebang/boilerplate chaos to zero + +**Findings:** +- **Three incompatible shebang variants** across projects: `#!/usr/bin/env bash` (best), `#!/bin/bash`, `#!/usr/bin/bash` (non-portable). +- **Four different `set`-flag policies**: `set -euo pipefail` (best), `set -e` only, `set -uo pipefail`, none. KNEL-AIMiddleware uses `set -e` only — piped failures silently swallowed; `BuildAll.sh`'s `docker compose … | tail` can report green on failure. +- **The ANSI color block is copy-pasted into ~10 scripts.** +- **`log_*` helpers are redefined per project** (and per-script in KNEL-AIMiddleware, where they aren't even functions). +- **Repo-root resolution** is re-rolled in nearly every script. +- **No shared cross-project library exists.** Only `EngStack` factors helpers (`scripts/lib.sh` build-time + `lib/common.sh` runtime). + +**Decision:** `scripts/lib/common.sh` provides the deduplicated primitives once: ANSI colors, `log_info/ok/warn/error/step`, `have()`, `die()`, `repo_root()`, `as_root()`, `docker_run()`, and the `init_counters`/`check`/`print_summary_and_exit` audit helpers. All template scripts use `#!/usr/bin/env bash` + `set -euo pipefail`. + +--- + +## 7. Task runners — five conventions, standardized to one + +**Findings:** no `Makefile`/`Taskfile`/`justfile` exists anywhere. Five incompatible conventions for the same semantic verbs: + +| Project | Convention | +|---|---| +| football | `./run.sh ` | +| KNEL-AIMiddleware | `scripts/.sh` | +| EngStack | `scripts/-.sh` | +| PFVCluster | `tests/.sh` | +| hermes-agent | npm workspace scripts | + +The recurring semantic targets — **build, test, lint, validate, status, clean, setup** — map cleanly onto one target set that doesn't exist. + +**Decision:** a single `Makefile` provides `setup`, `validate`, `fast`, `lint`, `test`, `status`, `clean`, `help`. It is pure dispatch to `scripts/`; projects override `test`/`clean` for their stack. CI, hooks, and humans now share one set of verbs. + +--- + +## 8. CI — present in exactly one project + +Only `hermes-agent` has CI (22 GitHub Actions workflows — an exemplar: change-detection orchestrator, reusable-workflow lanes, SHA-pinned actions, supply-chain/OSV scans, live PR-comment bot). The other 17 have none. + +**Decision:** the template doesn't ship CI (it's stack-dependent), but `scripts/check-rules.sh` + `scripts/garden.sh` give any future workflow a uniform entry point. The hermes-agent `ci.yml` orchestrator is the documented growth path. + +--- + +## 9. Crush configuration layers — documented but unused + +Crush defines a priority chain (`$HOME/.config/crush/crush.json` → `crush.json` → `.crush.json`). In practice: +- The **global** config (`dotfiles`) is trivial (attribution style only) — no shared LSP/MCP baseline. +- Only **2 projects** have a project-local `crush.json` (KNEL-AIMiddleware: 4 LSP + 36 MCP via wrappers; RCEO-PersonalAssistant: hooks only). +- The highest-priority `.crush.json` layer is **unused anywhere**. +- **No project sets `model` or `provider`** in config. + +**Decision:** no Crush config is shipped. The hooks layer was removed for harness portability. LSP/MCP remain project-local concerns. + +--- + +## 10. Crush memory — a singleton, now a template + +Only `PFVCluster` has operational memory (`.crush/memory/operational.md`). Its format — Identity → Tracking Systems (with READY/PARTIAL/BLOCKED status) → Tooling → Access chokepoints → Key commands → Mandatory rules → Credential TODOs — is strong and reusable. + +**Decision:** the template ships `.crush/memory/operational.md` as a fill-in skeleton (optional, for projects using Crush). + +--- + +## 11. KNEL-AIMiddleware wrapper ecosystem — a standardization opportunity (not in the template) + +`KNEL-AIMiddleware` hand-maintains **38 near-identical** wrapper scripts (`mcp-*-wrapper.sh`, `lsp-*-wrapper.sh`) for its MCP/LSP fleet. ~90% of each file is duplicated boilerplate (container-cleanup stanza, `docker run -i --rm --name`, env passthrough). Drift is already visible (default style, double-passed creds, one structurally-different LSP wrapper). There is **no generator**; they were hand-cloned by an agent over many sessions. + +**Recommendation (out of scope for the template):** replace the 38 files with one parameterized launcher driven by a declarative `servers.yaml` manifest, plus a `gen-wrappers.sh`. The template's `docker-run.sh` + `lib/common.sh` show the direction; the same idea applies at fleet scale. + +--- + +## 12. Workflow documents — WORKING.md / STATUS.md / JOURNAL.md + +The remote personal genre contributes a discipline absent from infra: a **task/state/document triad** enforced by hooks: + +- **WORKING.md** — the only task tracker (todos tool banned); commits blocked while `- [ ]` remain; cleared before responding. +- **STATUS.md** — agent-maintained dashboard humans read; staleness is a warning. +- **JOURNAL.md** — append-only ADR/pattern log; no today-entry is a warning. +- **`CNW:` markers** — flag unresolved questions for the human; empty markers are a warning. + +**Decision:** all four are in the template, and check-rules.sh enforces their freshness/completion. + +--- + +## Standardization scorecard + +| Inconsistency | Was | Now | +|---|---|---| +| Shebangs | 3 variants | `#!/usr/bin/env bash` | +| `set` flags | 4 policies | `set -euo pipefail` | +| Color/log boilerplate | copy-pasted ~10× | `lib/common.sh` | +| Task runner | 5 conventions | one `Makefile` | +| Git hook install | 3 mechanisms, 1 missing | one `setup-hooks.sh` (copy) | +| Git hook coverage | 3/18 projects | every project, two hooks | +| Crush hooks | 1/18 projects | not used (harness-agnostic; git hooks only) | +| Rules engine | 1 project (Go-specific) | generalized, project-agnostic | +| Crush memory | 1 project | skeleton in template (optional, Crush-only) | +| AGENTS.md structure | bespoke per project | canonical 10-section skeleton | +| 💘 commit footer | 2/18 projects | mandated in template (harness-agnostic) | + +--- + +## 13. Global baseline prompt integration + +After the initial extraction, the owner shared a draft "global baseline prompt" +(an Apple Note of operating observations gathered over weeks of working with +agents). It encodes principles that cut across every project and that the +template now reflects. The cleaned canonical version lives in +[`BASELINE-PROMPT.md`](BASELINE-PROMPT.md); the project-level specialization is +in `AGENTS.md`. New artifacts and checks added: + +### New policy encoded + +| Principle (baseline §) | How the template enforces it | +|---|---| +| **Stop over-thinking; ask early** (§1, §9) | `questions-v1.md` skeleton + AGENTS.md "Questions" section; required-files check fails if absent | +| **Token efficiency / farm to tooling** (§2) | `scripts/check-rules.sh` runs shellcheck in Docker; AGENTS.md "Working Style" forbids parsing huge code in context | +| **Redmine = SoR for work; Discourse = SoR for docs** (§3) | AGENTS.md "Systems of Record" section; `scripts/garden.sh` flags oversized non-Discourse `.md` | +| **Git .md = stubs to Discourse** (§3) | `scripts/garden.sh` reports oversized `.md` lacking a Discourse URL | +| **`tea` CLI for PRs; off-workstation → PR** (§4) | AGENTS.md "Git Workflow" policy | +| **Shift-left CI/CD, lockstep local + hosted** (§5) | AGENTS.md "CI/CD" section; `scripts/check-rules.sh --fast` runs at pre-commit | +| **Docker/k8s for everything; container naming** (§6) | new container-naming rule in `check-rules.sh` (every compose service needs `container_name`); `docker-compose.yml.example` + `scripts/up.sh` / `scripts/down.sh` | +| **STATUS.md = scratchpad, not SoR; has Inbox** (§8) | STATUS.md reframed; Inbox section for mid-task interruptions ("don't pivot") | +| **Questions file** (§9) | `questions-v1.md` artifact + required-files check | +| **Belt-and-suspenders enforcement** (§10) | already present (git hooks + Crush hooks) — now documented as policy | +| **Gardening loop** (§11) | `scripts/garden.sh` | +| **Sub-agents as subcontractors** (§12) | AGENTS.md "Working Style" | +| **TDD + linters** (§13) | AGENTS.md "TDD & Linting"; `enforce-rules.sh` TDD reminder (opt-in via `PROJECT_SOURCE_SUFFIXES`) | + +### New template artifacts + +- `BASELINE-PROMPT.md` — the cleaned canonical global prompt (lives in the meta root; projects inherit). +- `questions-v1.md` — git-tracked question log skeleton. +- `docker-compose.yml.example` — lifecycle template with project-prefix naming. +- `scripts/up.sh`, `scripts/down.sh` — compose lifecycle wrappers. +- `scripts/garden.sh` — doc-sprawl / Discourse-migration report. + +### New `check-rules.sh` checks + +- **Container naming** (§6): every service in a `docker-compose*.y*ml` must declare `container_name:`; failure otherwise. +- **Questions file required**: `questions-v1.md` must exist (required-files manifest). + +### New Makefile targets + +`scripts/garden.sh`, `scripts/up.sh`, `scripts/down.sh` — standard scripts across every project. + +### What stayed project-level (not globalized) + +- `sectestbed-` / `preprod-` VM testing semantics — IAC-workstream-specific; left as AGENTS.md prose, not a mechanical check. +- Redmine Gantt / dependency modeling — workflow-specific. +- Specific DNS/cloudron/SITER production details — out of scope. diff --git a/questions-v2.md b/questions-v2.md index 9284e39..9e018f8 100644 --- a/questions-v2.md +++ b/questions-v2.md @@ -51,3 +51,10 @@ - **Answer:** _(human)_ - **Decision:** _(human/agent)_ - **Synthesized to:** — + +### Q10. Git flow: direct-push vs PR workflow (TSYSGroupAIOS conflict)? +- **Context:** Template says "once work leaves the workstation, it goes through a PR" (tea CLI). This project's policy is ALWAYS commit+push directly to origin/main. Founder's own rule, reinforced all session. +- **Question:** Keep direct-push for PFVCluster (ops repo, solo operator), adopt PRs for playbook code post-IaC-transition, or hybrid? +- **Answer:** _(human)_ +- **Decision:** _(human/agent)_ +- **Synthesized to:** —