AGENTS.md · git:20260817.9c1c7b4 · 2026-08-17 · sha256 f5a9134567bbfb65
AGENTS.md git:20260817.9c1c7b4A
Immutable. This exact content is served forever at /api/v1/blob/f5a9134567bbfb65.
# AGENTS.md - msp-skills Instructions for AI agents working in this repository. Read this before making changes; see [`CONTRIBUTING.md`](CONTRIBUTING.md) for the human-facing version. ## What this repo is A monorepo of MSP vendor connectors. Each `skills/<slug>/cli` is a Go CLI + MCP server **generated by [cli-printing-press](https://github.com/mvanhorn/cli-printing-press)** and then carries connector-specific edits. The press is upstream and refreshes independently; we pull new binaries and **reprint** connectors over time. ## Before you reprint or re-onboard a connector (READ THIS) A reprint regenerates the `DO NOT EDIT` files under `skills/<slug>/cli` and can **silently clobber** a hand-fix - the build and tests stay green while the live-API behavior the fix encoded is gone (this is how the axcient `id_` primary-key fallback got reverted; see [`docs/reprint-survival.md`](docs/reprint-survival.md)). **Whenever you regenerate, reprint, re-onboard (msp-skills-publish UPDATE), or bulk-overwrite a connector's `cli/` tree, you MUST:** 1. **Before** generating, read the connector's recorded hand-fixes so you know what to preserve: ```bash python3 tools/maintainer/check_handfixes.py --brief --slug <slug> ``` Preserve every entry it lists (3-way merge, don't blind-overwrite). For a targeted fix, prefer a surgical change over a full reprint. 2. **After** generating, prove nothing regressed: ```bash python3 tools/maintainer/check_handfixes.py --slug <slug> ``` If it fails, restore the missing hand-fix (the failure names the file + marker) before committing. CI runs this same gate per-skill and will block the merge otherwise. 3. **When you add a new hand-edit to a generated file**, record it in `skills/<slug>/handfixes.json` in the same change, or it will be unprotected on the next reprint. Schema + rationale: [`docs/reprint-survival.md`](docs/reprint-survival.md). Prefer encoding the behavior in the spec (e.g. `x-resource-id`) when the press supports it - that survives by construction. Find connectors whose hand-fixes are not yet recorded: ```bash python3 tools/maintainer/check_handfixes.py --discover ``` ## When a connector flips to live-verified (READ THIS TOO) A `live-verified` badge means a real MSP confirmed the connector against a real tenant. That is the moment it becomes worth keeping current, because it is the first moment anyone is positioned to notice a regression. Two questions come due: ```bash python3 tools/maintainer/check_engine_freshness.py --slug <slug> ``` 1. **Is the vendored engine behind the fleet?** The bar is the newest `printing_press_version` anywhere in `skills/*/manifest.json`, so it rises on its own - there is no constant to maintain. Only a MINOR-version gap is reported; a patch behind is not worth a reprint. Behind the bar means a reprint is worth considering, subject to the hand-fix rules above. It is not an order: a reprint is expensive and can clobber hand-fixes, and some connectors cannot be reprinted at all (a templated `token_url` is refused by press >= 4.30). 2. **Is the shipped binary behind `main`?** This is the one that actually bites. A tree-only fix reaches nobody: on 2026-08-16, 41 of 61 connectors were shipping binaries built before the 4.24 engine upgrade that had been sitting in `main` since June. `main` being current is not evidence that any user is running current code - only a tag is. This question is answered by `release_state.classify()`, which compares a freshly computed CLI hash against `cli_hash_at_release`. Do **not** answer it by comparing engine version stamps: a security fix like the GO-2026-6218 toolchain sweep changes every connector's binary without touching a single `printing_press_version`, so a stamp comparison reports the whole fleet as fine. That is a false-GREEN, and it is exactly the failure this check exists to catch. `.github/workflows/live-verified.yml` runs this automatically on every badge flip and posts the result as an issue comment. It is **advisory** - nothing gates on it. Whoever decides should record the decision in a reply on that issue so the next agent does not re-litigate it. ## General - Sign commits (`git commit -s`); no em-dashes in committed files; run `tools/maintainer/verify_all.sh <slug>` before pushing. See `CONTRIBUTING.md`.