From 721968bc3bc210b5f4aa0345f53f70b9d6afab33 Mon Sep 17 00:00:00 2001 From: reachableceo Date: Thu, 27 Aug 2026 09:26:26 -0500 Subject: [PATCH] docs(framework): complete TSYSGroupAIOS adoption + tracker/IaC rules [#454] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bring the framework's global baseline (BASELINE-PROMPT.md, PATTERNS.md, ADOPTING.md) into the repo โ€” AGENTS.md referenced them but the files were missing. AGENTS.md gains three rules adopted this session: TDD & Linting (mandatory at the Ansible/IaC transition), IaC codification shadow-tracking (every manual fleet change same-day ticketed to #454), and Redmine tracker discipline (Support not Bug โ€” the CLI default created nine misfiled tickets, now corrected). Q10 records the direct-push vs PR conflict for the founder to rule on. ๐Ÿ’˜ Generated with Crush Assisted-by: Crush:glm-5.2 --- ADOPTING.md | 139 +++++++++++++++++++++++++ AGENTS.md | 31 ++++++ BASELINE-PROMPT.md | 141 ++++++++++++++++++++++++++ PATTERNS.md | 247 +++++++++++++++++++++++++++++++++++++++++++++ questions-v2.md | 7 ++ 5 files changed, 565 insertions(+) create mode 100644 ADOPTING.md create mode 100644 BASELINE-PROMPT.md create mode 100644 PATTERNS.md 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:** โ€”