diff --git a/README.md b/README.md index 0a890dd..31698b1 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,267 @@ -

GitHub Repository Bootstrap

+ -

A small Pi skill for planning and applying repeatable GitHub repository setup without bypassing repository governance.

+
+

GitHub Repository Bootstrap

+

Plan repeatable GitHub repository setup before anything changes.

+

A Pi skill for repository governance: labels, milestones, repository files, issue and pull-request templates, and optional Projects v2 setup.

+

+ Release + CI + Issues + MIT License +

+
-

- Release - CI - Issues - License -

+> **Read the plan before you authorize it.** This package discovers the target state, emits a machine-readable plan, and applies changes only when given the exact authorization value from that plan. It does not delete GitHub resources. -## Status +
+Contents -This public repository is distributed directly as a Pi package. `package.json` remains `private: true` only to prevent npm publication; install the skill from a reviewed release tag. +- [Quick start](#quick-start) +- [What it can manage](#what-it-can-manage) +- [How a bootstrap runs](#how-a-bootstrap-runs) +- [Installation and prerequisites](#installation-and-prerequisites) +- [Manifest and command examples](#manifest-and-command-examples) +- [Safety model](#safety-model) +- [Verification](#verification) +- [Release policy](#release-policy) +- [Repository map](#repository-map) +- [License](#license) -## Quick path +
-1. Install the existing immutable release tag in the target project: +--- + +## Quick start + +1. Install a reviewed, immutable release tag in the project you want to configure: ```bash pi install -l git:github.com/egdev6/github-repository-bootstrap@v1.0.0 ``` -2. Ask Pi to bootstrap repository governance, such as labels, milestones, issue templates, or a Projects v2 board. -3. Review the generated manifest and plan, then explicitly authorize the exact plan before any mutation. +2. In Pi, ask for the repository outcome—not a blind mutation. For example: + + ```text + Bootstrap GitHub governance for this repository. Start with read-only discovery; + I need bug and feature labels, issue forms, and a pull-request template. + ``` + +3. Review the generated manifest and JSON plan. Authorize only the exact plan you intend to apply. + +Use a version tag rather than a moving branch reference for future installs. GitHub Releases—not npm—are this package's distribution channel; `package.json` is intentionally `private` to prevent npm publication. + +

(back to top)

+ +--- + +## What it can manage + +| Area | Behavior | +| --- | --- | +| **Labels** | Creates missing labels. Existing labels change only when the manifest marks them `managed: true`. | +| **Milestones** | Creates missing milestones and updates existing ones only when explicitly managed. | +| **Repository files** | Copies named, repository-relative source files to repository-relative destinations using `ensure` or `replace`. | +| **Issue and PR templates** | Installs only the fixed `bug_report`, `feature_request`, and pull-request template set. Legacy `templates` configuration can coexist with generic files. | +| **Projects v2** | Optionally creates or links a project, creates configured fields and BOARD/TABLE views, and preserves existing views and matching fields. | +| **Planning evidence** | Returns one JSON report containing validation, discovery, plan, completed, skipped, and failure evidence. | + +The manifest is intentionally modular: omit a resource family to leave it out of the bootstrap. + +

(back to top)

+ +--- + +## How a bootstrap runs + +| Step | What happens | Your decision | +| --- | --- | --- | +| **1. Discover** | Pi inspects the local repository binding and the relevant GitHub state. | Confirm only facts that cannot be safely inferred. | +| **2. Define** | The skill produces a manifest that is validated against the [configuration schema][schema]. | Choose the governance resources and which existing ones are managed. | +| **3. Plan** | The executor validates access, scopes, and target identity, then prints the exact create, update, skip, or unsupported actions. | Read the JSON report; a plan is not permission to mutate. | +| **4. Authorize** | The plan produces an `authorization.value` bound to its canonical inputs. | Approve the exact value only if the plan is correct. | +| **5. Apply and verify** | The executor revalidates the plan binding, applies allowed actions, and reports completed, skipped, and failed work. | Review the final report and any failures. | + +A changed manifest, target, discovered state, or managed-file hash produces a different authorization value. Re-plan instead of reusing an old one. -Use a version tag such as `v1.0.0`, never a moving branch reference, for future installs. +

(back to top)

-## Capabilities +--- -| Area | What the skill does | +## Installation and prerequisites + +### Install from a release tag + +```bash +pi install -l git:github.com/egdev6/github-repository-bootstrap@v1.0.0 +``` + +Before installing, review the release source and the [skill instructions][skill]. The package is a Pi package: `package.json` exposes the skill through `pi.skills`. + +### What the executor checks + +| Requirement | Why it is required | | --- | --- | -| Intake | Infers available repository facts and asks only for unresolved governance choices. | -| Configuration | Validates a reviewed manifest against its configuration schema. | -| Planning | Discovers current state and reports the exact creates, updates, skips, and failures before changes run. | -| Managed resources | Supports labels, milestones, repository files, legacy templates, and optional Projects v2 configuration. | -| Application | Applies only the reviewed plan after explicit authorization tied to its SHA-256 value. | +| Pi with this package installed | Loads the guided intake and bootstrap skill. | +| A writable local Git working tree | The executor validates the local target before planning or applying. | +| An `origin` remote matching the configured `owner/repository` | Prevents applying a reviewed manifest to a different repository. | +| GitHub CLI (`gh`) with authenticated, configured scopes | Used to discover GitHub state and apply GitHub resource changes. | +| Linux descriptor-relative filesystem support for managed file or template writes | Those local writes fail closed when the required safe-write support is unavailable. | + +Projects v2 discovery, GraphQL, and mutations run only when the manifest includes `project`. Its required scopes are also manifest-driven. + +

(back to top)

+ +--- + +## Manifest and command examples + +The [example manifest][example-config] is a small, valid starting point. It demonstrates two explicitly managed labels and the fixed template module: + +```json +{ + "account": "acme-org", + "repository": "acme-org/widgets", + "requiredScopes": ["repo"], + "labels": { + "kind:bug": { + "color": "D73A4A", + "description": "Defect report", + "managed": true + }, + "kind:feature": { + "color": "1D76DB", + "description": "Feature request", + "managed": true + } + }, + "templates": { + "issueForms": ["bug_report", "feature_request"], + "issueFormLabels": { + "bug_report": ["kind:bug"], + "feature_request": ["kind:feature"] + }, + "pullRequest": true, + "mode": "ensure" + } +} +``` + +Replace the example account, repository, and governance choices with facts for the target. The schema requires only `account` and `repository`; optional modules remain disabled when omitted. + +### Plan first + +From the target repository, after saving a reviewed manifest as `governance.json`, run the executor from Pi's project-local Git package directory: + +```bash +BOOTSTRAP=".pi/git/github.com/egdev6/github-repository-bootstrap/skills/github-repository-bootstrap/scripts/bootstrap.mjs" +node "$BOOTSTRAP" --config governance.json --mode plan +``` + +Read the JSON report. It includes `authorization.value`; do not fabricate or reuse that value. + +### Apply the reviewed plan + +```bash +BOOTSTRAP=".pi/git/github.com/egdev6/github-repository-bootstrap/skills/github-repository-bootstrap/scripts/bootstrap.mjs" +node "$BOOTSTRAP" --config governance.json --mode apply --authorize '' +``` + +The apply command accepts only the exact authorization value emitted by the corresponding plan. A nonzero exit leaves failure evidence in the JSON report; it never represents a partial operation as success. + +### Configure generic repository files + +Use the top-level `files` map for governed files that already exist inside the target repository. Both the source and destination must be repository-relative paths without traversal. + +```json +{ + "files": { + ".github/CODEOWNERS": { + "source": "governance/CODEOWNERS", + "mode": "ensure" + } + } +} +``` + +- `ensure` creates a missing destination and preserves an existing one. +- `replace` creates a missing destination or updates it when its bytes differ from the source. + +For the complete contract, see the [configuration schema][schema], [adaptive intake guide][intake], and [skill instructions][skill]. + +

(back to top)

+ +--- ## Safety model -- Discovery happens before every managed-resource change; configured resources are preserved unless they are explicitly managed. -- The workflow never deletes resources. Repository-file sources and destinations are constrained to safe paths under the target repository. -- `plan` is required before `apply`; authorization is bound to the exact reviewed plan and cannot be reused after relevant state changes. -- Failed operations remain visible in the JSON report instead of being represented as success. +| Guardrail | What it prevents | +| --- | --- | +| **Discovery before mutation** | Existing GitHub resources are inspected before each managed-resource change. | +| **Explicit management** | Existing labels and milestones remain unchanged unless `managed: true`; `ensure` preserves existing files and templates. | +| **Target binding** | The local Git root and `origin` must match the configured repository. | +| **Path confinement** | Generic file sources and destinations reject absolute paths, traversal, symbolic links, unsafe parents, and non-regular files. | +| **Plan-bound authorization** | `apply` requires the SHA-256-derived value from the exact reviewed plan and rechecks it before changing anything. | +| **No deletion path** | The executor creates, selectively updates, skips, or reports failures; it does not delete configured resources. | +| **Fail-closed project handling** | Conflicting project fields require manual reconciliation. Unavailable Projects v2 view capability is reported as unsupported without emulation. | -## Release policy +> **Do not treat discovery as authorization.** A plan tells you what would happen. Only the explicit `apply` invocation with its matching authorization value can make changes. -The GitHub Actions workflow runs `npm test` for pull requests to `main` and pushes to `main`. After successful `main` checks, it derives `v`. When that version has no tag yet—normally after a package version change—it creates an annotated tag at the pushed commit and a GitHub Release with generated notes. Existing tags and releases are reported and left unchanged. +

(back to top)

-GitHub Releases are the only release artifact produced here. npm publication is out of scope, and this package stays private. +--- ## Verification -Run the focused test suite locally: +Run the focused local test suite: ```bash npm test ``` -The same command is the required `test` job in GitHub Actions. +The suite exercises configuration validation, plan generation, authorization binding, repository-origin checks, safe managed-file and template writes, and Projects v2 planning behavior. GitHub Actions runs the same command for pull requests to `main` and pushes to `main` using Node.js 20. + +For a real bootstrap, verification is the final JSON report: inspect `completed`, `skipped`, `failures`, and `success`. A failure is evidence to investigate—not authorization for additional changes. + +

(back to top)

+ +--- + +## Release policy + +GitHub Actions runs `npm test` for pull requests to `main` and pushes to `main`. After a successful push, the workflow derives `v`. It creates an annotated tag at the pushed commit only when the tag is missing, then independently creates a generated-notes GitHub Release only when the release is missing. + +Existing tags and releases are left unchanged. GitHub Releases are the only release artifact produced by this repository; npm publication is out of scope. + +

(back to top)

+ +--- + +## Repository map + +```text +.github/workflows/release.yml CI and release automation +skills/github-repository-bootstrap/ +├── SKILL.md Guided workflow and command contract +├── assets/config.schema.json Manifest validation contract +├── assets/example.config.json Minimal example manifest +├── assets/templates/ Fixed issue and pull-request templates +├── references/intake.md Fact-based governance intake +├── scripts/bootstrap.mjs Plan/apply entry point +├── scripts/lib.mjs Validation, planning, and safety helpers +└── tests/lib.test.mjs Focused Node.js test suite +``` + +

(back to top)

+ +--- ## License -[MIT](LICENSE) +Distributed under the [MIT License][license]. + +[skill]: skills/github-repository-bootstrap/SKILL.md +[schema]: skills/github-repository-bootstrap/assets/config.schema.json +[example-config]: skills/github-repository-bootstrap/assets/example.config.json +[intake]: skills/github-repository-bootstrap/references/intake.md +[license]: LICENSE