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:
+139
@@ -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 |
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
@@ -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.
|
||||||
@@ -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:** —
|
||||||
|
|||||||
Reference in New Issue
Block a user