Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Veripsa support
url: https://veripsa.com
about: For account, billing, or installation questions, please reach out via veripsa.com — this repo is for the public webhook spec only.
url: https://veripsa.com/support
about: Account, installation, and billing questions belong in the canonical support channel.
- name: Recent Veripsa changes
url: https://veripsa.com/whats-new
about: Check the canonical product change log before reporting a behavior change.
about: Check user-visible product changes before reporting public-contract drift.
37 changes: 6 additions & 31 deletions .github/ISSUE_TEMPLATE/spec-clarification.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,14 @@
---
name: Spec clarification
about: The spec is ambiguous and I'm not sure how to integrate
title: "[clarify] "
labels: spec-clarification
about: Clarify an ambiguous observable integration contract
labels: ''
assignees: ''
---

## What are you trying to integrate?
## Integration surface

In one sentence — a dashboard, an agent that reads Veripsa's verdict, a
log shipper, a security review of the App's permissions, etc.
## Ambiguous contract text

## Which part of the spec is ambiguous?
## Concrete observable example

Quote the spec line and explain what two (or more) readings of it you
came up with.

## What would unblock you?

- [ ] A concrete example added to the spec.
- [ ] A clarification of which reading is correct.
- [ ] A statement that this is intentionally undefined and the App may
change behaviour here.

## Anything else?

(Optional.) Link to the section, or paste the lines of pseudocode you
were trying to write.

---

**Please do not include:**

- Source code or file contents from your repo.
- Customer names or third-party identifiers.

This repo is documentation only; we do not need either to answer a
clarification question.
Do not include source code, diffs, customer names, tokens, or private identifiers.
51 changes: 6 additions & 45 deletions .github/ISSUE_TEMPLATE/spec-correction.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,15 @@
---
name: Spec correction
about: The spec on this repo and the App's actual behaviour disagree
about: Report a difference between the public contract and visible App behavior
title: "[spec] "
labels: spec-correction
labels: ''
assignees: ''
---

## Where in the spec?
## Contract file and section

Which file and section? (e.g. `OUTPUT.md` → "The verdict ladder", or
`EVENTS.md` → "Subscribed events".)
## Visible check title, conclusion, marker, or label behavior

## What does the spec say?
## Date observed

Quote (or screenshot) the spec line you believe is wrong.

## What did the App actually do?

Describe what you observed on a real PR or a real webhook payload:

- which event you saw,
- which check title / `conclusion` was posted,
- which marker text appeared in the comment,
- or which label-event behaviour you observed.

> Example: "The spec says `Veripsa — Heads up` posts `neutral`, but on
> PR-17 I saw the check posted as `action_required`."

**Do not paste private source code, diffs, or file contents** — this
spec repo is content-free and we do not need them. Pasting the check
title, the comment marker, the conclusion, and the verdict word is
enough.

## When did you observe it?

A date or a date range. The Veripsa team correlates against the deploy
log.

## Anything else?

(Optional.) Screenshots of the GitHub check or the comment (with
private content redacted) help.

---

**Please do not include:**

- Source code or file contents from your repo.
- Diffs or commit patches.
- Customer names or third-party identifiers.

We only need to know what Veripsa's surfaces showed you and what the
spec on this repo said.
Do not include source code, diffs, customer names, tokens, or private identifiers.
23 changes: 23 additions & 0 deletions .github/workflows/contract.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: public-contract
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: python -m pip install --disable-pip-version-check "jsonschema>=4.23,<5"
- run: npm ci
- run: npm run check
- run: npm pack --dry-run
88 changes: 14 additions & 74 deletions ACK_LABEL.md
Original file line number Diff line number Diff line change
@@ -1,88 +1,28 @@
# The `veripsa-ack` label

`veripsa-ack` is the single PR label Veripsa reacts to. It is an **optional,
explicit, recorded acknowledgement** of a structural coupling that Veripsa
has surfaced. Installing or using Veripsa does not require a routine ACK step,
per-agent setup, CLI polling command, or copied merge rule.
`veripsa-ack` means: **“I have seen this specific material coupling and I am proceeding anyway.”** It is not correctness approval, code review approval, or proof that the coupling is resolved.

## What "ack" means
## Definition versus application

**Ack means: "I have seen this coupling and I am proceeding anyway."**
Two operations are deliberately separate:

It does **not** mean:
1. **Repository label definition:** Veripsa may lazily create the repository's `veripsa-ack` label definition when a material state first needs it.
2. **Application to a PR:** Veripsa never applies `veripsa-ack` to a pull request on its own. A human or agent with suitable base-repository permission must explicitly apply it.

- "this code is correct" — Veripsa does not assert correctness;
- "this PR is approved" — ack is **not** a review approval; GitHub's
normal review and branch-protection rules are independent of
`veripsa-ack`;
- "the collision is resolved" — the collision may still be real; ack
only records that someone took responsibility for proceeding.
This distinction is part of the v1 public contract.

## When the label matters
## Effect

The label is meaningful only on PRs where Veripsa has surfaced a
**material coupling** in its high-salience check state (see
[`OUTPUT.md`](./OUTPUT.md)). The state appears automatically; recording an ACK
is optional unless the repository owner independently makes the Veripsa check
required and chooses ACK as its exception path.
For a material `Wait in line` or named-partner `Heads up` state, the unacknowledged normalized check is `Paused (acknowledge to proceed)` with `action_required`. A matching explicit ACK reshapes it to `Acknowledged`, `neutral`, and `acknowledged: true`.

- On a **Clear** PR, the label has no effect.
- On a **Heads up** PR with no named in-flight partner (a solo notice),
or a minor build/list-file overlap, the label has no effect — those
never pause.
- On a material PR — a **Wait in line** verdict, or a **Heads up**
verdict with a named in-flight partner PR — the label toggles the
check's `conclusion` from `action_required` to `neutral` and
re-renders the comment to record the ack.
The check gates a merge only when the repository owner independently marks the Veripsa check as required.

## Adding / removing the label
## Staleness

- **Who can add it.** Anyone with write access to the PR's base
repository (humans, bots, autonomous agents using a token with
`pull_requests: write`). Fork contributors cannot add it; their PRs
are treated as non-material for ack purposes.
- **How an agent adds it.** Using the standard GitHub CLI:
`gh pr edit <PR> --add-label veripsa-ack`.
- **How a human adds it.** From the PR sidebar's Labels picker.
- **Removing it.** Removing the label re-raises the pause on the next
event that re-analyses the PR.
An ACK is bound to the specific material coupling. When partners or colliding paths materially change, the prior ACK becomes stale, the high-salience state returns, and the stale PR label is removed or slated for removal.

Veripsa is subscribed to `pull_request` `labeled` / `unlabeled` events
but only acts on them when the changed label is exactly `veripsa-ack`.
Other label changes are ignored at the routing layer.
The comment's 12-lowercase-hex ACK snapshot token is opaque. Its format is public; its derivation is not.

## Stale acks
## Fork PRs

An ack is bound to the **specific coupling** it covered (which partners,
which files). If the coupling **materially changes** between events — a
different partner PR, a different set of colliding files — the prior
ack is considered **stale**:

- the high-salience state re-raises on the next analysis,
- the `veripsa-ack` label is slated for removal so the PR visibly reads
un-acked again.

This makes ack a **fresh, recorded decision per coupling**, not a
one-time opt-out for the lifetime of the PR.

The binding is recorded in an invisible HTML marker
(`<!-- veripsa-ack-snap:<12-hex> -->`) inside Veripsa's PR comment; see
[`OUTPUT.md`](./OUTPUT.md) for the marker shape. Integrators generally
do not need to parse it.

## What Veripsa never does with labels

- Veripsa does not add or remove **any label other than `veripsa-ack`**.
- Veripsa does not add `veripsa-ack` itself; the label is
human-or-agent-applied.
- Veripsa does not interpret label color, description, or position in
the picker. The label name is the entire contract.

## Naming and color

- Veripsa relies on the **exact label name** `veripsa-ack`. Capitalisation
matters. The label is created lazily on first need; it does not have
to exist on the repository ahead of time.
- Color, description, and label-picker position are not part of the
contract — you may change them freely. Veripsa will not overwrite
them.
Fork contributors cannot apply the base repository's label. Fork PRs therefore keep the advisory non-paused form and receive redacted cross-PR context.
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Changelog

## 1.0.0 — 2026-07-19

Initial versioned public contract.

### Corrected

- Separates exact `check_run.name` (`Veripsa`) from human-facing `check_run.output.title`.
- Locks `Heading to` to `success` across manifest, Schema, types, examples, and docs.
- Rejects impossible token/conclusion/underlying-verdict/ACK combinations.
- Defines the ACK snapshot as a 12-lowercase-hex opaque wire token.
- Defines clean `Clear` as check-only and clear coordination comments as `Clear to land`.
- Separates repository label-definition creation from explicit PR label application.

### Added

- Canonical check-state and webhook-event manifests.
- Full eight-event normalized routing envelope.
- Positive/negative example validation, TypeScript compile tests, local-link tests, generated-file drift checks, and CI.

### Deprecated

- `schemas/webhook-routing-event.schema.json` for new integrations. It remains a v1 compatibility schema for selected raw GitHub bodies.
- `VeripsaVerdictToken` in favor of `VeripsaCheckToken`.
23 changes: 23 additions & 0 deletions CHECK_STATES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Check-state contract

Generated from `contract/check-states.json` for contract **v1.0.0**. Human sentence copy may evolve; integrations depend on `check_run.name === "Veripsa"` plus the normalized token.

| Token | Observable title example | Conclusion | Underlying verdict | ACK field | PR comment | Stability |
| --- | --- | --- | --- | --- | --- | --- |
| `Clear` | `Veripsa — Clear` | `success` | `clear` | `forbidden` | `never` | `stable` |
| `Clear to land` | `Veripsa — Clear to land` | `success` | `clear` | `forbidden` | `required` | `stable` |
| `Heads up` | `Veripsa — Heads up` | `neutral` | `heads_up` | `forbidden` | `when_coordination_context_exists` | `stable` |
| `Wait in line` | `Veripsa — Wait in line` | `neutral` | `wait_in_line` | `forbidden` | `when_coordination_context_exists` | `stable` |
| `Unknown` | `Veripsa — Unknown` | `neutral` | `unknown` | `forbidden` | `required` | `stable` |
| `Paused (acknowledge to proceed)` | `Veripsa — Paused (acknowledge to proceed)` | `action_required` | `heads_up` / `wait_in_line` | `false` | `required` | `stable` |
| `Acknowledged` | `Veripsa — Acknowledged` | `neutral` | `heads_up` / `wait_in_line` | `true` | `required` | `stable` |
| `Unresolved merge conflict markers` | `Veripsa — Unresolved merge conflict markers` | `action_required` | `merge_conflict_markers` | `forbidden` | `required` | `stable` |
| `Acknowledgement verification pending` | `Veripsa — acknowledgement verification pending` | `neutral` | — | `forbidden` | `never` | `stable` |
| `Heading to` | `Veripsa — heading to main` | `success` | — | `forbidden` | `never` | `stable` |
| `Watching` | `Veripsa is now watching` | `neutral` | — | `forbidden` | `never` | `stable` |
| `Early-access limit reached` | `Veripsa paused — early-access limit reached` | `neutral` | — | `forbidden` | `never` | `stable` |
| `Changed files not read` | `Veripsa — changed files not read, not analyzed` | `neutral` | — | `forbidden` | `never` | `stable` |
| `Branch state not verified` | `Veripsa — branch state not verified, retrying` | `neutral` | — | `forbidden` | `never` | `stable` |
| `Merge queue: clear` | `Veripsa — merge queue: clear` | `success` | — | `forbidden` | `never` | `stable` |
| `Merge queue: review overlap` | `Veripsa — merge queue: review overlap` | `neutral` | — | `forbidden` | `never` | `stable` |
| `Merge queue: not analyzed` | `Veripsa — merge queue: not analyzed` | `neutral` | — | `forbidden` | `never` | `stable` |
11 changes: 11 additions & 0 deletions COMPATIBILITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Compatibility policy

The public contract is versioned independently from product deployment.

- **Patch:** prose clarification, stricter tests that do not reject previously valid contract data, or corrections to generated artifacts without changing stable wire shapes.
- **Minor:** additive token/event/optional field/schema path. Consumers must treat unknown future titles/tokens as unsupported rather than guessing.
- **Major:** removal/rename of a stable token, field, marker, schema path, or a changed required conclusion/meaning.

Deprecated v1 paths remain available for the lifetime of v1. New integrations should prefer `webhook-routing-envelope.schema.json`; `webhook-routing-event.schema.json` remains a selected raw-body compatibility surface.

Human-facing sentence copy and paragraph order are not stable. Stable assets are the exact check name, normalized tokens and their conclusion constraints, marker shapes, label name/meaning, versioned schema IDs, and exported TypeScript names not marked deprecated.
68 changes: 9 additions & 59 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,16 @@
# Contributing to veripsa-webhook-spec
# Contributing

Thank you for helping keep Veripsa's public integration contract accurate.
Contributions may clarify observable output, fix Schema/type/example drift, improve agent/dashboard consumption, or correct the public data boundary. Do not submit Core source, private scoring or heuristics, SQL/table internals, customer code, diffs, tokens, or proprietary identifiers.

This repository exists so external tools can safely depend on the Veripsa
GitHub App surface without needing access to Veripsa Core internals. Good
contributions usually make the contract easier to consume from an agent,
dashboard, log shipper, security review, or test fixture.

## Good contributions

We welcome pull requests and issues for:

- corrections when the App's visible behaviour and this spec disagree,
- clearer wording around check-run titles, conclusions, PR comments, and
`veripsa-ack`,
- JSON Schema or TypeScript type fixes,
- small examples that show how an agent or dashboard should branch on the
public surface,
- security / compliance documentation for the public GitHub App surface,
- typo and link fixes.

## Out of scope

Please do not send:

- Veripsa Core engine internals,
- requests to publish scoring formulas or collision heuristics,
- private repository source code, diffs, or proprietary file contents,
- customer names, tokens, installation secrets, or confidential identifiers,
- code that requires Veripsa to read or publish source file bodies.

The public contract is intentionally content-free. A useful issue report can
usually be written with only the check title, GitHub `conclusion`, PR number
shape, label name, marker text, and the date you observed the behaviour.

## Compatibility rules

When proposing a change, call out whether it affects any stable surface:

- check-run title prefix tokens,
- GitHub check `conclusion` values,
- PR comment markers,
- `veripsa-ack` semantics,
- schema file paths,
- TypeScript exported names.

If the change only improves prose, say that explicitly.

## Local validation

This repository has no build step. To validate JSON files:
Run:

```sh
npm run check:json
npm ci
npm run generate
npm run check
npm pack --dry-run
```

The script checks that every JSON file under `schemas/` and `examples/`
parses correctly. Schema semantic validation is intentionally kept
dependency-free for now so the repo stays easy to inspect.

## Security
Generated files must be committed with their canonical manifest changes. Classify contract impact as patch, minor/additive, or major/breaking in the PR description. Prose-only changes must say so explicitly.

Do not report vulnerabilities by opening a public issue if the report
contains sensitive details. Use the disclosure path linked from
<https://veripsa.com/security/disclosure>.
Security reports do not belong in public issues. Follow <https://veripsa.com/security/disclosure>.
Loading
Loading