docs(framework): complete TSYSGroupAIOS adoption + tracker/IaC rules [#454]

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
This commit is contained in:
2026-08-27 09:26:26 -05:00
parent 28b28026bf
commit 721968bc3b
5 changed files with 565 additions and 0 deletions
+139
View File
@@ -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 <org> --name <project> --template-from TSYSGroupCorporate/TSYSGroupAIOS
# or clone directly:
git clone ssh://git@git.knownelement.com:29418/TSYSGroupCorporate/TSYSGroupAIOS.git <project>
cd <project>
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/<existing-project>
# 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 |
+31
View File
@@ -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; - **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 gather ground truth. Do not burn tokens reasoning about things a quick command
answers. 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 - **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 runners. If an LSP is wired up, use it; otherwise pull a Docker image and lint
inside it. inside it.
@@ -331,11 +334,39 @@ vendor/ Vendored KNELShellFramework
justification. A script that emits any diagnostic is a protocol violation. justification. A script that emits any diagnostic is a protocol violation.
Non-bash scripts (PHP with `.sh` shebang `#!/usr/bin/php`, etc.) are exempt. 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 Tracking Policy
**Redmine is the system of record for all work.** Do not track status, **Redmine is the system of record for all work.** Do not track status,
checklists, or TODOs in repo files. Use Redmine tickets instead. 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 - **URL:** https://projects.knownelement.com
- **Version:** Potential to Kinetic Ready (due 2026-09-30) - **Version:** Potential to Kinetic Ready (due 2026-09-30)
- **Project:** Known Element Enterprises - Technology & Facility Services (id 55) - **Project:** Known Element Enterprises - Technology & Facility Services (id 55)
+141
View File
@@ -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. `<project>-<service>`).
- 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.
+247
View File
@@ -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 <subcommand>` |
| KNEL-AIMiddleware | `scripts/<Verb>.sh` |
| EngStack | `scripts/<verb>-<noun>.sh` |
| PFVCluster | `tests/<name>.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.
+7
View File
@@ -51,3 +51,10 @@
- **Answer:** _(human)_ - **Answer:** _(human)_
- **Decision:** _(human/agent)_ - **Decision:** _(human/agent)_
- **Synthesized to:** — - **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:** —