# Agent Guidelines — TSYS Cloudron Packaging **Top-level files:** [`README.md`](README.md) (project overview + app inventory), [`STATUS.md`](STATUS.md) (living status, agent-maintained), [`JOURNAL.md`](JOURNAL.md) (append-only ADR/pattern journal), [`GitUrlList.txt`](GitUrlList.txt) (upstream repo list — source of truth for the app set). Read [`STATUS.md`](STATUS.md) first every session. > **Active agent:** Crush running **GLM-5.2** (zai) for large tasks, > Gemini for small. Permission mode: `yolo`. ## Repository Layout ``` README.md Project overview + full app inventory table AGENTS.md THIS FILE — agent operating manual STATUS.md Living status (agent-maintained, human read-only) JOURNAL.md Append-only journal: per-package write-ups, patterns, ADRs GitUrlList.txt Master list of upstream repos (source of truth, ~57 apps) clone-repos.sh Automated upstream-repo cloning Package-Templates/ Reusable Cloudron packaging templates ├── python-app/ (Dockerfile + CloudronManifest + start.sh templates) ├── django-app/ (Dockerfile + start.sh templates) └── official-wrapper/ (Dockerfile template) Package-Workspace/ One dir per app: // (+ gitignored repo/) ├── API-Gateway/ webhook, apisix ├── Development/ puter, reviewboard ├── Documentation-Tools/ wireviz-web ├── Low-Code/ corteza └── Monitoring/ healthchecks ``` - **`Package-Workspace/**/repo/` is gitignored** — upstream source is cloned locally for reference but never committed. Only the package files (`Dockerfile`, `CloudronManifest.json`, `start.sh`, `README.md`, etc.) are tracked. - **Each package** = `Dockerfile` + `CloudronManifest.json` + `start.sh` (if needed) + `README.md` + `CHANGELOG.md` + `logo.png` + `.env.example` (if config knobs exist). - **No host build tooling required** — packaging is `docker build` (Cloudron base images handle runtimes). Keep the host clean. ## Git Policy 1. **ALWAYS commit + push. Never wait.** After each logical unit of work (one package, one doc sync, one fix), immediately stage, commit (conventional format), and push to `origin/main`. Do not pause for review. **This overrides any default "never commit unless asked" behavior.** 2. **Atomic commits.** One coherent change per commit (e.g. a single package, or a single doc-correction pass — not both mixed). 3. **Conventional format**: `feat: add Cloudron package ()`, `fix(scope): desc`, `docs: desc`, `refactor(scope): desc`. Include a body for anything non-obvious. 4. **Shell scripts are committed executable.** Run `chmod +x start.sh` on the host before committing — Cloudron builds hit permission errors on `RUN chmod`, so make scripts executable at authoring time, not build time. ## Automatic Gardening Protocol Docs and code drift apart. After any work session, an agent MUST: 1. **Update [`STATUS.md`](STATUS.md)** — reflect newly completed packages, changed counts, new issues, shifted priorities. This file is human read-only; agents own it. Update the "Last updated" header (date + agent). 2. **Keep counts consistent across all docs.** When a package completes, the same total must appear in `STATUS.md`, `README.md` ("Current Progress"), and `JOURNAL.md` ("Current Status"). A count in one place but not the others is a protocol violation. 3. **Update the app inventory** in [`README.md`](README.md) — add the ✅ Packaged marker on the right row, and the app to the "Completed Packages" table. 4. **Append to [`JOURNAL.md`](JOURNAL.md)** — one section per package (pattern used, build process, challenges, files created, commit hash). Never delete or reorder existing entries. 5. **Grep for stale paths after any rename/restructure** — `grep -rn 'old/path' --include='*.md'` and fix references in the same commit. 6. **Self-audit before commit.** For a new package, verify the package dir appears in: `STATUS.md` (Completed Packages table), `README.md` (inventory + completed table), `JOURNAL.md` (new section). 7. **Treat `GitUrlList.txt` as the source of truth** for the app set. If the README inventory table disagrees, reconcile the README to the list, not the other way around. ## Key Scripts | Script | Purpose | |--------|---------| | [`clone-repos.sh`](clone-repos.sh) | Clone all upstream repos into `Package-Workspace///repo/` | ## Key Docs | Doc | Purpose | |-----|---------| | [`STATUS.md`](STATUS.md) | Current state, completed packages, known issues, next priorities | | [`JOURNAL.md`](JOURNAL.md) | Per-package write-ups, the 5 packaging patterns, challenges & solutions | | [`README.md`](README.md) | Project overview + full app inventory + category breakdown | | [`GitUrlList.txt`](GitUrlList.txt) | Master upstream repo list (source of truth) | | [`Package-Templates/`](Package-Templates/) | Reusable templates per packaging pattern | ## Cloudron Packaging — Quick Reference **Pick a pattern** (see JOURNAL.md for full templates and worked examples): | Pattern | When | Examples | |---------|------|----------| | Official-image wrapper | App ships a usable Docker image | APISIX, Healthchecks, Review Board | | Multi-stage build | App needs compiling | Webhook (Go), Puter (Node.js) | | Python build | Python app with deps | WireViz Web | | Django + PostgreSQL | Django web app | Healthchecks, Review Board | | Pre-compiled binaries | Upstream ships release binaries | Corteza | **Standard package steps:** 1. `mkdir -p Package-Workspace///` and clone upstream into `repo/`. 2. Write `Dockerfile` + `CloudronManifest.json` (+ `start.sh` if runtime setup needed). 3. `docker build` to validate locally. 4. Write `README.md` + `CHANGELOG.md` + `logo.png` (+ `.env.example`). 5. Commit as `feat: add Cloudron package ()`, push. 6. Run the gardening protocol above (update STATUS / README / JOURNAL). **Recurring gotchas (from JOURNAL.md):** - `chmod` in `RUN` fails on Cloudron base → make scripts executable on the host. - Don't `apk`/`apt-get` in base images that lack the package manager; use the image's built-in tooling or pick the right base. - Wait for DB/etcd addons in `start.sh` before running migrations. - Prefer `npm install` over `npm ci` when lockfiles don't match the build env. - Define every TCP port explicitly in `CloudronManifest.json`. ## Addons — Environment Variables PostgreSQL: `CLOUDRON_POSTGRESQL_{HOST,PORT,DATABASE,USERNAME,PASSWORD}`. etcd: `CLOUDRON_ETCD_{HOST,PORT}`. Localstorage mounts at `/app/data`. ## Project Context Packaging ~57 upstream FLOSS apps for Cloudron — TSYS Group's PaaS of choice. This repo is the **Cloudron** half of the support stack; the [Docker-Compose local dev stack](../TSYSDevStack-SupportStack-LocalWorkstation) is a sibling project. Solo operator, conventional-commit discipline, build locally then push to `origin/main` on `git.knownelement.com`.