From e7ec235d9a40fc46ff6c77df20a1e50d5b08991b Mon Sep 17 00:00:00 2001 From: Gale W Date: Thu, 20 Aug 2026 22:29:39 -0400 Subject: [PATCH 1/2] repository: integrate docs into repo maintenance --- ROADMAP.md | 6 +- docs/maintainers/automation-suitability.md | 2 +- docs/maintainers/validation-and-test-audit.md | 3 +- docs/releases/v10.0.2.md | 40 +++++ .../skills/bootstrap-xcode-workspace/SKILL.md | 4 +- .../skills/maintain-project-docs/SKILL.md | 73 --------- .../maintain-project-docs/agents/openai.yaml | 4 - ...ect-docs-maintenance-automation-prompts.md | 25 --- .../scripts/maintain_project_readme.py | 14 +- .../skills/maintain-project-repo/SKILL.md | 42 +++-- .../maintain-project-repo/agents/openai.yaml | 4 +- .../references/automation-prompts.md | 6 +- .../references/document-boundaries.md | 0 ...ect-docs-maintenance-automation-prompts.md | 30 ++++ .../references/trigger-eval.md | 5 +- .../scripts/maintain_project_docs.py | 2 +- .../scripts/run_workflow.py | 77 +++++++++- .../scripts/maintain_project_roadmap.py | 13 +- .../repository-operations-workflow/SKILL.md | 4 +- scripts/export_hermes_skills.py | 1 - skills.sh.json | 1 - skills/bootstrap-xcode-workspace/SKILL.md | 4 +- skills/maintain-project-docs/SKILL.md | 73 --------- .../maintain-project-docs/agents/openai.yaml | 4 - ...ect-docs-maintenance-automation-prompts.md | 25 --- .../scripts/maintain_project_readme.py | 14 +- skills/maintain-project-repo/SKILL.md | 42 +++-- .../maintain-project-repo/agents/openai.yaml | 4 +- .../references/automation-prompts.md | 6 +- .../references/document-boundaries.md | 0 ...ect-docs-maintenance-automation-prompts.md | 30 ++++ .../references/trigger-eval.md | 5 +- .../scripts/maintain_project_docs.py | 2 +- .../scripts/run_workflow.py | 77 +++++++++- .../scripts/maintain_project_roadmap.py | 13 +- .../repository-operations-workflow/SKILL.md | 4 +- tests/test_repository_docs_workflow.py | 81 ---------- tests/test_repository_maintenance_workflow.py | 143 ++++++++++++++++++ 38 files changed, 527 insertions(+), 356 deletions(-) create mode 100644 docs/releases/v10.0.2.md delete mode 100644 plugins/repository-skills/skills/maintain-project-docs/SKILL.md delete mode 100644 plugins/repository-skills/skills/maintain-project-docs/agents/openai.yaml delete mode 100644 plugins/repository-skills/skills/maintain-project-docs/references/project-docs-maintenance-automation-prompts.md rename plugins/repository-skills/skills/{maintain-project-docs => maintain-project-repo}/references/document-boundaries.md (100%) create mode 100644 plugins/repository-skills/skills/maintain-project-repo/references/project-docs-maintenance-automation-prompts.md rename {skills/maintain-project-docs => plugins/repository-skills/skills/maintain-project-repo}/scripts/maintain_project_docs.py (99%) delete mode 100644 skills/maintain-project-docs/SKILL.md delete mode 100644 skills/maintain-project-docs/agents/openai.yaml delete mode 100644 skills/maintain-project-docs/references/project-docs-maintenance-automation-prompts.md rename skills/{maintain-project-docs => maintain-project-repo}/references/document-boundaries.md (100%) create mode 100644 skills/maintain-project-repo/references/project-docs-maintenance-automation-prompts.md rename {plugins/repository-skills/skills/maintain-project-docs => skills/maintain-project-repo}/scripts/maintain_project_docs.py (99%) delete mode 100644 tests/test_repository_docs_workflow.py diff --git a/ROADMAP.md b/ROADMAP.md index 1447dc54e..b1e51b0ef 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1191,8 +1191,10 @@ and test/production deployments for GitHub Actions. - [x] Add `game-dev-skills:metalfx-game-rendering-workflow`, `metal-asset-streaming-workflow`, and `metal-neural-rendering-workflow` for native MetalFX integration, GPU asset residency/streaming, and carefully gated experimental neural rendering. - [x] Overhaul `agent-portability-skills` so its docs, tests, generated bootstrap content, and sync audit logic target Codex/OpenAI plus the open `.agents/skills` discovery mirror only. Remove stale expectations for retired child maintainer docs such as reality-audit and install-surface docs, and keep the wording away from unsupported non-Codex or generic multi-agent surfaces. - [x] Consolidate README, CONTRIBUTING, AGENTS, coordinated docs, and ROADMAP - maintenance workflows into `repository-skills` so repository operations and - repository documentation have one owner. + maintenance workflows into `repository-skills`, then absorb the coordinated + docs lifecycle into `maintain-project-repo` so every repository install, + refresh, and calling bootstrap creates or refreshes the canonical document + set without a parallel umbrella skill. - [x] Add a first `agent-engineering-skills:design-agent-automation-workflow` planning skill for agent and automation design. It chooses between Codex app automations, `codex exec`, Codex subagents, OpenAI Agents SDK services, LangGraph graphs, Hermes-specific workflows, or no automation yet while delegating stack-specific implementation to the owning plugin. - [x] Added `agent-engineering-skills:design-agent-eval-workflow` for agent, skill, prompt, and automation eval planning, and skewed automation guidance toward safe full automation with exact escalation gates instead of broad human review. - [x] Replaced the legacy Apple app guidance and sync routes with the unified `bootstrap-xcode-workspace` workflow and its managed `just align` contract. diff --git a/docs/maintainers/automation-suitability.md b/docs/maintainers/automation-suitability.md index 35cfaf2f3..3a130c985 100644 --- a/docs/maintainers/automation-suitability.md +++ b/docs/maintainers/automation-suitability.md @@ -154,7 +154,7 @@ as the default Socket maintainer automation runtime. | `maintain-project-agents` | `codex exec` for one repo; code-owned service for policy rollout | It changes durable agent instructions, so apply mode should be branch-and-PR gated. App automation is good for drift reports. | | `maintain-project-contributing` | `codex exec` for one repo; code-owned service for standardization campaigns | It owns contributor workflow. Good candidate for automated apply after check-only evidence. | | `maintain-project-readme` | `codex exec` for one repo; code-owned service for product-doc sweep | It keeps README product-focused and hands contributor details to `CONTRIBUTING.md`, which makes it safer for repeated repo-wide application. | -| `maintain-project-repo` | `codex exec` first; code-owned service for coordinated rollout | It installs managed scripts and CI wrappers. It is deterministic, but the write surface is broad enough that every repo should get a PR. | +| `maintain-project-repo` | `codex exec` first; code-owned service for coordinated rollout | It installs managed scripts and CI wrappers and creates or refreshes canonical project docs through their owner workflows. It is deterministic, but the write surface is broad enough that every repo should get a PR. | | `maintain-project-roadmap` | App check-only or `codex exec`; code-owned service only for planning sync | Roadmaps reflect human priorities. Automate stale-structure fixes, but keep milestone meaning human-reviewed. | | `bootstrap-xcode-workspace --operation align` | `codex exec` for one product workspace | It refreshes the one managed Apps/Packages/Services guidance boundary and repository maintenance surface without classifying the repository. | | `bootstrap-xcode-workspace --operation align` | `codex exec` for one repo; code-owned service for Apple-product workspace alignment | It safely owns only marked guidance, the managed hook, and marked Just recipes while preserving product-local content. | diff --git a/docs/maintainers/validation-and-test-audit.md b/docs/maintainers/validation-and-test-audit.md index 5db9f9b43..432693aa2 100644 --- a/docs/maintainers/validation-and-test-audit.md +++ b/docs/maintainers/validation-and-test-audit.md @@ -69,8 +69,7 @@ root and the root full profile already owns their checks. | `tests/test_model_lab_skill_contracts.py` | 9 | Protects current inventory/routing, authorization controls, experiment validation, paired comparison correctness, provenance stability, and version alignment. | | `tests/test_release_version.py` | 4 | Exercises target discovery, aligned SemVer calculation, split-version rejection, and atomic manifest/lockfile updates. | | `tests/test_release_workflow.py` | 10 | Exercises PR/check gating, branch ownership/accounting, version ordering, publication checks, evidence generation, and the single release CLI. | -| `tests/test_repository_docs_workflow.py` | 5 | Exercises coordinator selection, flag routing, responsibility drift detection, and structured error output. | -| `tests/test_repository_maintenance_workflow.py` | 21 | Exercises generated validation/release assets, profile installation, workspace dispatch, delayed GitHub state, prerelease metadata, notes selection, branch accounting, triggers, and preservation of repo-owned extensions. | +| `tests/test_repository_maintenance_workflow.py` | 29 | Exercises generated validation/release assets, mandatory documentation creation and refresh, non-mutating reports, owner dispatch, bootstrap integration, workspace dispatch, delayed GitHub state, prerelease metadata, notes selection, branch accounting, triggers, and preservation of repo-owned extensions. | | `tests/test_spi_add_package.py` | 10 | Exercises canonical URL/form construction, live form validation, package readiness, tag/toolchain checks, and the explicit prohibition on unauthorized alternate submission writes. | | `tests/test_swiftasb_skills_install.py` | 2 | Performs a real temporary Codex marketplace install and verifies the published .NET skill inventory. | | `tests/test_unified_swift_workspace_contracts.py` | 7 | Protects positive package/workspace context, component ownership, target layout, native-local/cloud deployment, immutable artifacts, and Soto lifecycle policy. | diff --git a/docs/releases/v10.0.2.md b/docs/releases/v10.0.2.md new file mode 100644 index 000000000..1327ca4b3 --- /dev/null +++ b/docs/releases/v10.0.2.md @@ -0,0 +1,40 @@ +# Socket v10.0.2 + +## Changes + +- Makes `repository-skills:maintain-project-repo` the coordinated owner for + repository tooling and canonical project documentation. +- Runs README, CONTRIBUTING, AGENTS, and ROADMAP creation or refresh during + every `maintain-project-repo` install and refresh, including repository + bootstraps that call the installer. +- Makes `report-only` and dry-run operations audit the same four documents + without writing them, and returns their owner reports and cross-document + responsibility findings in the repository workflow result. +- Treats missing README and ROADMAP files as reportable, auto-fixable findings, + matching the existing CONTRIBUTING and AGENTS behavior. + +## Breaking Changes + +- Removes the standalone `repository-skills:maintain-project-docs` skill. + Coordinated documentation sweeps now use `maintain-project-repo`; individual + document maintenance still uses the matching `maintain-project-readme`, + `maintain-project-contributing`, `maintain-project-agents`, or + `maintain-project-roadmap` owner. +- `maintain-project-repo --operation install|refresh` now creates or updates the + canonical documentation set as part of the same local operation. There is no + skip-docs compatibility path. + +## Upgrade + +- Replace coordinated `$maintain-project-docs` invocations with + `$maintain-project-repo`. +- Use `--operation report-only` for a non-mutating tooling and documentation + report, or `--operation refresh` to update both surfaces. +- Review the four canonical documents in the resulting branch or pull request, + because repository refreshes now include their bounded owner-workflow edits. + +## Verification + +- `uv run pytest tests/test_repository_maintenance_workflow.py tests/test_unified_swift_workspace_contracts.py -q` +- `uv run scripts/export_hermes_skills.py --check` +- `uv run scripts/validate_socket.py --profile compatibility` diff --git a/plugins/apple-dev-skills/skills/bootstrap-xcode-workspace/SKILL.md b/plugins/apple-dev-skills/skills/bootstrap-xcode-workspace/SKILL.md index 1cb3e327e..a4316d7ff 100644 --- a/plugins/apple-dev-skills/skills/bootstrap-xcode-workspace/SKILL.md +++ b/plugins/apple-dev-skills/skills/bootstrap-xcode-workspace/SKILL.md @@ -165,7 +165,9 @@ project migration entrypoint. - Hand service generation to `server-side-swift:workspace-service-component`; do not let the framework generator own or replace the product workspace. - Hand repository maintenance to `repository-skills:maintain-project-repo` with - the `xcode-workspace` profile. + the `xcode-workspace` profile. Its install operation also creates or refreshes + README.md, CONTRIBUTING.md, AGENTS.md, and ROADMAP.md through the canonical + document-owner workflows; do not add a second bootstrap-only docs path. - When Xcode-only state is required, use the root workspace and Xcode workflows; otherwise run the nearest package operation directly. diff --git a/plugins/repository-skills/skills/maintain-project-docs/SKILL.md b/plugins/repository-skills/skills/maintain-project-docs/SKILL.md deleted file mode 100644 index ced89515c..000000000 --- a/plugins/repository-skills/skills/maintain-project-docs/SKILL.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -name: maintain-project-docs -description: Coordinate maintenance across README.md, CONTRIBUTING.md, AGENTS.md, and ROADMAP.md. Use for a complete documentation sweep, ownership-boundary audit, repeated-content cleanup, or one coordinated project-docs pass. ---- - -# Maintain Project Docs - -Coordinate a complete project-docs sweep without collapsing the document-specific skills into one oversized workflow. - -This skill is the umbrella layer for repository documentation maintenance. It delegates canonical file audits and bounded edits to the owner skills, then checks whether content responsibilities are drifting across files. - -## Inputs - -- Required: `--project-root ` -- Required: `--run-mode ` -- Optional: `--include ` -- Optional: `--skip ` -- Optional: `--collect-source-tickets` -- Optional: `--collect-github-issues` -- Optional: `--github-repo ` - -## Workflow - -1. Validate the project root and choose the included document workflows. -2. Run the owner workflows serially in this order: README, CONTRIBUTING, - AGENTS, ROADMAP. -3. Pass `--collect-source-tickets`, `--collect-github-issues`, and `--github-repo` only to the roadmap workflow. -4. In `check-only`, report each owner workflow's findings plus cross-document responsibility issues. -5. In `apply`, let each owner workflow make only its own bounded file edits, then audit the resulting document set again. -6. Keep any cross-document moves, wording rewrites, or repeated-content cleanup in the main thread unless a future deterministic fixer owns those edits. - -## Responsibility Boundaries - -- `README.md`: product overview, status, quick start, usage, and short development pointer. -- `CONTRIBUTING.md`: human contributor workflow, setup, development expectations, PR expectations, and communication rules. -- `AGENTS.md`: durable agent-facing repo scope, routing, commands, review and delivery rules, and safety boundaries. -- `ROADMAP.md`: milestones, small tickets, TODO/FIXME imports, backlog planning, and notable roadmap history. - -When content belongs in another file, report the mismatch instead of copying or rewriting it silently. - -## Codex Subagent Fit - -When delegation is explicitly requested or authorized, follow `agent-engineering-skills:orchestrate-agent-work`. This skill is a good fit for `repo-docs-auditor`, review-packet planning, and broad repo-doc discovery before this skill coordinates owner docs workflows: checking docs for stale commands, comparing roadmap claims against repo evidence, inventorying nested `AGENTS.md` overrides, and finding cross-document responsibility drift. - -Keep `apply` edits in the main thread. The auditor may return proposed patch-set entries, but the main agent should review them with the user before saving, editing, or applying any documentation edits. - -## Output Contract - -- Return Markdown plus JSON with: - - `run_context` - - `document_order` - - `document_reports` - - `responsibility_issues` - - `fixes_applied` - - `post_fix_status` - - `errors` -- If there are no issues and no errors, output exactly `No findings.` - -## Guardrails - -- Never auto-commit, auto-push, or open a PR. -- Never invent project claims, commands, API behavior, roadmap scope, or agent policy. -- Never make broad cross-file rewrites as a side effect of running the umbrella workflow. -- Do not duplicate detailed rules across README, CONTRIBUTING, AGENTS, and - ROADMAP just to make each file self-contained. -- Treat this skill as an orchestrator. The owner document skills keep their own schemas, templates, and bounded apply behavior. - -## References - -- `agents/openai.yaml` -- `references/document-boundaries.md` -- `references/project-docs-maintenance-automation-prompts.md` -- `scripts/maintain_project_docs.py` diff --git a/plugins/repository-skills/skills/maintain-project-docs/agents/openai.yaml b/plugins/repository-skills/skills/maintain-project-docs/agents/openai.yaml deleted file mode 100644 index 72b3a66b9..000000000 --- a/plugins/repository-skills/skills/maintain-project-docs/agents/openai.yaml +++ /dev/null @@ -1,4 +0,0 @@ -interface: - display_name: "Maintain Project Docs" - short_description: "Run a coordinated docs sweep across README, CONTRIBUTING, AGENTS, optional API, and ROADMAP." - default_prompt: "Use $maintain-project-docs when a repository needs a complete documentation maintenance pass across README.md, CONTRIBUTING.md, AGENTS.md, and ROADMAP.md. Delegate each file to its owner maintenance skill, run the workflows serially, preserve the responsibility split between product docs, contributor workflow, agent guidance, and roadmap planning, and report cross-document drift instead of rewriting several files at once." diff --git a/plugins/repository-skills/skills/maintain-project-docs/references/project-docs-maintenance-automation-prompts.md b/plugins/repository-skills/skills/maintain-project-docs/references/project-docs-maintenance-automation-prompts.md deleted file mode 100644 index 73a6bfca7..000000000 --- a/plugins/repository-skills/skills/maintain-project-docs/references/project-docs-maintenance-automation-prompts.md +++ /dev/null @@ -1,25 +0,0 @@ -# Project Docs Maintenance Automation Prompts - -Use these prompts when scheduling or delegating recurring documentation sweeps. - -## Check-Only Sweep - -Run `maintain-project-docs` in `check-only` mode for the target repository. -Audit README, CONTRIBUTING, AGENTS, and ROADMAP in that order. Report -owner-skill findings, cross-document responsibility drift, stale command -evidence, and any roadmap small-ticket candidates requested by the operator. Do -not edit files, commit, push, or open a pull request. - -## Bounded Apply Sweep - -Run `maintain-project-docs` in `apply` mode only after the operator approves bounded file normalization. Let each owner document skill edit only its own target file. After apply, rerun the umbrella audit and report remaining cross-document issues separately from fixes already applied. Do not move content across files unless the operator explicitly requested that cleanup. - -## Subagent Discovery - -When the repository is large, ask subagents for read-only findings before the main thread edits: - -- one worker checks README and contributor docs for stale commands -- one worker checks AGENTS and nested guidance for routing or policy drift -- one worker checks ROADMAP and issue state for small-ticket candidates - -Require file references and concise evidence from each worker. The main thread owns the final edits and validation. diff --git a/plugins/repository-skills/skills/maintain-project-readme/scripts/maintain_project_readme.py b/plugins/repository-skills/skills/maintain-project-readme/scripts/maintain_project_readme.py index d21b8260b..fef06ca3d 100644 --- a/plugins/repository-skills/skills/maintain-project-readme/scripts/maintain_project_readme.py +++ b/plugins/repository-skills/skills/maintain-project-readme/scripts/maintain_project_readme.py @@ -830,8 +830,18 @@ def run_maintenance(args: argparse.Namespace) -> Tuple[Dict[str, Any], str]: elif args.run_mode == "apply": readme_text = "" else: - report["errors"].append(f"README path does not exist: {readme_path}") - return report, markdown_report(report) + readme_text = "" + report["schema_violations"] = [ + Issue( + issue_id="missing-readme-file", + category="schema", + severity="high", + file=str(readme_path), + evidence="README.md does not exist.", + recommended_fix="Create the canonical README.md file from the bundled template.", + auto_fixable=True, + ).to_dict() + ] if args.run_mode == "apply" and not report["errors"]: _updated_text, actions = apply_fixes(project_root, readme_path, readme_text, config) diff --git a/plugins/repository-skills/skills/maintain-project-repo/SKILL.md b/plugins/repository-skills/skills/maintain-project-repo/SKILL.md index ab7922db3..a10c0a9cf 100644 --- a/plugins/repository-skills/skills/maintain-project-repo/SKILL.md +++ b/plugins/repository-skills/skills/maintain-project-repo/SKILL.md @@ -1,32 +1,32 @@ --- name: maintain-project-repo -description: Install or refresh validation, sync, and release tooling. Use to release or publish a version, bump and tag a release, create the GitHub release, prepare a protected-main release, or finish release cleanup and branch accounting. +description: Install or refresh repository tooling and canonical project docs. Use for repository bootstrap or maintenance, coordinated README/CONTRIBUTING/AGENTS/ROADMAP updates, releases, tags, publication, or branch accounting. license: Apache-2.0 metadata: - semver: 0.2.1 + semver: 0.3.0 --- # Maintain Project Repo ## Purpose -Install or refresh the reusable `maintain-project-repo` toolkit inside a -general repository or a canonical Swift product workspace so validation, -shared-sync work, and release steps live in repo-owned local scripts rather than -CI-only glue. Callers select `generic` or `xcode-workspace` explicitly; this -workflow does not classify repository shape. +Install or refresh the reusable `maintain-project-repo` toolkit and canonical +project documentation inside a general repository or a canonical Swift product +workspace. Validation, shared-sync work, release steps, README, contributor +guidance, agent guidance, and roadmap planning stay aligned through one +repository lifecycle. Callers select `generic` or `xcode-workspace` explicitly; +this workflow does not classify repository shape. ## When To Use - Use this skill when a Swift or Xcode repo needs one local entrypoint for validation, shared sync work, and releases. - Use this skill when a repo has GitHub Actions or local shell helpers that should become thin wrappers around repo-owned scripts. +- Use this skill for a coordinated README.md, CONTRIBUTING.md, AGENTS.md, and ROADMAP.md maintenance pass. - Use this skill when a repo needs a protected-main standard release flow and a submodule-aware release flow. - Use this skill when the user asks to release or publish a version. -- Use this skill when the user asks to bump versions, tag a release, create a - GitHub release, prepare or merge a protected-main release, or finish release - cleanup and branch accounting. +- Use this skill when the user asks to bump and tag a release, create the GitHub release, prepare or merge a protected-main release, or finish release cleanup and branch accounting. - Use this skill when the user wants a local-first alternative to putting maintainer logic under `.github/scripts/`. -- Do not use this skill to make ordinary questions, investigations, local edits, or documentation maintenance take a full PR, CI, release, tag, and cleanup path. +- Do not use this skill to make ordinary questions, investigations, local edits, or documentation maintenance take a full PR, CI, release, tag, and cleanup path. Repository installation, refresh, and documentation maintenance remain local operations unless the user separately requests delivery or release work. - Do not run or recommend the release choreography unless the user is actually asking to release, publish, merge, tag, open a release PR, or prepare the repo for that protected-main release workflow. - Do not use this skill for app bootstrap, Swift package bootstrap, or AGENTS-only guidance sync by themselves. - Recommend `bootstrap-xcode-workspace --operation create --component-kind library` when the repo does not exist yet and package scaffold creation is still the primary task. @@ -69,16 +69,23 @@ workflow does not classify repository shape. `Scripts/repo-maintenance/` toolkit root to lowercase `scripts/repo-maintenance/`; stop if both roots exist separately - preserve repo-specific scripts or files that are not part of the managed file set -6. Verify the installed `maintain-project-repo` files: +6. Maintain canonical project documentation as part of the same operation: + - `install` and `refresh` run the README, CONTRIBUTING, AGENTS, and ROADMAP owner workflows serially in `apply` mode + - `report-only` and `--dry-run` run the same document workflows in `check-only` mode and never write documentation + - create missing canonical documents from the owner workflow templates + - preserve the responsibility split between product docs, contributor workflow, agent guidance, and roadmap planning + - report cross-document responsibility drift without silently moving content between files + - never offer a skip-docs path: every repository install or refresh owns the corresponding documentation pass +7. Verify the installed `maintain-project-repo` files and documentation result: - `scripts/repo-maintenance/*.sh` for every profile - `.github/workflows/validate-repo-maintenance.yml` when workflow installation is enabled - branch protection, when enabled, requires the GitHub Actions check context `validate`; do not require the display-style string `Validate Repo Maintenance / validate` -7. Hand off GitHub repository settings work: +8. Hand off GitHub repository settings work: - use `maintain-github-repository` for repository features, merge methods, Dependabot, secret scanning, push protection, vulnerability reporting, sign-off policy, branch protection, and rulesets - keep settings alignment separate from release choreography -8. Hand off follow-on work cleanly: +9. Hand off follow-on work cleanly: - use the selected profile's `validate-all.sh` for local validation - use the selected profile's `sync-shared.sh` for repo-local shared sync tasks - use the selected profile's `release.sh --mode standard --operation prepare` from a feature branch or worktree when protected `main` owns the final release line @@ -103,6 +110,7 @@ workflow does not classify repository shape. - `operation=install` - `profile=generic` - GitHub workflow installation is enabled unless explicitly skipped + - documentation mode is derived from the repository operation and cannot be skipped: `apply` for install/refresh and `check-only` for report-only/dry-run ## Outputs @@ -119,6 +127,7 @@ workflow does not classify repository shape. - selected profile - managed file list - planned or applied actions + - integrated documentation report with document order, owner reports, responsibility issues, fixes, post-fix status, and errors - one concise next step ## Guards and Stop Conditions @@ -127,10 +136,12 @@ workflow does not classify repository shape. - Stop with `blocked` if the repo root is not a directory. - Stop with `blocked` if the managed target paths are blocked by non-regular files that cannot be updated safely. - Stop with `blocked` if the requested operation is unsupported. +- Return `failed` when any selected document owner workflow errors after the repository installer starts; report completed actions explicitly so a partial write is never presented as atomic success. ## Fallbacks and Handoffs - `report-only` is the non-mutating fallback path. +- Documentation is a required repository lifecycle surface. Do not add a compatibility switch that refreshes tooling while leaving README.md, CONTRIBUTING.md, AGENTS.md, or ROADMAP.md outside the operation. - The installer preserves repo-specific extra files under the selected profile's repo-maintenance root, `.github/workflows/`, and adjacent surfaces when they are not part of the managed file set. - The installer keeps the selected `maintain-project-repo` profile explicit via the selected profile's `config/profile.env`. - The installer does not write repository-local Git defaults. Its release script @@ -168,6 +179,7 @@ When a repo needs Codex Hooks guidance, record that hooks are enabled by default ### Workflow References +- `references/document-boundaries.md` - `references/repo-maintenance-layout.md` - `references/release-modes.md` - `references/pre-commit-vs-ci.md` @@ -176,6 +188,7 @@ When a repo needs Codex Hooks guidance, record that hooks are enabled by default ### Contract References - `references/automation-prompts.md` +- `references/project-docs-maintenance-automation-prompts.md` - `references/customization-flow.md` ### Support References @@ -187,4 +200,5 @@ When a repo needs Codex Hooks guidance, record that hooks are enabled by default - `scripts/run_workflow.py` - `scripts/install_maintain_project_repo.py` +- `scripts/maintain_project_docs.py` - `scripts/customization_config.py` diff --git a/plugins/repository-skills/skills/maintain-project-repo/agents/openai.yaml b/plugins/repository-skills/skills/maintain-project-repo/agents/openai.yaml index 15e25fa44..e5b4fd95e 100644 --- a/plugins/repository-skills/skills/maintain-project-repo/agents/openai.yaml +++ b/plugins/repository-skills/skills/maintain-project-repo/agents/openai.yaml @@ -1,4 +1,4 @@ interface: display_name: "Maintain Project Repo" - short_description: "Install repo tooling or run protected-main releases" - default_prompt: "Use $maintain-project-repo to install or refresh repo-owned validation, sync, and release tooling, or to execute an explicitly requested protected-main release, publish, tag, GitHub release, cleanup, and branch-accounting workflow." + short_description: "Maintain repo tooling, docs, and releases" + default_prompt: "Use $maintain-project-repo to install or refresh repo-owned validation, sync, release tooling, and canonical README, CONTRIBUTING, AGENTS, and ROADMAP docs, or to execute an explicitly requested protected-main release, publish, tag, GitHub release, cleanup, and branch-accounting workflow." diff --git a/plugins/repository-skills/skills/maintain-project-repo/references/automation-prompts.md b/plugins/repository-skills/skills/maintain-project-repo/references/automation-prompts.md index 814554144..2b095be28 100644 --- a/plugins/repository-skills/skills/maintain-project-repo/references/automation-prompts.md +++ b/plugins/repository-skills/skills/maintain-project-repo/references/automation-prompts.md @@ -1,8 +1,8 @@ # Repo Maintenance Toolkit Automation Prompts -- Install `maintain-project-repo` into `` and keep the GitHub workflow wrapper enabled. -- Refresh `maintain-project-repo` in `` without deleting repo-specific custom scripts. -- Report what `maintain-project-repo` would install into `` without mutating files. +- Install `maintain-project-repo` into ``, keep the GitHub workflow wrapper enabled, and create or normalize README.md, CONTRIBUTING.md, AGENTS.md, and ROADMAP.md in the same operation. +- Refresh `maintain-project-repo` in `` without deleting repo-specific custom scripts, then refresh the four canonical project documents through their owner workflows. +- Report what `maintain-project-repo` would install and which documentation findings remain in `` without mutating files. - Explain when to use `scripts/repo-maintenance/validate-all.sh`, `scripts/repo-maintenance/sync-shared.sh`, and `scripts/repo-maintenance/release.sh`. - Explain that standard release mode runs from a feature branch or worktree, opens a PR against protected `main`, takes bounded CI/review snapshots through `prepare`, `inspect`, and `advance`, gates on PR comments, merges, fast-forwards local `main`, creates and pushes the tag from that reviewed `main`, creates the GitHub release, accounts for every local branch not contained by `main`, and only then cleans up branches that are proven safe to delete. - Explain that branch cleanup is gated by commit reachability: do not call work on `main`, merged, recovered, preserved, or safe to clean up until the exact local repository and remote prove it, and do not delete local branches, remote branches, worktrees, archive refs, or temporary rescue refs until any non-base history is merged or explicitly archived. diff --git a/plugins/repository-skills/skills/maintain-project-docs/references/document-boundaries.md b/plugins/repository-skills/skills/maintain-project-repo/references/document-boundaries.md similarity index 100% rename from plugins/repository-skills/skills/maintain-project-docs/references/document-boundaries.md rename to plugins/repository-skills/skills/maintain-project-repo/references/document-boundaries.md diff --git a/plugins/repository-skills/skills/maintain-project-repo/references/project-docs-maintenance-automation-prompts.md b/plugins/repository-skills/skills/maintain-project-repo/references/project-docs-maintenance-automation-prompts.md new file mode 100644 index 000000000..9d4545d1b --- /dev/null +++ b/plugins/repository-skills/skills/maintain-project-repo/references/project-docs-maintenance-automation-prompts.md @@ -0,0 +1,30 @@ +# Project Docs Maintenance Automation Prompts + +Use these prompts when scheduling or delegating the documentation phase owned by +`maintain-project-repo`. + +## Check-Only Sweep + +Run `maintain-project-repo --operation report-only` for the target repository. +Report the planned toolkit actions and audit README, CONTRIBUTING, AGENTS, and +ROADMAP in that order. Include owner-skill findings, cross-document +responsibility drift, and stale command evidence. Do not edit files, commit, +push, or open a pull request. + +## Bounded Apply Sweep + +Run `maintain-project-repo --operation refresh` after the operator approves the +repository refresh. Let each owner document workflow edit only its own target +file. Report remaining cross-document issues separately from fixes already +applied. Do not move content across files unless the operator explicitly +requested that cleanup. + +## Subagent Discovery + +When the repository is large, ask subagents for read-only findings before the main thread edits: + +- one worker checks README and contributor docs for stale commands +- one worker checks AGENTS and nested guidance for routing or policy drift +- one worker checks ROADMAP and issue state for small-ticket candidates + +Require file references and concise evidence from each worker. The main thread owns the final edits and validation. diff --git a/plugins/repository-skills/skills/maintain-project-repo/references/trigger-eval.md b/plugins/repository-skills/skills/maintain-project-repo/references/trigger-eval.md index b193c7378..7e20b0047 100644 --- a/plugins/repository-skills/skills/maintain-project-repo/references/trigger-eval.md +++ b/plugins/repository-skills/skills/maintain-project-repo/references/trigger-eval.md @@ -9,6 +9,8 @@ - Run the release workflow and clean up the merged branch. - Install the repo-maintenance toolkit. - Refresh our validation, sync, and release scripts. +- Bootstrap this repository and create its canonical project docs. +- Run a coordinated README, CONTRIBUTING, AGENTS, and ROADMAP refresh. - Use the checked-in release notes for this patch release. ## Should Not Trigger @@ -26,6 +28,7 @@ - GitHub repository settings audit and alignment route to `maintain-github-repository`. -- Ordinary documentation work routes to the owning document-maintenance skill. +- Ordinary single-document work routes to the owning document-maintenance skill; + coordinated project-doc maintenance routes to `maintain-project-repo`. - Ordinary local Git work follows repo-local Git guidance without invoking the full release lifecycle. diff --git a/skills/maintain-project-docs/scripts/maintain_project_docs.py b/plugins/repository-skills/skills/maintain-project-repo/scripts/maintain_project_docs.py similarity index 99% rename from skills/maintain-project-docs/scripts/maintain_project_docs.py rename to plugins/repository-skills/skills/maintain-project-repo/scripts/maintain_project_docs.py index 50b4b2521..f3409aedf 100644 --- a/skills/maintain-project-docs/scripts/maintain_project_docs.py +++ b/plugins/repository-skills/skills/maintain-project-repo/scripts/maintain_project_docs.py @@ -308,7 +308,7 @@ def child_fixes(child: Dict[str, Any]) -> List[Dict[str, Any]]: report = child.get("report") if not isinstance(report, dict): return [] - fixes = report.get("fixes_applied", []) + fixes = report.get("fixes_applied", report.get("apply_actions", [])) return fixes if isinstance(fixes, list) else [] diff --git a/plugins/repository-skills/skills/maintain-project-repo/scripts/run_workflow.py b/plugins/repository-skills/skills/maintain-project-repo/scripts/run_workflow.py index a786f7ca6..dbb21ae8e 100755 --- a/plugins/repository-skills/skills/maintain-project-repo/scripts/run_workflow.py +++ b/plugins/repository-skills/skills/maintain-project-repo/scripts/run_workflow.py @@ -5,14 +5,16 @@ # "PyYAML>=6.0.2,<7", # ] # /// -"""Unified runtime entrypoint for maintain-project-repo.""" +"""Install or refresh repository tooling and canonical project documentation.""" from __future__ import annotations import argparse import json import subprocess +import sys from pathlib import Path +from typing import Any def build_parser() -> argparse.ArgumentParser: @@ -25,6 +27,44 @@ def build_parser() -> argparse.ArgumentParser: return parser +def decode_payload(proc: subprocess.CompletedProcess[str], fallback: dict[str, Any]) -> dict[str, Any]: + if not proc.stdout.strip(): + return fallback + try: + payload = json.loads(proc.stdout) + except json.JSONDecodeError: + return { + **fallback, + "stdout": proc.stdout, + "stderr": proc.stderr, + } + return payload if isinstance(payload, dict) else fallback + + +def run_documentation(repo_root: str, run_mode: str) -> tuple[int, dict[str, Any], str]: + helper_path = Path(__file__).with_name("maintain_project_docs.py") + command = [ + sys.executable, + str(helper_path), + "--project-root", + repo_root, + "--run-mode", + run_mode, + "--print-json", + ] + proc = subprocess.run(command, capture_output=True, text=True, check=False) + fallback = { + "run_context": {"project_root": repo_root, "run_mode": run_mode}, + "document_order": [], + "document_reports": [], + "responsibility_issues": [], + "fixes_applied": [], + "post_fix_status": [], + "errors": ["The integrated documentation workflow did not return JSON output."], + } + return proc.returncode, decode_payload(proc, fallback), proc.stderr.strip() + + def main() -> int: args = build_parser().parse_args() repo_root = str(Path(args.repo_root or ".").expanduser().resolve()) @@ -54,7 +94,8 @@ def main() -> int: command.append("--dry-run") proc = subprocess.run(command, capture_output=True, text=True, check=False) - payload = json.loads(proc.stdout) if proc.stdout.strip() else { + return_code = proc.returncode + payload = decode_payload(proc, { "status": "failed", "path_type": "primary", "repo_root": repo_root, @@ -65,10 +106,38 @@ def main() -> int: "stdout": proc.stdout, "stderr": proc.stderr, "next_step": "Fix the maintain-project-repo workflow error and rerun the workflow.", - } + }) payload.setdefault("normalized_inputs", normalized_inputs) + if proc.returncode == 0: + documentation_mode = ( + "check-only" + if operation == "report-only" or args.dry_run + else "apply" + ) + docs_code, docs_payload, docs_stderr = run_documentation( + repo_root, documentation_mode + ) + payload["documentation"] = docs_payload + payload["documentation_result"] = ( + "checked (no writes)" + if documentation_mode == "check-only" + else "canonical documents created or refreshed" + ) + if docs_code != 0: + payload["status"] = "failed" + payload["documentation_result"] = "failed after toolkit update" + existing_stderr = str(payload.get("stderr", "")).strip() + details = docs_stderr or "The integrated documentation workflow failed." + payload["stderr"] = "\n".join( + part for part in (existing_stderr, details) if part + ) + payload["next_step"] = ( + "Fix the reported documentation workflow error and rerun " + "maintain-project-repo so tooling and canonical docs agree." + ) + return_code = 1 print(json.dumps(payload, indent=2, sort_keys=True)) - return 0 if proc.returncode == 0 else 1 + return 0 if return_code == 0 else 1 if __name__ == "__main__": diff --git a/plugins/repository-skills/skills/maintain-project-roadmap/scripts/maintain_project_roadmap.py b/plugins/repository-skills/skills/maintain-project-roadmap/scripts/maintain_project_roadmap.py index f7a98506e..b1228cd66 100644 --- a/plugins/repository-skills/skills/maintain-project-roadmap/scripts/maintain_project_roadmap.py +++ b/plugins/repository-skills/skills/maintain-project-roadmap/scripts/maintain_project_roadmap.py @@ -1551,8 +1551,17 @@ def run_maintenance(args: argparse.Namespace) -> Tuple[Dict[str, Any], str]: ).to_dict() ] else: - report["errors"].append(f"ROADMAP path does not exist: {roadmap_path}") - return report, markdown_report(report) + roadmap_text = "" + report["findings"] = [ + Finding( + finding_id="missing-roadmap", + category="schema", + severity="high", + message=f"ROADMAP file is missing at {roadmap_path}.", + file=str(roadmap_path), + auto_fixable=True, + ).to_dict() + ] small_ticket_candidates: List[SmallTicketCandidate] = [] if args.collect_source_tickets: diff --git a/plugins/repository-skills/skills/repository-operations-workflow/SKILL.md b/plugins/repository-skills/skills/repository-operations-workflow/SKILL.md index c278a19b6..20715dfe3 100644 --- a/plugins/repository-skills/skills/repository-operations-workflow/SKILL.md +++ b/plugins/repository-skills/skills/repository-operations-workflow/SKILL.md @@ -24,8 +24,8 @@ needed for that classification, then hand work to the narrowest owner. | Codex worktree mode, local environment, or app-owned worktree behavior | `codex-gui-worktree-workflow` | | Parallel worker branch, worktree, write, or integration ownership | `coordinate-worktrees-and-threads` | | GitHub settings, rulesets, security automation, or repository policy | `maintain-github-repository` | - | README, CONTRIBUTING, AGENTS, or ROADMAP maintenance | The matching `maintain-project-*` document workflow | - | Coordinated repository-document sweep | `maintain-project-docs` | + | One README, CONTRIBUTING, AGENTS, or ROADMAP maintenance task | The matching `maintain-project-*` document workflow | + | Coordinated repository-document sweep, repository bootstrap, or repository refresh | `maintain-project-repo` | | Version bump, tag, release, publication, or branch-accounting cleanup | `maintain-project-repo` | 3. When the request crosses multiple outcomes, name the sequence and keep each mutation with its owning workflow. For example: select a worktree, make a diff --git a/scripts/export_hermes_skills.py b/scripts/export_hermes_skills.py index 33fa5ff2f..ea51afb9d 100644 --- a/scripts/export_hermes_skills.py +++ b/scripts/export_hermes_skills.py @@ -177,7 +177,6 @@ "maintain-github-repository", "maintain-project-agents", "maintain-project-contributing", - "maintain-project-docs", "maintain-project-readme", "maintain-project-repo", "maintain-project-roadmap", diff --git a/skills.sh.json b/skills.sh.json index 5f9e48e89..5ff51e9e8 100644 --- a/skills.sh.json +++ b/skills.sh.json @@ -191,7 +191,6 @@ "maintain-github-repository", "maintain-project-agents", "maintain-project-contributing", - "maintain-project-docs", "maintain-project-readme", "maintain-project-repo", "maintain-project-roadmap" diff --git a/skills/bootstrap-xcode-workspace/SKILL.md b/skills/bootstrap-xcode-workspace/SKILL.md index 1cb3e327e..a4316d7ff 100644 --- a/skills/bootstrap-xcode-workspace/SKILL.md +++ b/skills/bootstrap-xcode-workspace/SKILL.md @@ -165,7 +165,9 @@ project migration entrypoint. - Hand service generation to `server-side-swift:workspace-service-component`; do not let the framework generator own or replace the product workspace. - Hand repository maintenance to `repository-skills:maintain-project-repo` with - the `xcode-workspace` profile. + the `xcode-workspace` profile. Its install operation also creates or refreshes + README.md, CONTRIBUTING.md, AGENTS.md, and ROADMAP.md through the canonical + document-owner workflows; do not add a second bootstrap-only docs path. - When Xcode-only state is required, use the root workspace and Xcode workflows; otherwise run the nearest package operation directly. diff --git a/skills/maintain-project-docs/SKILL.md b/skills/maintain-project-docs/SKILL.md deleted file mode 100644 index ced89515c..000000000 --- a/skills/maintain-project-docs/SKILL.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -name: maintain-project-docs -description: Coordinate maintenance across README.md, CONTRIBUTING.md, AGENTS.md, and ROADMAP.md. Use for a complete documentation sweep, ownership-boundary audit, repeated-content cleanup, or one coordinated project-docs pass. ---- - -# Maintain Project Docs - -Coordinate a complete project-docs sweep without collapsing the document-specific skills into one oversized workflow. - -This skill is the umbrella layer for repository documentation maintenance. It delegates canonical file audits and bounded edits to the owner skills, then checks whether content responsibilities are drifting across files. - -## Inputs - -- Required: `--project-root ` -- Required: `--run-mode ` -- Optional: `--include ` -- Optional: `--skip ` -- Optional: `--collect-source-tickets` -- Optional: `--collect-github-issues` -- Optional: `--github-repo ` - -## Workflow - -1. Validate the project root and choose the included document workflows. -2. Run the owner workflows serially in this order: README, CONTRIBUTING, - AGENTS, ROADMAP. -3. Pass `--collect-source-tickets`, `--collect-github-issues`, and `--github-repo` only to the roadmap workflow. -4. In `check-only`, report each owner workflow's findings plus cross-document responsibility issues. -5. In `apply`, let each owner workflow make only its own bounded file edits, then audit the resulting document set again. -6. Keep any cross-document moves, wording rewrites, or repeated-content cleanup in the main thread unless a future deterministic fixer owns those edits. - -## Responsibility Boundaries - -- `README.md`: product overview, status, quick start, usage, and short development pointer. -- `CONTRIBUTING.md`: human contributor workflow, setup, development expectations, PR expectations, and communication rules. -- `AGENTS.md`: durable agent-facing repo scope, routing, commands, review and delivery rules, and safety boundaries. -- `ROADMAP.md`: milestones, small tickets, TODO/FIXME imports, backlog planning, and notable roadmap history. - -When content belongs in another file, report the mismatch instead of copying or rewriting it silently. - -## Codex Subagent Fit - -When delegation is explicitly requested or authorized, follow `agent-engineering-skills:orchestrate-agent-work`. This skill is a good fit for `repo-docs-auditor`, review-packet planning, and broad repo-doc discovery before this skill coordinates owner docs workflows: checking docs for stale commands, comparing roadmap claims against repo evidence, inventorying nested `AGENTS.md` overrides, and finding cross-document responsibility drift. - -Keep `apply` edits in the main thread. The auditor may return proposed patch-set entries, but the main agent should review them with the user before saving, editing, or applying any documentation edits. - -## Output Contract - -- Return Markdown plus JSON with: - - `run_context` - - `document_order` - - `document_reports` - - `responsibility_issues` - - `fixes_applied` - - `post_fix_status` - - `errors` -- If there are no issues and no errors, output exactly `No findings.` - -## Guardrails - -- Never auto-commit, auto-push, or open a PR. -- Never invent project claims, commands, API behavior, roadmap scope, or agent policy. -- Never make broad cross-file rewrites as a side effect of running the umbrella workflow. -- Do not duplicate detailed rules across README, CONTRIBUTING, AGENTS, and - ROADMAP just to make each file self-contained. -- Treat this skill as an orchestrator. The owner document skills keep their own schemas, templates, and bounded apply behavior. - -## References - -- `agents/openai.yaml` -- `references/document-boundaries.md` -- `references/project-docs-maintenance-automation-prompts.md` -- `scripts/maintain_project_docs.py` diff --git a/skills/maintain-project-docs/agents/openai.yaml b/skills/maintain-project-docs/agents/openai.yaml deleted file mode 100644 index 72b3a66b9..000000000 --- a/skills/maintain-project-docs/agents/openai.yaml +++ /dev/null @@ -1,4 +0,0 @@ -interface: - display_name: "Maintain Project Docs" - short_description: "Run a coordinated docs sweep across README, CONTRIBUTING, AGENTS, optional API, and ROADMAP." - default_prompt: "Use $maintain-project-docs when a repository needs a complete documentation maintenance pass across README.md, CONTRIBUTING.md, AGENTS.md, and ROADMAP.md. Delegate each file to its owner maintenance skill, run the workflows serially, preserve the responsibility split between product docs, contributor workflow, agent guidance, and roadmap planning, and report cross-document drift instead of rewriting several files at once." diff --git a/skills/maintain-project-docs/references/project-docs-maintenance-automation-prompts.md b/skills/maintain-project-docs/references/project-docs-maintenance-automation-prompts.md deleted file mode 100644 index 73a6bfca7..000000000 --- a/skills/maintain-project-docs/references/project-docs-maintenance-automation-prompts.md +++ /dev/null @@ -1,25 +0,0 @@ -# Project Docs Maintenance Automation Prompts - -Use these prompts when scheduling or delegating recurring documentation sweeps. - -## Check-Only Sweep - -Run `maintain-project-docs` in `check-only` mode for the target repository. -Audit README, CONTRIBUTING, AGENTS, and ROADMAP in that order. Report -owner-skill findings, cross-document responsibility drift, stale command -evidence, and any roadmap small-ticket candidates requested by the operator. Do -not edit files, commit, push, or open a pull request. - -## Bounded Apply Sweep - -Run `maintain-project-docs` in `apply` mode only after the operator approves bounded file normalization. Let each owner document skill edit only its own target file. After apply, rerun the umbrella audit and report remaining cross-document issues separately from fixes already applied. Do not move content across files unless the operator explicitly requested that cleanup. - -## Subagent Discovery - -When the repository is large, ask subagents for read-only findings before the main thread edits: - -- one worker checks README and contributor docs for stale commands -- one worker checks AGENTS and nested guidance for routing or policy drift -- one worker checks ROADMAP and issue state for small-ticket candidates - -Require file references and concise evidence from each worker. The main thread owns the final edits and validation. diff --git a/skills/maintain-project-readme/scripts/maintain_project_readme.py b/skills/maintain-project-readme/scripts/maintain_project_readme.py index d21b8260b..fef06ca3d 100644 --- a/skills/maintain-project-readme/scripts/maintain_project_readme.py +++ b/skills/maintain-project-readme/scripts/maintain_project_readme.py @@ -830,8 +830,18 @@ def run_maintenance(args: argparse.Namespace) -> Tuple[Dict[str, Any], str]: elif args.run_mode == "apply": readme_text = "" else: - report["errors"].append(f"README path does not exist: {readme_path}") - return report, markdown_report(report) + readme_text = "" + report["schema_violations"] = [ + Issue( + issue_id="missing-readme-file", + category="schema", + severity="high", + file=str(readme_path), + evidence="README.md does not exist.", + recommended_fix="Create the canonical README.md file from the bundled template.", + auto_fixable=True, + ).to_dict() + ] if args.run_mode == "apply" and not report["errors"]: _updated_text, actions = apply_fixes(project_root, readme_path, readme_text, config) diff --git a/skills/maintain-project-repo/SKILL.md b/skills/maintain-project-repo/SKILL.md index ab7922db3..a10c0a9cf 100644 --- a/skills/maintain-project-repo/SKILL.md +++ b/skills/maintain-project-repo/SKILL.md @@ -1,32 +1,32 @@ --- name: maintain-project-repo -description: Install or refresh validation, sync, and release tooling. Use to release or publish a version, bump and tag a release, create the GitHub release, prepare a protected-main release, or finish release cleanup and branch accounting. +description: Install or refresh repository tooling and canonical project docs. Use for repository bootstrap or maintenance, coordinated README/CONTRIBUTING/AGENTS/ROADMAP updates, releases, tags, publication, or branch accounting. license: Apache-2.0 metadata: - semver: 0.2.1 + semver: 0.3.0 --- # Maintain Project Repo ## Purpose -Install or refresh the reusable `maintain-project-repo` toolkit inside a -general repository or a canonical Swift product workspace so validation, -shared-sync work, and release steps live in repo-owned local scripts rather than -CI-only glue. Callers select `generic` or `xcode-workspace` explicitly; this -workflow does not classify repository shape. +Install or refresh the reusable `maintain-project-repo` toolkit and canonical +project documentation inside a general repository or a canonical Swift product +workspace. Validation, shared-sync work, release steps, README, contributor +guidance, agent guidance, and roadmap planning stay aligned through one +repository lifecycle. Callers select `generic` or `xcode-workspace` explicitly; +this workflow does not classify repository shape. ## When To Use - Use this skill when a Swift or Xcode repo needs one local entrypoint for validation, shared sync work, and releases. - Use this skill when a repo has GitHub Actions or local shell helpers that should become thin wrappers around repo-owned scripts. +- Use this skill for a coordinated README.md, CONTRIBUTING.md, AGENTS.md, and ROADMAP.md maintenance pass. - Use this skill when a repo needs a protected-main standard release flow and a submodule-aware release flow. - Use this skill when the user asks to release or publish a version. -- Use this skill when the user asks to bump versions, tag a release, create a - GitHub release, prepare or merge a protected-main release, or finish release - cleanup and branch accounting. +- Use this skill when the user asks to bump and tag a release, create the GitHub release, prepare or merge a protected-main release, or finish release cleanup and branch accounting. - Use this skill when the user wants a local-first alternative to putting maintainer logic under `.github/scripts/`. -- Do not use this skill to make ordinary questions, investigations, local edits, or documentation maintenance take a full PR, CI, release, tag, and cleanup path. +- Do not use this skill to make ordinary questions, investigations, local edits, or documentation maintenance take a full PR, CI, release, tag, and cleanup path. Repository installation, refresh, and documentation maintenance remain local operations unless the user separately requests delivery or release work. - Do not run or recommend the release choreography unless the user is actually asking to release, publish, merge, tag, open a release PR, or prepare the repo for that protected-main release workflow. - Do not use this skill for app bootstrap, Swift package bootstrap, or AGENTS-only guidance sync by themselves. - Recommend `bootstrap-xcode-workspace --operation create --component-kind library` when the repo does not exist yet and package scaffold creation is still the primary task. @@ -69,16 +69,23 @@ workflow does not classify repository shape. `Scripts/repo-maintenance/` toolkit root to lowercase `scripts/repo-maintenance/`; stop if both roots exist separately - preserve repo-specific scripts or files that are not part of the managed file set -6. Verify the installed `maintain-project-repo` files: +6. Maintain canonical project documentation as part of the same operation: + - `install` and `refresh` run the README, CONTRIBUTING, AGENTS, and ROADMAP owner workflows serially in `apply` mode + - `report-only` and `--dry-run` run the same document workflows in `check-only` mode and never write documentation + - create missing canonical documents from the owner workflow templates + - preserve the responsibility split between product docs, contributor workflow, agent guidance, and roadmap planning + - report cross-document responsibility drift without silently moving content between files + - never offer a skip-docs path: every repository install or refresh owns the corresponding documentation pass +7. Verify the installed `maintain-project-repo` files and documentation result: - `scripts/repo-maintenance/*.sh` for every profile - `.github/workflows/validate-repo-maintenance.yml` when workflow installation is enabled - branch protection, when enabled, requires the GitHub Actions check context `validate`; do not require the display-style string `Validate Repo Maintenance / validate` -7. Hand off GitHub repository settings work: +8. Hand off GitHub repository settings work: - use `maintain-github-repository` for repository features, merge methods, Dependabot, secret scanning, push protection, vulnerability reporting, sign-off policy, branch protection, and rulesets - keep settings alignment separate from release choreography -8. Hand off follow-on work cleanly: +9. Hand off follow-on work cleanly: - use the selected profile's `validate-all.sh` for local validation - use the selected profile's `sync-shared.sh` for repo-local shared sync tasks - use the selected profile's `release.sh --mode standard --operation prepare` from a feature branch or worktree when protected `main` owns the final release line @@ -103,6 +110,7 @@ workflow does not classify repository shape. - `operation=install` - `profile=generic` - GitHub workflow installation is enabled unless explicitly skipped + - documentation mode is derived from the repository operation and cannot be skipped: `apply` for install/refresh and `check-only` for report-only/dry-run ## Outputs @@ -119,6 +127,7 @@ workflow does not classify repository shape. - selected profile - managed file list - planned or applied actions + - integrated documentation report with document order, owner reports, responsibility issues, fixes, post-fix status, and errors - one concise next step ## Guards and Stop Conditions @@ -127,10 +136,12 @@ workflow does not classify repository shape. - Stop with `blocked` if the repo root is not a directory. - Stop with `blocked` if the managed target paths are blocked by non-regular files that cannot be updated safely. - Stop with `blocked` if the requested operation is unsupported. +- Return `failed` when any selected document owner workflow errors after the repository installer starts; report completed actions explicitly so a partial write is never presented as atomic success. ## Fallbacks and Handoffs - `report-only` is the non-mutating fallback path. +- Documentation is a required repository lifecycle surface. Do not add a compatibility switch that refreshes tooling while leaving README.md, CONTRIBUTING.md, AGENTS.md, or ROADMAP.md outside the operation. - The installer preserves repo-specific extra files under the selected profile's repo-maintenance root, `.github/workflows/`, and adjacent surfaces when they are not part of the managed file set. - The installer keeps the selected `maintain-project-repo` profile explicit via the selected profile's `config/profile.env`. - The installer does not write repository-local Git defaults. Its release script @@ -168,6 +179,7 @@ When a repo needs Codex Hooks guidance, record that hooks are enabled by default ### Workflow References +- `references/document-boundaries.md` - `references/repo-maintenance-layout.md` - `references/release-modes.md` - `references/pre-commit-vs-ci.md` @@ -176,6 +188,7 @@ When a repo needs Codex Hooks guidance, record that hooks are enabled by default ### Contract References - `references/automation-prompts.md` +- `references/project-docs-maintenance-automation-prompts.md` - `references/customization-flow.md` ### Support References @@ -187,4 +200,5 @@ When a repo needs Codex Hooks guidance, record that hooks are enabled by default - `scripts/run_workflow.py` - `scripts/install_maintain_project_repo.py` +- `scripts/maintain_project_docs.py` - `scripts/customization_config.py` diff --git a/skills/maintain-project-repo/agents/openai.yaml b/skills/maintain-project-repo/agents/openai.yaml index 15e25fa44..e5b4fd95e 100644 --- a/skills/maintain-project-repo/agents/openai.yaml +++ b/skills/maintain-project-repo/agents/openai.yaml @@ -1,4 +1,4 @@ interface: display_name: "Maintain Project Repo" - short_description: "Install repo tooling or run protected-main releases" - default_prompt: "Use $maintain-project-repo to install or refresh repo-owned validation, sync, and release tooling, or to execute an explicitly requested protected-main release, publish, tag, GitHub release, cleanup, and branch-accounting workflow." + short_description: "Maintain repo tooling, docs, and releases" + default_prompt: "Use $maintain-project-repo to install or refresh repo-owned validation, sync, release tooling, and canonical README, CONTRIBUTING, AGENTS, and ROADMAP docs, or to execute an explicitly requested protected-main release, publish, tag, GitHub release, cleanup, and branch-accounting workflow." diff --git a/skills/maintain-project-repo/references/automation-prompts.md b/skills/maintain-project-repo/references/automation-prompts.md index 814554144..2b095be28 100644 --- a/skills/maintain-project-repo/references/automation-prompts.md +++ b/skills/maintain-project-repo/references/automation-prompts.md @@ -1,8 +1,8 @@ # Repo Maintenance Toolkit Automation Prompts -- Install `maintain-project-repo` into `` and keep the GitHub workflow wrapper enabled. -- Refresh `maintain-project-repo` in `` without deleting repo-specific custom scripts. -- Report what `maintain-project-repo` would install into `` without mutating files. +- Install `maintain-project-repo` into ``, keep the GitHub workflow wrapper enabled, and create or normalize README.md, CONTRIBUTING.md, AGENTS.md, and ROADMAP.md in the same operation. +- Refresh `maintain-project-repo` in `` without deleting repo-specific custom scripts, then refresh the four canonical project documents through their owner workflows. +- Report what `maintain-project-repo` would install and which documentation findings remain in `` without mutating files. - Explain when to use `scripts/repo-maintenance/validate-all.sh`, `scripts/repo-maintenance/sync-shared.sh`, and `scripts/repo-maintenance/release.sh`. - Explain that standard release mode runs from a feature branch or worktree, opens a PR against protected `main`, takes bounded CI/review snapshots through `prepare`, `inspect`, and `advance`, gates on PR comments, merges, fast-forwards local `main`, creates and pushes the tag from that reviewed `main`, creates the GitHub release, accounts for every local branch not contained by `main`, and only then cleans up branches that are proven safe to delete. - Explain that branch cleanup is gated by commit reachability: do not call work on `main`, merged, recovered, preserved, or safe to clean up until the exact local repository and remote prove it, and do not delete local branches, remote branches, worktrees, archive refs, or temporary rescue refs until any non-base history is merged or explicitly archived. diff --git a/skills/maintain-project-docs/references/document-boundaries.md b/skills/maintain-project-repo/references/document-boundaries.md similarity index 100% rename from skills/maintain-project-docs/references/document-boundaries.md rename to skills/maintain-project-repo/references/document-boundaries.md diff --git a/skills/maintain-project-repo/references/project-docs-maintenance-automation-prompts.md b/skills/maintain-project-repo/references/project-docs-maintenance-automation-prompts.md new file mode 100644 index 000000000..9d4545d1b --- /dev/null +++ b/skills/maintain-project-repo/references/project-docs-maintenance-automation-prompts.md @@ -0,0 +1,30 @@ +# Project Docs Maintenance Automation Prompts + +Use these prompts when scheduling or delegating the documentation phase owned by +`maintain-project-repo`. + +## Check-Only Sweep + +Run `maintain-project-repo --operation report-only` for the target repository. +Report the planned toolkit actions and audit README, CONTRIBUTING, AGENTS, and +ROADMAP in that order. Include owner-skill findings, cross-document +responsibility drift, and stale command evidence. Do not edit files, commit, +push, or open a pull request. + +## Bounded Apply Sweep + +Run `maintain-project-repo --operation refresh` after the operator approves the +repository refresh. Let each owner document workflow edit only its own target +file. Report remaining cross-document issues separately from fixes already +applied. Do not move content across files unless the operator explicitly +requested that cleanup. + +## Subagent Discovery + +When the repository is large, ask subagents for read-only findings before the main thread edits: + +- one worker checks README and contributor docs for stale commands +- one worker checks AGENTS and nested guidance for routing or policy drift +- one worker checks ROADMAP and issue state for small-ticket candidates + +Require file references and concise evidence from each worker. The main thread owns the final edits and validation. diff --git a/skills/maintain-project-repo/references/trigger-eval.md b/skills/maintain-project-repo/references/trigger-eval.md index b193c7378..7e20b0047 100644 --- a/skills/maintain-project-repo/references/trigger-eval.md +++ b/skills/maintain-project-repo/references/trigger-eval.md @@ -9,6 +9,8 @@ - Run the release workflow and clean up the merged branch. - Install the repo-maintenance toolkit. - Refresh our validation, sync, and release scripts. +- Bootstrap this repository and create its canonical project docs. +- Run a coordinated README, CONTRIBUTING, AGENTS, and ROADMAP refresh. - Use the checked-in release notes for this patch release. ## Should Not Trigger @@ -26,6 +28,7 @@ - GitHub repository settings audit and alignment route to `maintain-github-repository`. -- Ordinary documentation work routes to the owning document-maintenance skill. +- Ordinary single-document work routes to the owning document-maintenance skill; + coordinated project-doc maintenance routes to `maintain-project-repo`. - Ordinary local Git work follows repo-local Git guidance without invoking the full release lifecycle. diff --git a/plugins/repository-skills/skills/maintain-project-docs/scripts/maintain_project_docs.py b/skills/maintain-project-repo/scripts/maintain_project_docs.py similarity index 99% rename from plugins/repository-skills/skills/maintain-project-docs/scripts/maintain_project_docs.py rename to skills/maintain-project-repo/scripts/maintain_project_docs.py index 50b4b2521..f3409aedf 100644 --- a/plugins/repository-skills/skills/maintain-project-docs/scripts/maintain_project_docs.py +++ b/skills/maintain-project-repo/scripts/maintain_project_docs.py @@ -308,7 +308,7 @@ def child_fixes(child: Dict[str, Any]) -> List[Dict[str, Any]]: report = child.get("report") if not isinstance(report, dict): return [] - fixes = report.get("fixes_applied", []) + fixes = report.get("fixes_applied", report.get("apply_actions", [])) return fixes if isinstance(fixes, list) else [] diff --git a/skills/maintain-project-repo/scripts/run_workflow.py b/skills/maintain-project-repo/scripts/run_workflow.py index a786f7ca6..dbb21ae8e 100755 --- a/skills/maintain-project-repo/scripts/run_workflow.py +++ b/skills/maintain-project-repo/scripts/run_workflow.py @@ -5,14 +5,16 @@ # "PyYAML>=6.0.2,<7", # ] # /// -"""Unified runtime entrypoint for maintain-project-repo.""" +"""Install or refresh repository tooling and canonical project documentation.""" from __future__ import annotations import argparse import json import subprocess +import sys from pathlib import Path +from typing import Any def build_parser() -> argparse.ArgumentParser: @@ -25,6 +27,44 @@ def build_parser() -> argparse.ArgumentParser: return parser +def decode_payload(proc: subprocess.CompletedProcess[str], fallback: dict[str, Any]) -> dict[str, Any]: + if not proc.stdout.strip(): + return fallback + try: + payload = json.loads(proc.stdout) + except json.JSONDecodeError: + return { + **fallback, + "stdout": proc.stdout, + "stderr": proc.stderr, + } + return payload if isinstance(payload, dict) else fallback + + +def run_documentation(repo_root: str, run_mode: str) -> tuple[int, dict[str, Any], str]: + helper_path = Path(__file__).with_name("maintain_project_docs.py") + command = [ + sys.executable, + str(helper_path), + "--project-root", + repo_root, + "--run-mode", + run_mode, + "--print-json", + ] + proc = subprocess.run(command, capture_output=True, text=True, check=False) + fallback = { + "run_context": {"project_root": repo_root, "run_mode": run_mode}, + "document_order": [], + "document_reports": [], + "responsibility_issues": [], + "fixes_applied": [], + "post_fix_status": [], + "errors": ["The integrated documentation workflow did not return JSON output."], + } + return proc.returncode, decode_payload(proc, fallback), proc.stderr.strip() + + def main() -> int: args = build_parser().parse_args() repo_root = str(Path(args.repo_root or ".").expanduser().resolve()) @@ -54,7 +94,8 @@ def main() -> int: command.append("--dry-run") proc = subprocess.run(command, capture_output=True, text=True, check=False) - payload = json.loads(proc.stdout) if proc.stdout.strip() else { + return_code = proc.returncode + payload = decode_payload(proc, { "status": "failed", "path_type": "primary", "repo_root": repo_root, @@ -65,10 +106,38 @@ def main() -> int: "stdout": proc.stdout, "stderr": proc.stderr, "next_step": "Fix the maintain-project-repo workflow error and rerun the workflow.", - } + }) payload.setdefault("normalized_inputs", normalized_inputs) + if proc.returncode == 0: + documentation_mode = ( + "check-only" + if operation == "report-only" or args.dry_run + else "apply" + ) + docs_code, docs_payload, docs_stderr = run_documentation( + repo_root, documentation_mode + ) + payload["documentation"] = docs_payload + payload["documentation_result"] = ( + "checked (no writes)" + if documentation_mode == "check-only" + else "canonical documents created or refreshed" + ) + if docs_code != 0: + payload["status"] = "failed" + payload["documentation_result"] = "failed after toolkit update" + existing_stderr = str(payload.get("stderr", "")).strip() + details = docs_stderr or "The integrated documentation workflow failed." + payload["stderr"] = "\n".join( + part for part in (existing_stderr, details) if part + ) + payload["next_step"] = ( + "Fix the reported documentation workflow error and rerun " + "maintain-project-repo so tooling and canonical docs agree." + ) + return_code = 1 print(json.dumps(payload, indent=2, sort_keys=True)) - return 0 if proc.returncode == 0 else 1 + return 0 if return_code == 0 else 1 if __name__ == "__main__": diff --git a/skills/maintain-project-roadmap/scripts/maintain_project_roadmap.py b/skills/maintain-project-roadmap/scripts/maintain_project_roadmap.py index f7a98506e..b1228cd66 100644 --- a/skills/maintain-project-roadmap/scripts/maintain_project_roadmap.py +++ b/skills/maintain-project-roadmap/scripts/maintain_project_roadmap.py @@ -1551,8 +1551,17 @@ def run_maintenance(args: argparse.Namespace) -> Tuple[Dict[str, Any], str]: ).to_dict() ] else: - report["errors"].append(f"ROADMAP path does not exist: {roadmap_path}") - return report, markdown_report(report) + roadmap_text = "" + report["findings"] = [ + Finding( + finding_id="missing-roadmap", + category="schema", + severity="high", + message=f"ROADMAP file is missing at {roadmap_path}.", + file=str(roadmap_path), + auto_fixable=True, + ).to_dict() + ] small_ticket_candidates: List[SmallTicketCandidate] = [] if args.collect_source_tickets: diff --git a/skills/repository-operations-workflow/SKILL.md b/skills/repository-operations-workflow/SKILL.md index c278a19b6..20715dfe3 100644 --- a/skills/repository-operations-workflow/SKILL.md +++ b/skills/repository-operations-workflow/SKILL.md @@ -24,8 +24,8 @@ needed for that classification, then hand work to the narrowest owner. | Codex worktree mode, local environment, or app-owned worktree behavior | `codex-gui-worktree-workflow` | | Parallel worker branch, worktree, write, or integration ownership | `coordinate-worktrees-and-threads` | | GitHub settings, rulesets, security automation, or repository policy | `maintain-github-repository` | - | README, CONTRIBUTING, AGENTS, or ROADMAP maintenance | The matching `maintain-project-*` document workflow | - | Coordinated repository-document sweep | `maintain-project-docs` | + | One README, CONTRIBUTING, AGENTS, or ROADMAP maintenance task | The matching `maintain-project-*` document workflow | + | Coordinated repository-document sweep, repository bootstrap, or repository refresh | `maintain-project-repo` | | Version bump, tag, release, publication, or branch-accounting cleanup | `maintain-project-repo` | 3. When the request crosses multiple outcomes, name the sequence and keep each mutation with its owning workflow. For example: select a worktree, make a diff --git a/tests/test_repository_docs_workflow.py b/tests/test_repository_docs_workflow.py deleted file mode 100644 index 85e1a17f0..000000000 --- a/tests/test_repository_docs_workflow.py +++ /dev/null @@ -1,81 +0,0 @@ -from __future__ import annotations - -import importlib.util -import subprocess -import sys -import tempfile -import unittest -from pathlib import Path - - -ROOT = Path(__file__).resolve().parents[1] -SCRIPT = ROOT / "plugins/repository-skills/skills/maintain-project-docs/scripts/maintain_project_docs.py" - -spec = importlib.util.spec_from_file_location("maintain_project_docs", SCRIPT) -assert spec is not None and spec.loader is not None -module = importlib.util.module_from_spec(spec) -sys.modules["maintain_project_docs"] = module -spec.loader.exec_module(module) - - -class MaintainProjectDocsTests(unittest.TestCase): - def test_select_workflows_preserves_canonical_order(self) -> None: - selected, errors = module.select_workflows(None, None) - self.assertEqual(errors, []) - self.assertEqual([workflow.key for workflow in selected], ["readme", "contributing", "agents", "roadmap"]) - - def test_select_workflows_reports_unknown_keys(self) -> None: - selected, errors = module.select_workflows("readme,unknown", "roadmap") - self.assertEqual([workflow.key for workflow in selected], ["readme"]) - self.assertEqual(errors, ["Unknown document workflow key: unknown"]) - - def test_build_child_command_passes_ticket_flags_only_to_roadmap(self) -> None: - args = module.parse_args( - [ - "--project-root", - "/tmp/demo", - "--run-mode", - "check-only", - "--collect-source-tickets", - "--collect-github-issues", - "--github-repo", - "owner/repo", - ] - ) - readme_command = module.build_child_command(args, module.DOCUMENT_WORKFLOWS[0], Path("/tmp/demo")) - roadmap_command = module.build_child_command(args, module.DOCUMENT_WORKFLOWS[-1], Path("/tmp/demo")) - self.assertNotIn("--collect-source-tickets", readme_command) - self.assertIn("--collect-source-tickets", roadmap_command) - self.assertIn("--collect-github-issues", roadmap_command) - self.assertIn("owner/repo", roadmap_command) - - def test_responsibility_audit_flags_cross_doc_drift(self) -> None: - with tempfile.TemporaryDirectory() as tmpdir: - root = Path(tmpdir) - (root / "README.md").write_text("# Demo\n\n## Contribution Workflow\n\nDo all the things.\n", encoding="utf-8") - (root / "ROADMAP.md").write_text("# Roadmap\n\n## Safety Boundaries\n\nDo not.\n", encoding="utf-8") - issues = module.audit_responsibility_boundaries(root, module.DOCUMENT_WORKFLOWS) - issue_ids = {issue["issue_id"] for issue in issues} - self.assertIn("readme-contains-maintainer-workflow", issue_ids) - self.assertIn("roadmap-contains-procedural-guidance", issue_ids) - - def test_script_reports_selection_errors_as_json(self) -> None: - with tempfile.TemporaryDirectory() as tmpdir: - proc = subprocess.run( - [ - sys.executable, - str(SCRIPT), - "--project-root", - tmpdir, - "--run-mode", - "check-only", - "--include", - "missing", - "--print-json", - ], - capture_output=True, - text=True, - check=False, - ) - self.assertEqual(proc.returncode, 1) - self.assertIn("Unknown document workflow key: missing", proc.stdout) diff --git a/tests/test_repository_maintenance_workflow.py b/tests/test_repository_maintenance_workflow.py index 56a807887..094918a34 100644 --- a/tests/test_repository_maintenance_workflow.py +++ b/tests/test_repository_maintenance_workflow.py @@ -1,14 +1,23 @@ from __future__ import annotations import json +import importlib.util import os import subprocess +import sys import tempfile import unittest from pathlib import Path ROOT = Path(__file__).resolve().parents[1] SCRIPT = ROOT / "plugins/repository-skills/skills/maintain-project-repo/scripts/run_workflow.py" +DOCS_SCRIPT = ROOT / "plugins/repository-skills/skills/maintain-project-repo/scripts/maintain_project_docs.py" + +docs_spec = importlib.util.spec_from_file_location("maintain_project_repo_docs", DOCS_SCRIPT) +assert docs_spec is not None and docs_spec.loader is not None +docs_module = importlib.util.module_from_spec(docs_spec) +sys.modules["maintain_project_repo_docs"] = docs_module +docs_spec.loader.exec_module(docs_module) class RepoMaintenanceToolkitWorkflowTests(unittest.TestCase): @@ -35,6 +44,13 @@ def test_report_only_lists_managed_files(self) -> None: self.assertIn(".github/workflows/validate-repo-maintenance.yml", payload["managed_files"]) self.assertIn("scripts/repo-maintenance/config/profile.env", payload["managed_files"]) self.assertEqual(payload["profile"], "generic") + self.assertEqual(payload["documentation_result"], "checked (no writes)") + self.assertEqual( + payload["documentation"]["document_order"], + ["readme", "contributing", "agents", "roadmap"], + ) + for filename in ("README.md", "CONTRIBUTING.md", "AGENTS.md", "ROADMAP.md"): + self.assertFalse(Path(tmpdir, filename).exists()) def test_xcode_workspace_profile_installs_workspace_validation_and_dispatches_components(self) -> None: with tempfile.TemporaryDirectory() as tmpdir: @@ -155,6 +171,55 @@ def test_generic_profile_uses_generic_macos_latest_workflow(self) -> None: self.assertIn("actions/checkout@v6.0.2", workflow_text) self.assertNotIn("actions/checkout@v4", workflow_text) self.assertNotIn("maxim-lobanov/setup-xcode@v1", workflow_text) + for filename in ("README.md", "CONTRIBUTING.md", "AGENTS.md", "ROADMAP.md"): + self.assertTrue(Path(tmpdir, filename).is_file()) + self.assertEqual( + payload["documentation_result"], + "canonical documents created or refreshed", + ) + + def test_refresh_recreates_missing_canonical_document(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + code, _payload = self.run_script("--repo-root", tmpdir, "--operation", "install") + self.assertEqual(code, 0) + roadmap = Path(tmpdir, "ROADMAP.md") + roadmap.unlink() + + code, payload = self.run_script("--repo-root", tmpdir, "--operation", "refresh") + + self.assertEqual(code, 0) + self.assertEqual(payload["status"], "success") + self.assertTrue(roadmap.is_file()) + self.assertTrue( + any( + fix.get("action") == "create-roadmap-from-template" + for fix in payload["documentation"]["fixes_applied"] + ) + ) + + def test_documentation_error_fails_combined_operation(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + Path(tmpdir, "README.md").mkdir() + + code, payload = self.run_script("--repo-root", tmpdir, "--operation", "install") + + self.assertEqual(code, 1) + self.assertEqual(payload["status"], "failed") + self.assertIn("documentation", payload) + self.assertTrue(payload["documentation"]["errors"]) + self.assertTrue(Path(tmpdir, "scripts/repo-maintenance/validate-all.sh").is_file()) + + def test_xcode_bootstrap_uses_integrated_repo_install(self) -> None: + bootstrap = ( + ROOT + / "plugins/apple-dev-skills/skills/bootstrap-xcode-workspace/scripts/run_workflow.py" + ).read_text(encoding="utf-8") + self.assertIn("runner = maintain_project_repo_runner()", bootstrap) + self.assertIn( + '[str(runner), "--repo-root", str(root), "--operation", "install", "--profile", "xcode-workspace"]', + bootstrap, + ) + self.assertNotIn("--skip-doc", bootstrap) def test_managed_workflows_avoid_node20_action_versions(self) -> None: workflow_assets = [ @@ -465,5 +530,83 @@ def test_only_generic_and_xcode_workspace_profiles_exist(self) -> None: self.assertIn('choices=("generic", "xcode-workspace")', runner) +class MaintainProjectRepoDocumentationTests(unittest.TestCase): + def test_select_workflows_preserves_canonical_order(self) -> None: + selected, errors = docs_module.select_workflows(None, None) + self.assertEqual(errors, []) + self.assertEqual( + [workflow.key for workflow in selected], + ["readme", "contributing", "agents", "roadmap"], + ) + + def test_select_workflows_reports_unknown_keys(self) -> None: + selected, errors = docs_module.select_workflows("readme,unknown", "roadmap") + self.assertEqual([workflow.key for workflow in selected], ["readme"]) + self.assertEqual(errors, ["Unknown document workflow key: unknown"]) + + def test_build_child_command_passes_ticket_flags_only_to_roadmap(self) -> None: + args = docs_module.parse_args( + [ + "--project-root", + "/tmp/demo", + "--run-mode", + "check-only", + "--collect-source-tickets", + "--collect-github-issues", + "--github-repo", + "owner/repo", + ] + ) + readme_command = docs_module.build_child_command( + args, docs_module.DOCUMENT_WORKFLOWS[0], Path("/tmp/demo") + ) + roadmap_command = docs_module.build_child_command( + args, docs_module.DOCUMENT_WORKFLOWS[-1], Path("/tmp/demo") + ) + self.assertNotIn("--collect-source-tickets", readme_command) + self.assertIn("--collect-source-tickets", roadmap_command) + self.assertIn("--collect-github-issues", roadmap_command) + self.assertIn("owner/repo", roadmap_command) + + def test_responsibility_audit_flags_cross_doc_drift(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + root = Path(tmpdir) + (root / "README.md").write_text( + "# Demo\n\n## Contribution Workflow\n\nDo all the things.\n", + encoding="utf-8", + ) + (root / "ROADMAP.md").write_text( + "# Roadmap\n\n## Safety Boundaries\n\nDo not.\n", + encoding="utf-8", + ) + issues = docs_module.audit_responsibility_boundaries( + root, docs_module.DOCUMENT_WORKFLOWS + ) + issue_ids = {issue["issue_id"] for issue in issues} + self.assertIn("readme-contains-maintainer-workflow", issue_ids) + self.assertIn("roadmap-contains-procedural-guidance", issue_ids) + + def test_script_reports_selection_errors_as_json(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + proc = subprocess.run( + [ + sys.executable, + str(DOCS_SCRIPT), + "--project-root", + tmpdir, + "--run-mode", + "check-only", + "--include", + "missing", + "--print-json", + ], + capture_output=True, + text=True, + check=False, + ) + self.assertEqual(proc.returncode, 1) + self.assertIn("Unknown document workflow key: missing", proc.stdout) + + if __name__ == "__main__": unittest.main() From 13956dfe0fafbad6220678cf26622f3725f4042a Mon Sep 17 00:00:00 2001 From: Gale W Date: Thu, 20 Aug 2026 22:29:52 -0400 Subject: [PATCH 2/2] release: prepare Socket v10.0.2 --- plugins/agent-engineering-skills/.codex-plugin/plugin.json | 2 +- plugins/agent-portability-skills/.codex-plugin/plugin.json | 2 +- plugins/agentdeck/.codex-plugin/plugin.json | 2 +- plugins/android-dev-skills/.codex-plugin/plugin.json | 2 +- plugins/apple-creator-studio-skills/.codex-plugin/plugin.json | 2 +- plugins/apple-dev-skills/.codex-plugin/plugin.json | 2 +- plugins/cloud-deployment-skills/.codex-plugin/plugin.json | 2 +- plugins/cloud-inference-skills/.codex-plugin/plugin.json | 2 +- plugins/codebase-understanding-skills/.codex-plugin/plugin.json | 2 +- plugins/cybersecurity-skills/.codex-plugin/plugin.json | 2 +- plugins/dotnet-skills/.codex-plugin/plugin.json | 2 +- plugins/game-dev-skills/.codex-plugin/plugin.json | 2 +- .../messaging-collaboration-skills/.codex-plugin/plugin.json | 2 +- plugins/model-lab-skills/.codex-plugin/plugin.json | 2 +- plugins/network-protocol-skills/.codex-plugin/plugin.json | 2 +- plugins/professional-skills/.codex-plugin/plugin.json | 2 +- plugins/python-skills/.codex-plugin/plugin.json | 2 +- plugins/repository-skills/.codex-plugin/plugin.json | 2 +- plugins/reverse-engineering-skills/.codex-plugin/plugin.json | 2 +- plugins/rust-skills/.codex-plugin/plugin.json | 2 +- plugins/server-side-jvm/.codex-plugin/plugin.json | 2 +- plugins/server-side-swift/.codex-plugin/plugin.json | 2 +- plugins/swift-lang/.codex-plugin/plugin.json | 2 +- plugins/swiftasb-skills/.codex-plugin/plugin.json | 2 +- plugins/web-dev-skills/.codex-plugin/plugin.json | 2 +- pyproject.toml | 2 +- uv.lock | 2 +- 27 files changed, 27 insertions(+), 27 deletions(-) diff --git a/plugins/agent-engineering-skills/.codex-plugin/plugin.json b/plugins/agent-engineering-skills/.codex-plugin/plugin.json index 81794d34f..2b30d983f 100644 --- a/plugins/agent-engineering-skills/.codex-plugin/plugin.json +++ b/plugins/agent-engineering-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agent-engineering-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Agent-system design, orchestration, scheduling, external-agent, and evaluation workflow skills.", "author": { "name": "Gale", diff --git a/plugins/agent-portability-skills/.codex-plugin/plugin.json b/plugins/agent-portability-skills/.codex-plugin/plugin.json index d71039da8..114a966cc 100644 --- a/plugins/agent-portability-skills/.codex-plugin/plugin.json +++ b/plugins/agent-portability-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agent-portability-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Skills for agent portability, ACP, A2A, Zed, Hermes, Codex plugin surfaces, and host adapter guidance.", "author": { "name": "Gale", diff --git a/plugins/agentdeck/.codex-plugin/plugin.json b/plugins/agentdeck/.codex-plugin/plugin.json index 1952a8fd1..a5405da54 100644 --- a/plugins/agentdeck/.codex-plugin/plugin.json +++ b/plugins/agentdeck/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "agentdeck", - "version": "10.0.1", + "version": "10.0.2", "description": "Local Codex runtime utilities for thread, hook, and app-server workflows.", "author": { "name": "Gale", diff --git a/plugins/android-dev-skills/.codex-plugin/plugin.json b/plugins/android-dev-skills/.codex-plugin/plugin.json index dc52c475d..8a59ceeea 100644 --- a/plugins/android-dev-skills/.codex-plugin/plugin.json +++ b/plugins/android-dev-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "android-dev-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Android, Kotlin, Java, Gradle, Android Gradle Plugin, testing, lint, UI implementation, and release-readiness workflow skills.", "author": { "name": "Gale", diff --git a/plugins/apple-creator-studio-skills/.codex-plugin/plugin.json b/plugins/apple-creator-studio-skills/.codex-plugin/plugin.json index ae5d772d5..3bbec7de5 100644 --- a/plugins/apple-creator-studio-skills/.codex-plugin/plugin.json +++ b/plugins/apple-creator-studio-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "apple-creator-studio-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Human-facing and Computer Use-aware Apple Creator Studio workflows for Final Cut Pro editing, Motion templates, Compressor delivery, Logic Pro production, MainStage concert preparation, and GarageBand projects.", "author": { "name": "Gale", diff --git a/plugins/apple-dev-skills/.codex-plugin/plugin.json b/plugins/apple-dev-skills/.codex-plugin/plugin.json index 97a4e30c7..05f4603b8 100644 --- a/plugins/apple-dev-skills/.codex-plugin/plugin.json +++ b/plugins/apple-dev-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "apple-dev-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Apple development workflows for Codex, including macOS privacy permissions, sandbox file access, entitlement diagnosis, virtualization, SwiftPM, Xcode, app extensions, media, provisioning, SwiftUI, AppKit, Safari, security, OpenAPI, and DocC.", "author": { "name": "Gale", diff --git a/plugins/cloud-deployment-skills/.codex-plugin/plugin.json b/plugins/cloud-deployment-skills/.codex-plugin/plugin.json index 2e6c5aca2..9f3b7fcd4 100644 --- a/plugins/cloud-deployment-skills/.codex-plugin/plugin.json +++ b/plugins/cloud-deployment-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "cloud-deployment-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Codex skills for routing cloud deployment work through official provider plugins, MCP servers, CLIs, and a reusable Dockerized-service release and deployment contract.", "author": { "name": "Gale", diff --git a/plugins/cloud-inference-skills/.codex-plugin/plugin.json b/plugins/cloud-inference-skills/.codex-plugin/plugin.json index 123fd7a01..968cf84d9 100644 --- a/plugins/cloud-inference-skills/.codex-plugin/plugin.json +++ b/plugins/cloud-inference-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "cloud-inference-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Cloud AI inference workflow skills for routing model serving, training, conversion, and GPU infrastructure work across Runpod, Hugging Face, AWS, Vast.ai, CoreWeave, and similar providers.", "author": { "name": "Gale", diff --git a/plugins/codebase-understanding-skills/.codex-plugin/plugin.json b/plugins/codebase-understanding-skills/.codex-plugin/plugin.json index 6b377d383..009e0816d 100644 --- a/plugins/codebase-understanding-skills/.codex-plugin/plugin.json +++ b/plugins/codebase-understanding-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "codebase-understanding-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Code-path exploration, call-site tracing, and evidence-based codebase explanation skills.", "author": { "name": "Gale", diff --git a/plugins/cybersecurity-skills/.codex-plugin/plugin.json b/plugins/cybersecurity-skills/.codex-plugin/plugin.json index a3fb99cb2..239f33dd3 100644 --- a/plugins/cybersecurity-skills/.codex-plugin/plugin.json +++ b/plugins/cybersecurity-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "cybersecurity-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Defensive cybersecurity, isolated Linux and macOS analysis labs, suspicious-content and malware analysis, macOS defense, vulnerability testing, pentesting, and incident response workflows.", "skills": "./skills/", "author": { diff --git a/plugins/dotnet-skills/.codex-plugin/plugin.json b/plugins/dotnet-skills/.codex-plugin/plugin.json index e2acb029a..c3a989ad3 100644 --- a/plugins/dotnet-skills/.codex-plugin/plugin.json +++ b/plugins/dotnet-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "dotnet-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Codex skills for choosing, bootstrapping, building, testing, packaging, diagnosing, and maintaining .NET projects, including F# web applications, with F# and C# as equal first-party languages.", "author": { "name": "Gale", diff --git a/plugins/game-dev-skills/.codex-plugin/plugin.json b/plugins/game-dev-skills/.codex-plugin/plugin.json index 4ba38ccba..b020c53d2 100644 --- a/plugins/game-dev-skills/.codex-plugin/plugin.json +++ b/plugins/game-dev-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "game-dev-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Apple platform game development workflow skills for native Metal rendering, Game Porting Toolkit routing, MetalFX, GPU asset streaming, neural rendering, frameworks, input, haptics, and profiling.", "author": { "name": "Gale", diff --git a/plugins/messaging-collaboration-skills/.codex-plugin/plugin.json b/plugins/messaging-collaboration-skills/.codex-plugin/plugin.json index e68c8182d..4ce8a20a4 100644 --- a/plugins/messaging-collaboration-skills/.codex-plugin/plugin.json +++ b/plugins/messaging-collaboration-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "messaging-collaboration-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Codex workflows for chat apps, bots, collaboration, iMessage, Apple notifications and Push to Talk, VoIP, and default communication-app planning.", "author": { "name": "Gale", diff --git a/plugins/model-lab-skills/.codex-plugin/plugin.json b/plugins/model-lab-skills/.codex-plugin/plugin.json index fc4072d3f..77d80bae3 100644 --- a/plugins/model-lab-skills/.codex-plugin/plugin.json +++ b/plugins/model-lab-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "model-lab-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Reproducible model training, evaluation, intervention, and runtime research workflows.", "author": { "name": "Gale" diff --git a/plugins/network-protocol-skills/.codex-plugin/plugin.json b/plugins/network-protocol-skills/.codex-plugin/plugin.json index 696bcd9e0..88e645bab 100644 --- a/plugins/network-protocol-skills/.codex-plugin/plugin.json +++ b/plugins/network-protocol-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "network-protocol-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Codex skills for choosing, planning, implementing, and diagnosing modern application transports and real-time networking protocols, including QUIC, HTTP/3, WebRTC, Media over QUIC, WebTransport-adjacent handoffs, protocol maturity checks, and stack-specific implementation routing.", "author": { "name": "Gale", diff --git a/plugins/professional-skills/.codex-plugin/plugin.json b/plugins/professional-skills/.codex-plugin/plugin.json index b2fd8cb42..f1eb19ef2 100644 --- a/plugins/professional-skills/.codex-plugin/plugin.json +++ b/plugins/professional-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "professional-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Professional workflow skills for job search, career materials, and external professional services.", "author": { "name": "Gale", diff --git a/plugins/python-skills/.codex-plugin/plugin.json b/plugins/python-skills/.codex-plugin/plugin.json index bfd95d3fe..91f25d5fe 100644 --- a/plugins/python-skills/.codex-plugin/plugin.json +++ b/plugins/python-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "python-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Bundled Python-focused Codex skills for uv bootstrapping, project implementation, diagnostics, packaging, tooling, CI, upgrades, FastAPI service maintenance, FastMCP service maintenance, and testing workflows.", "author": { "name": "Gale", diff --git a/plugins/repository-skills/.codex-plugin/plugin.json b/plugins/repository-skills/.codex-plugin/plugin.json index addd96bf4..b95dbe531 100644 --- a/plugins/repository-skills/.codex-plugin/plugin.json +++ b/plugins/repository-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "repository-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Repository operations, documentation maintenance, GitHub settings, worktree, and release workflow skills.", "author": { "name": "Gale", diff --git a/plugins/reverse-engineering-skills/.codex-plugin/plugin.json b/plugins/reverse-engineering-skills/.codex-plugin/plugin.json index cfd7a3077..cff43425c 100644 --- a/plugins/reverse-engineering-skills/.codex-plugin/plugin.json +++ b/plugins/reverse-engineering-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "reverse-engineering-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Workflow skills for reverse engineering, decompilation, disassembly, symbols, artifact analysis, and exact-build macOS security-control research.", "skills": "./skills/", "author": { diff --git a/plugins/rust-skills/.codex-plugin/plugin.json b/plugins/rust-skills/.codex-plugin/plugin.json index 927cc4186..026198582 100644 --- a/plugins/rust-skills/.codex-plugin/plugin.json +++ b/plugins/rust-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "rust-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Rust, Cargo, rustup, crate, workspace, CLI, library, package, CI, testing, linting, and formatting workflow skills.", "skills": "./skills/", "author": { diff --git a/plugins/server-side-jvm/.codex-plugin/plugin.json b/plugins/server-side-jvm/.codex-plugin/plugin.json index 3c513c3b5..89b5daf0c 100644 --- a/plugins/server-side-jvm/.codex-plugin/plugin.json +++ b/plugins/server-side-jvm/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "server-side-jvm", - "version": "10.0.1", + "version": "10.0.2", "description": "Codex skills for choosing, building, testing, and maintaining server-side JVM backend projects with Java and Scala as equal first-party languages and future Clojure support planned.", "author": { "name": "Gale", diff --git a/plugins/server-side-swift/.codex-plugin/plugin.json b/plugins/server-side-swift/.codex-plugin/plugin.json index 84bca8380..857b0c0d4 100644 --- a/plugins/server-side-swift/.codex-plugin/plugin.json +++ b/plugins/server-side-swift/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "server-side-swift", - "version": "10.0.1", + "version": "10.0.2", "description": "Codex skills for adding, building, testing, and operating server-side Swift components in canonical product workspaces, with native Homebrew local services and GitHub-only Linux builds and deployments.", "author": { "name": "Gale", diff --git a/plugins/swift-lang/.codex-plugin/plugin.json b/plugins/swift-lang/.codex-plugin/plugin.json index ec5fbb8d0..e7be04c41 100644 --- a/plugins/swift-lang/.codex-plugin/plugin.json +++ b/plugins/swift-lang/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "swift-lang", - "version": "10.0.1", + "version": "10.0.2", "description": "Shared Swift language and tooling skills for API style, errors, functional pipelines, formatting, source organization, SwiftSyntax, compiler inspection, SourceKit, indexing, SourceKit-LSP, and modernization.", "skills": "./skills/", "author": { diff --git a/plugins/swiftasb-skills/.codex-plugin/plugin.json b/plugins/swiftasb-skills/.codex-plugin/plugin.json index 106a7a3f6..8bb3c0aeb 100644 --- a/plugins/swiftasb-skills/.codex-plugin/plugin.json +++ b/plugins/swiftasb-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "swiftasb-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Codex skills for explaining SwiftASB and building SwiftUI, AppKit, and Swift package integrations on top of it.", "author": { "name": "Gale", diff --git a/plugins/web-dev-skills/.codex-plugin/plugin.json b/plugins/web-dev-skills/.codex-plugin/plugin.json index 9cb322c1b..5e0e1a5f3 100644 --- a/plugins/web-dev-skills/.codex-plugin/plugin.json +++ b/plugins/web-dev-skills/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "web-dev-skills", - "version": "10.0.1", + "version": "10.0.2", "description": "Codex skills for focused web and Expo native-boundary workflows.", "author": { "name": "Gale", diff --git a/pyproject.toml b/pyproject.toml index 8c10e1057..57bd47f73 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "socket-maintenance" -version = "10.0.1" +version = "10.0.2" description = "Root uv tooling baseline for the socket superproject." requires-python = ">=3.11" dependencies = [] diff --git a/uv.lock b/uv.lock index aa28db1f1..b357d29b0 100644 --- a/uv.lock +++ b/uv.lock @@ -286,7 +286,7 @@ wheels = [ [[package]] name = "socket-maintenance" -version = "10.0.1" +version = "10.0.2" source = { virtual = "." } [package.dev-dependencies]