Files
detections-semantic/.cursor/skills/monorepo-document/SKILL.md
T
2026-04-18 22:04:08 +03:00

176 lines
8.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: monorepo-document
description: Syncs unified documentation (`_docs/*.md` and equivalent) in a monorepo after one or more components changed. Reads `_docs/_repo-config.yaml` (produced by monorepo-discover) to know which doc files each component feeds into and which cross-cutting docs own which concerns. Touches ONLY documentation files — never CI, compose, env templates, or component directories. Use when a submodule/package added/changed an API, schema, permission, event, or dependency and the unified docs need to catch up.
---
# Monorepo Document
Propagates component changes into the unified documentation set. Strictly scoped to `*.md` files under `docs.root` (and `repo.root_readme` if referenced as cross-cutting).
## Scope — explicit
| In scope | Out of scope |
| -------- | ------------ |
| `_docs/*.md` (primary and cross-cutting) | `.env.example`, `docker-compose.*.yml` → use `monorepo-cicd` |
| Root `README.md` **only** if `_repo-config.yaml` lists it as a doc target (e.g., services table) | Install scripts (`ci-*.sh`) → use `monorepo-cicd` |
| Docs index (`_docs/README.md` or similar) cross-reference tables | Component-internal docs (`<component>/README.md`, `<component>/docs/*`) |
| Cross-cutting docs listed in `docs.cross_cutting` | `_docs/_repo-config.yaml` itself (only `monorepo-discover` and `monorepo-onboard` write it) |
If a component change requires CI/env updates too, tell the user to also run `monorepo-cicd`. This skill does NOT cross domains.
## Preconditions (hard gates)
1. `_docs/_repo-config.yaml` exists.
2. Top-level `confirmed_by_user: true` in the config.
3. `docs.root` is set (non-null) in the config.
4. Components-in-scope have `confirmed: true` mappings, OR the user explicitly approves an inferred mapping for this run.
If any gate fails:
- Config missing → redirect: "Run `monorepo-discover` first."
- `confirmed_by_user: false` → "Please review the config and set `confirmed_by_user: true`."
- `docs.root: null` → "Config has no docs root. Run `monorepo-discover` to re-detect, or edit the config."
- Component inferred but not confirmed → ask user: "Mapping `<component>``<doc>` is inferred. Use it this run? (y/n/edit config first)"
## Mitigations (same M1M7 spirit)
- **M1** Separation: this skill only syncs docs; never touches CI or config.
- **M3** Factual vs. interpretive: don't guess mappings. Use config. If config has an `unresolved:` entry for a component in scope, SKIP it (M5) and report.
- **M4** Batch questions at checkpoints: end of scope determination, end of drift check.
- **M5** Skip over guess: missing/ambiguous mapping → skip and report, never pick a default.
- **M6** Assumptions footer every run; append to config's `assumptions_log:`.
- **M7** Drift detection before action: re-scan `docs.root` to verify config-listed docs still exist; if not, stop and ask.
## Workflow
### Phase 1: Drift check (M7)
Before editing anything:
1. For each component in scope, verify its `primary_doc` and each `secondary_docs` file exists on disk.
2. For each entry in `docs.cross_cutting`, verify the file exists.
3. If any expected file is missing → **stop**, ask user whether to:
- Run `monorepo-discover` to refresh the config, OR
- Skip the missing file for this run (recorded as skipped in report)
Do NOT silently create missing docs. That's onboarding territory.
### Phase 2: Determine scope
If the user hasn't specified which components changed, ask:
> Which components changed? (a) list them, (b) auto-detect from recent commits, (c) skip to review changes you've already made.
For **auto-detect**, for each component in config:
```bash
git -C <path> log --oneline -20 # submodule
# or
git log --oneline -20 -- <path> # monorepo subfolder
```
Flag components whose recent commits touch doc-relevant concerns:
- API/route files (controllers, handlers, OpenAPI specs, route definitions)
- Schema/migration files
- Auth/permission files (attributes, middleware, policies)
- Streaming/SSE/websocket event definitions
- Public exports (`index.ts`, `mod.rs`, `__init__.py`)
- Component's own README if it documents API
- Environment variable additions (only impact docs if a Configuration section exists)
Present the flagged list; ask for confirmation before proceeding.
### Phase 3: Classify changes per component
For each in-scope component, read recent diffs and classify changes:
| Change type | Target doc concern |
| ----------- | ------------------ |
| New/changed REST endpoint | Primary doc API section; cross-cutting arch doc if pattern changes |
| Schema/migration | Cross-cutting schema doc; primary doc if entity documented there |
| New permission/role | Cross-cutting roles/permissions doc; index permission-matrix table |
| New streaming/SSE event | Primary doc events section; cross-cutting arch doc |
| New inter-component dependency | Cross-cutting arch doc; primary doc dependencies section |
| New env variable (affects docs) | Primary doc Configuration section only — `.env.example` is out of scope |
Match concerns to docs via `docs.cross_cutting[].owns`. If a concern has no owner, add to an in-memory unresolved list and skip it (M5) — tell the user at the end.
### Phase 4: Apply edits
For each mapping (component change → target doc):
1. Read the target doc.
2. Locate the relevant section (heading match, anchor, or `primary_doc_section` from config).
3. Edit only that section. Preserve:
- Heading structure and anchors (inbound links depend on them)
- Table column widths / alignment style
- ASCII diagrams (characters, indentation, widths)
- Cross-reference wording style
4. Update cross-references when needed: if a renamed doc is linked elsewhere, fix links too.
### Phase 5: Skip-and-report (M5)
Skip a component, don't guess, if:
- No mapping in config (the component itself isn't listed)
- Mapping tagged `confirmed: false` and user didn't approve it in Phase 2
- Component internally inconsistent (README asserts endpoints not in code) — surface contradiction
Each skip gets a line in the report with the reason.
### Phase 6: Lint / format
Run markdown linter or formatter if the project has one (check for `.markdownlintrc`, `prettier`, or similar at repo root). Skip if none.
### Phase 7: Report + assumptions footer (M6)
Output:
```
monorepo-document run complete.
Docs updated (N):
- _docs/01_flights.md — added endpoint POST /flights/gps-denied-start
- _docs/00_roles_permissions.md — added permission `FLIGHTS.GPS_DENIED.OPERATE`
- _docs/README.md — permission-matrix row updated
Skipped (K):
- satellite-provider: no confirmed mapping (config has unresolved entry)
- detections-semantic: internal README references endpoints not in code — needs reconciliation
Assumptions used this run:
- component `flights` → `_docs/02_flights.md` (user-confirmed in config)
- roles doc = `_docs/00_roles_permissions.md` (user-confirmed cross-cutting)
- target branch: `dev` (from conventions.work_branch)
Next step: review the diff in your editor, then commit with
`<commit_prefix> Sync docs after <components>` (or your own message).
```
Append to `_docs/_repo-config.yaml` under `assumptions_log:`:
```yaml
- date: 2026-04-17
skill: monorepo-document
run_notes: "Synced <components>"
assumptions:
- "<list>"
```
## What this skill will NEVER do
- Modify files inside component directories
- Edit CI files, compose files, install scripts, or env templates
- Create new doc files (that's `monorepo-onboard`)
- Change `confirmed_by_user` or any `confirmed: <bool>` flag
- Auto-commit or push
- Guess a mapping not in the config
## Edge cases
- **Component has no primary doc** (UI component that spans all feature docs): if config has `primary_doc: null` or similar marker, iterate through `docs.cross_cutting` where the component is referenced. Don't invent a doc.
- **Multiple components touch the same cross-cutting doc in one run**: apply sequentially; after each edit re-read to get updated line numbers.
- **Cosmetic-only changes** (whitespace renames, internal refactors without API changes): inform user, ask whether to sync or skip.
- **Large gap** (doc untouched for months, component has dozens of commits): ask user which commits matter — don't reconstruct full history.