diff --git a/.gitpin/change-evidence.json b/.gitpin/change-evidence.json index c2d275f..6ff75fb 100644 --- a/.gitpin/change-evidence.json +++ b/.gitpin/change-evidence.json @@ -1,28 +1,58 @@ { "schemaVersion": 1, - "summary": "Let the Validate workflow be dispatched on main, because auto-merged commits pushed with GITHUB_TOKEN never start the push: main run; the CI routing check now requires the trigger.", + "summary": "Rewrite the README for a fast first read (problem, 30-second fail-to-pass quickstart, film, Mermaid trust-boundary sketch, guardrails, stage-neutral status) and add the social preview and demo GIF it references.", "claims": [ { - "id": "VALIDATE-DISPATCH-ON-MAIN", - "statement": ".github/workflows/ci.yml adds workflow_dispatch so main can be validated at its exact merged SHA, and scripts/verify-ci-runner-routing.mjs fails if ci.yml ever drops that trigger.", + "id": "README-FIRST-READ", + "statement": "README.md now leads with the problem, a pnpm demo:gate quickstart, use-in-your-repo steps, a Mermaid sketch of the base-trusted policy and head-submitted manifest, guardrails and non-goals, and keeps the stage-neutral 0.6.4 sentence required by scripts/verify-release-tag.mjs.", "covers": [ - ".github/workflows/ci.yml", - "scripts/verify-ci-runner-routing.mjs" + "README.md" ], "evidence": [ { "ref": "head", - "path": ".github/workflows/ci.yml", - "lineStart": 10, - "lineEnd": 10, - "contentSha256": "31ef10165fe98492a75234e221d538925dc4007bfd24de8f56275ef977e9f564" + "path": "README.md", + "lineStart": 38, + "lineEnd": 38, + "contentSha256": "d3088a4ed3623c123bbc6615dce53fc46ac9c61666bd84fd1231e0c49ba82132" }, { "ref": "head", - "path": "scripts/verify-ci-runner-routing.mjs", - "lineStart": 46, - "lineEnd": 46, - "contentSha256": "7c8cbd587163ebb59858ea291e2ec5615475e89f9721728c5d6f5929b28ea39b" + "path": "README.md", + "lineStart": 43, + "lineEnd": 43, + "contentSha256": "a0a4d4a60b7eb8343c9a0021ec8237f9cbdc088d03c4c6bcd0ffd4c70d92d67c" + }, + { + "ref": "head", + "path": "README.md", + "lineStart": 184, + "lineEnd": 184, + "contentSha256": "06fa519f1345a104f9fc86974955bc236498b11ae67e363335cc2887a94efef2" + } + ] + }, + { + "id": "README-MEDIA", + "statement": "The social preview image and the demo GIF are referenced from the README; the GIF is cut from the delivered 30-second film and the preview is rendered from a real film frame.", + "covers": [ + "docs/media/social-preview.png", + "docs/media/gitpin-demo.gif" + ], + "evidence": [ + { + "ref": "head", + "path": "README.md", + "lineStart": 3, + "lineEnd": 3, + "contentSha256": "8a856a365aea603fe62f31cbd6e285d0acb04f352a6667701f760ea7813cf968" + }, + { + "ref": "head", + "path": "README.md", + "lineStart": 68, + "lineEnd": 68, + "contentSha256": "98a2d7c9416a700e619964b9069a5a7f6d7892ff032e6e0e4450f38c818cefd1" } ] } diff --git a/README.md b/README.md index fcb55bb..d5176b9 100644 --- a/README.md +++ b/README.md @@ -1,102 +1,194 @@ +
+ +GitPin: agent pull requests must show exact evidence before they merge. + # GitPin +### Agent-authored pull requests must show exact evidence before they merge. + +**A read-only PR gate and local MCP server that ties every claim an AI agent makes about its change to an exact committed line that anyone can re-check with plain `git`.** + [![Validate](https://github.com/shmindmaster/gitpin/actions/workflows/ci.yml/badge.svg)](https://github.com/shmindmaster/gitpin/actions/workflows/ci.yml) +[![npm](https://img.shields.io/npm/v/gitpin.svg)](https://www.npmjs.com/package/gitpin) +[![MCP Registry](https://img.shields.io/badge/MCP%20Registry-io.github.shmindmaster%2Fgitpin-blue.svg)](https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.shmindmaster/gitpin&limit=20) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Node.js Version](https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg)](package.json) -[![MCP Protocol](https://img.shields.io/badge/MCP_SDK-1.32-blue.svg)](https://modelcontextprotocol.io) -[![npm](https://img.shields.io/npm/v/gitpin.svg)](https://www.npmjs.com/package/gitpin) -### Make agent-authored changes show exact evidence before merge. +[Quickstart](#quickstart-the-gate-in-30-seconds) · [Watch the film](#see-it-run) · [Use it in your repo](#use-it-in-your-repo) · [How it works](#how-it-works) · [Guardrails](#guardrails-and-non-goals) · [Status](#status-and-limits) -**GitPin is an agent-delivery assurance gate with a local evidence MCP.** It makes material PR claims cover the actual diff and point to exact committed line slices. The local MCP supplies index-free, read-only, multi-repo evidence that humans and CI can re-check with `git show`. +
-**Public-good thesis:** evidence for agent-authored software changes should remain inspectable with ordinary local Git, independent of the coding agent or proprietary hosted platform that produced the change. +--- -```text -Agent claim - → pin.search_* (candidates only) - → pin.prove (evidence pack: path + line + full SHA + content hash) - → pin.verify (git show re-check; HEAD match report) - → you run: git show : -``` +## Why it exists -| Crowded category | GitPin product | -| --- | --- | -| Vector / SQLite “repo context” servers | **No embeddings, no DB, no reindex** | -| Filesystem MCP (writes) | **Never writes indexed repos** | -| One-shot repo dumps | **Live prove → verify MCP loop** | -| Grep hits as “the answer” | **Candidates → evidence pack → verification report** | -| GitHub platform MCP | **Local Git roots (private/offline)** | +Coding agents now open pull requests with confident descriptions: "added retry +logging", "updated the protocol doc", "no other files touched". A reviewer who +wants to trust one of those sentences has to open the file and hunt for the +line, then do it again for the next sentence. Most reviewers stop checking, and +an agent can change a file it never mentions. -Formerly RepoContext 0.3.x. See [migration](docs/migration-gitpin.md). +GitPin turns the description into evidence. The agent commits a small manifest +in which every material claim names the paths it covers and points at an exact +line slice with a SHA-256 of its text. A required check compares that manifest +with the real diff. Any changed file that no claim covers fails the build, and +every claim that passes can be re-checked by a human with `git show`, without +GitPin, without the agent and without a hosted platform. -## Required PR evidence gate +## Quickstart: the gate in 30 seconds ```bash -gitpin gate --base --head +git clone https://github.com/shmindmaster/gitpin.git && cd gitpin +corepack enable && pnpm install --frozen-lockfile +pnpm demo:gate +``` + +`demo:gate` builds GitPin, creates a throwaway synthetic repository in a temp +folder, and runs the real `gitpin gate` twice. The agent's first commit changes +`docs/protocol.md` without claiming it, so the gate fails with exit `1`. The +agent adds one evidence locator (line 5, hashed) and the same gate passes with +exit `0`: + +```text +$ gitpin gate --base --head +status: failed exit code: 1 +violation: uncovered-change: Changed path has no material claim: docs/protocol.md. +covered: synthetic-service/docs/overview.md:3 @ (verified) +$ gitpin gate --base --head +status: ok exit code: 0 +covered: synthetic-service/docs/overview.md:3 @ (verified) +covered: synthetic-service/docs/protocol.md:5 @ (verified) ``` -The gate reads policy only from the trusted base commit, reads the submitted manifest only from the head commit, compares the merge-base diff, and verifies exact line-slice hashes. It never executes PR code and never labels a locator match as proof of semantic correctness. Use the [GitPin GitHub Action setup](docs/pr-evidence-gate.md) to make it a required check. That guide also documents an optional, separate CrewScore check for teams that want written-control coverage alongside GitPin evidence verification. +Nothing is written outside the temp folder, and the folder is removed afterward. + +## See it run + + + GitPin demo: the gate fails an agent pull request that changed an unclaimed file, then passes after one hashed line locator is added. + -> **Versioned distribution:** This source tree and its packed documentation describe GitPin 0.6.4 without asserting publication status. Availability is established only by independently verifying the npm, MCP Registry, GitHub Release, and Pages receipts. Install with `npx -y gitpin@0.6.4` only after the npm receipt resolves. Node 20+. +**[Watch the 90-second film →](https://saroshhussain.com/films/gitpin-the-gate-that-wants-evidence.mp4)** · +**[The 30-second cut →](https://saroshhussain.com/films/gitpin-the-gate-in-30-seconds.mp4)** -GitPin is maintained by **Sarosh Hussain**, an independent open-source maintainer who leads the project's technical direction. +## Use it in your repo -## Five-minute path +**1. Install the trusted policy on your default branch** (a separate, reviewed +change, so a pull request can never weaken its own gate): ```bash -# From a committed Git repository -# This exact version becomes usable only after npm publication is verified. -npx -y gitpin@0.6.4 init --client codex +mkdir -p .gitpin +curl -fsSL https://raw.githubusercontent.com/shmindmaster/gitpin/v0.6.4/templates/gate.yml -o .gitpin/gate.yml ``` -`init` creates `~/.gitpin/repositories.yaml` **outside** the repo, runs `doctor`, prints a **first evidence line with full SHA**, and paste-ready MCP config. It never edits the indexed repository. +**2. Make it a required check:** + +```yaml +name: Agent delivery assurance +on: pull_request # never pull_request_target +permissions: + contents: read +jobs: + evidence: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} + - uses: shmindmaster/gitpin@514799cb0eae55e965e51d510d5e7a0a7604c9cc # v0.6.4 + with: + base-sha: ${{ github.event.pull_request.base.sha }} + head-sha: ${{ github.event.pull_request.head.sha }} +``` + +**3. Each agent PR commits `.gitpin/change-evidence.json`**, starting from +[`templates/change-evidence.json`](templates/change-evidence.json). The full +setup, including rulesets, is in [docs/pr-evidence-gate.md](docs/pr-evidence-gate.md). + +**Give your agent the evidence tools.** The local MCP server lets Claude Code, +Codex, Cursor and other MCP clients find candidates and produce the evidence +packs the gate checks: ```bash -# Independently verify any claim (same contract as pin.verify) -# This exact version becomes usable only after npm publication is verified. -npx -y gitpin@0.6.4 verify \ - --repository my-service \ - --path docs/architecture.md \ - --line 42 \ - --sha +# Run inside any committed Git repository +npx -y gitpin@0.6.4 init --client codex # or claude-code, cursor, windsurf, zed, continue +``` + +`init` writes `~/.gitpin/repositories.yaml` outside the repository, runs +`doctor`, prints a first evidence line with a full SHA, and prints paste-ready +MCP config. It never edits the repository it registers. + +## How it works + +```mermaid +flowchart LR + subgraph BASE["Trusted: base commit"] + POL[".gitpin/gate.yml
policy"] + end + subgraph HEAD["Submitted: head commit"] + MAN[".gitpin/change-evidence.json
claims → path, lines, sha256"] + end + DIFF["git diff merge-base..head
the real change"] + POL --> GATE{"gitpin gate
read-only, never runs PR code"} + MAN --> GATE + DIFF --> GATE + GATE -- "uncovered path, wrong hash,
sensitive path" --> FAIL(["exit 1: check fails"]) + GATE -- "every changed path covered,
every slice re-hashed" --> PASS(["exit 0: report with full-SHA citations"]) + PASS -.-> HUMAN(["Reviewer: git show <sha>:<path>"]) ``` -## Product job +The gate reads policy only from the trusted base commit and the manifest only +from the head commit, through `git show`, never from a working tree. It compares +the merge-base diff, re-hashes every cited line slice, and emits a report whose +citations carry full SHAs. -**When** agents invent file contents, mix dirty worktrees, or cite the wrong branch -**You want** every fact re-checkable with `git show :` -**GitPin** registers local Git roots, serves **HEAD-only** docs/code, flags **stale** tracked docs, returns **path / line / SHA**, and closes the loop with **`pin.verify`**. +The MCP side follows one loop. Search returns candidates, never answers. Proof +turns a candidate into an evidence pack. Verification re-checks it with +`git show`: -### Agent tool surface (`pin.*`) — 12 read-only tools +```text +pin.search_docs / pin.search_code candidates only, with a forced next step + → pin.prove evidence pack: path, line, full SHA, content hash + → pin.verify independent git show re-check, HEAD match report + → you: git show : +``` -| Job | Tools | +| Job | Tools (12, all read-only) | | --- | --- | | Discover | `pin.catalog` | | Find candidates | `pin.search_docs`, `pin.search_code` | -| Prove | `pin.prove` (primary), `pin.prove_set` (1–8 cites), `pin.get_doc`, `pin.read` | +| Prove | `pin.prove`, `pin.prove_set` (1 to 8 cites), `pin.get_doc`, `pin.read` | | Verify | `pin.verify`, `pin.verify_set` | -| Decide | `pin.analyze` → `EvidenceBrief` | -| Inspect / diff | `pin.inspect`, `pin.compare` | +| Decide | `pin.analyze` → `EvidenceBrief` (known facts, gaps, stable `evidenceSetId`) | +| Inspect and diff | `pin.inspect`, `pin.compare` | + +Resource `gitpin://catalog`; prompt `prove-with-git-head`. Cite formats are in +[docs/cite-spec.md](docs/cite-spec.md); an agent skill template is in +[templates/gitpin-skill.md](templates/gitpin-skill.md). -Resource: `gitpin://catalog`. Prompt: `prove-with-git-head` (forces the product loop). -Cite formats: [docs/cite-spec.md](docs/cite-spec.md). Agent skill template: [templates/gitpin-skill.md](templates/gitpin-skill.md). +## Guardrails and non-goals -### Functionality that is the pivot (not a rename) +- **Read-only, always.** GitPin never writes, commits or pushes to a repository it reads, and the gate never executes pull-request code. +- **A PR cannot weaken its own gate.** Policy comes from the base commit; evidence comes from the head commit; the dirty working tree is never read. +- **Uncommitted work is never evidence.** Dirty and untracked content is excluded from HEAD citations. +- **Sensitive paths stay sensitive.** Deny rules apply to evidence, and the manifest cannot cite itself. +- **Candidates are not claims.** Search output is labelled `evidence-candidates` and must go through `pin.prove`. +- **No embeddings, no database, no reindex.** Evidence comes from Git objects, so it works offline and on private repositories. -- **Evidence pack** (`pin.prove`): claim binding, line slice, full SHA, `contentSha256`, `citation.cite` / `handle`, next-step verify. -- **Multi-cite sets** (`pin.prove_set` / `pin.verify_set`): stable `evidenceSetId` for multi-repo answers and CI. -- **Verification report** (`pin.verify` / CLI): independent `git show`; optional `mustContain` claim-text; status includes `contradicted`. -- **Candidates, not claims**: search returns `kind: evidence-candidates` with forced `next: pin.prove`. -- **EvidenceBrief**: multi-repo knownFacts / gaps / stable `evidenceSetId` (schema v2). -- **Dirty exclusion**: uncommitted work is never cited as HEAD evidence. +Not goals: semantic search, writing or committing code, replacing GitHub +Issues or PR automation, or treating a non-Git folder as one repository. -### Explicit non-goals +## Status and limits -- Semantic / embedding search -- Writing, committing, or pushing -- Replacing GitHub Issues/PRs automation -- Indexing non-Git umbrella folders as one “repo” +This source tree and its packed documentation describe GitPin 0.6.4 without asserting publication status. Check each channel independently: [npm](https://www.npmjs.com/package/gitpin), the [MCP Registry](https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.shmindmaster/gitpin&limit=20) (`io.github.shmindmaster/gitpin`) and [GitHub Releases](https://github.com/shmindmaster/gitpin/releases/tag/v0.6.4). +Node 20 or later. Site: [shmindmaster.github.io/gitpin](https://shmindmaster.github.io/gitpin/). + +GitPin verifies **coverage, location, revision and content hash**. It proves +what was committed, not that a claim is true: it does not establish semantic +correctness, runtime behavior, authorship, authorization or compliance. That +judgment stays with the reviewer, who now reads one cited line instead of +hunting for it. Planned work is in the [roadmap](ROADMAP.md). ## Configuration @@ -109,23 +201,24 @@ Cite formats: [docs/cite-spec.md](docs/cite-spec.md). Agent skill template: [tem Default registry: `~/.gitpin/repositories.yaml` (legacy compatibility fallback: `~/.repocontext/...` if present). -## Docs - -[Tools](docs/tools.md) · [Compare](docs/compare.md) · [FAQ](docs/faq.md) · [Migration](docs/migration-gitpin.md) · [Clients](docs/clients.md) · [Architecture](docs/architecture.md) · [Roadmap](ROADMAP.md) · [Governance](GOVERNANCE.md) · [Security](SECURITY.md) · [Competitive landscape](docs/research/competitive-landscape-corrected-2026-07-30.md) +Formerly RepoContext 0.3.x. See [migration](docs/migration-gitpin.md). -Site: [shmindmaster.github.io/gitpin](https://shmindmaster.github.io/gitpin/). GitPin is the canonical product and repository name; legacy `repocontext` references exist only for migration compatibility. +## Docs -## Development +[Tools](docs/tools.md) · [PR evidence gate](docs/pr-evidence-gate.md) · [Clients](docs/clients.md) · [Architecture](docs/architecture.md) · [Compare](docs/compare.md) · [FAQ](docs/faq.md) · [Troubleshooting](docs/troubleshooting.md) · [Roadmap](ROADMAP.md) · [Governance](GOVERNANCE.md) -```bash -corepack enable -pnpm install --frozen-lockfile -pnpm validate -pnpm build -pnpm verify:package -pnpm site:test -``` +## Contributing, security and license -## License +- **Contributing:** start with an issue for bugs and proposals, then follow + [CONTRIBUTING.md](CONTRIBUTING.md). Good first issues are labelled + [`good first issue`](https://github.com/shmindmaster/gitpin/labels/good%20first%20issue). + Before a pull request: `pnpm validate && pnpm build && pnpm verify:package`. +- **Security:** report vulnerabilities privately through a + [GitHub security advisory](https://github.com/shmindmaster/gitpin/security/advisories/new), + as described in [SECURITY.md](SECURITY.md). Please do not open a public issue. +- **License:** [MIT](LICENSE). -[MIT](LICENSE) +Created and maintained by [Sarosh Hussain](https://saroshhussain.com). Related +open source: [Assay](https://github.com/shmindmaster/assay) keeps an agent's +decision out of its side effects; [CrewScore](https://github.com/shmindmaster/crewscore) +checks whether an agent's prompt writes its safeguards down. diff --git a/docs/media/gitpin-demo.gif b/docs/media/gitpin-demo.gif new file mode 100644 index 0000000..343730d Binary files /dev/null and b/docs/media/gitpin-demo.gif differ diff --git a/docs/media/social-preview.png b/docs/media/social-preview.png new file mode 100644 index 0000000..292fecf Binary files /dev/null and b/docs/media/social-preview.png differ