Overview
BuildTrail keeps three records apart for every milestone: the criterion the maintainer signed before the work, the evidence that was submitted or observed, and the verdict of a reviewer who isn't the author. The page shows the result of one criterion with its limits, never a project-wide “verified” badge.
The pilot covers Solana projects with a public GitHub repository and up to five milestones each. We don't hold funds, run escrow, unlock or burn anything, execute repository code, or score honesty or returns.
Identity & signing
Publishing a manifest asks the maintainer wallet to sign a plain-text message (not a transaction):
BuildTrailManifest v1
origin: https://buildtrail.app
project: <project id>
network: solana-mainnet
ca: <exact mint>
repo: github.com/<owner>/<name>
manifest: sha256:<hash of the canonical manifest>
nonce: <single use>
expires: <issued + 10 min>- The server verifies the Ed25519 signature against the session and the exact bytes. A nonce works once; an expired nonce or a different manifest hash is refused.
- Repository challenge. We issue a unique string; you commit it to
.buildtrail/challenge.txt. We read that commit through the GitHub API and store SHA, digest and challenge. This shows that one key controls both the manifest and a write to the repo. It doesn't establish legal ownership of the brand. - CA relationship is shown as
maintainer-declared. Owning tokens doesn't prove repo ownership, and we never infer it from a ticker. - Changing CA, repo or key creates a new identity revision. Past milestones keep the binding they were signed under. A revoked key adds a
revokedevent; historic signatures stay valid for what they signed.
Evidence model
| Kind | Who | What it proves |
|---|---|---|
source_observation | BuildTrail | We fetched this commit/release/tag through the GitHub API at this time and pinned the resolved SHA and response digest. |
maintainer_submission | The team | The team signed and provided this link, file or description. Not independently checked on its own. |
reviewer_observation | A reviewer | The exact steps, environment, time and result someone ran, plus the limits of that check. |
Uploads accept text, JSON, PNG and JPEG up to 10 MiB. HTML, scripts, archives and executables are refused. Image metadata is stripped from the public copy; the original digest is kept privately. Demo URLs are stored as links and are never fetched by our servers. Reviewers open them in their own environment.
Verdicts
| criterion_met | Every acceptance step passed within the stated scope. |
| partially_demonstrated | Some steps passed and some didn't; limitations list which. |
| criterion_not_met | The checked steps did not show the outcome. No conclusion about motives. |
| untestable | The reviewer couldn't run the steps (e.g. demo unreachable). Not a failure. |
| review_pending | Submitted, waiting for a reviewer. |
Scope, reviewer, evidence IDs and criterion revision are required on every verdict. Commit counts and CI status can never set criterion_met. A missed due date shows overdue · pending, which is not a rug or fraud finding.
Revisions & corrections
- Published criteria are immutable. A change creates revision B with a reason and
effective_at. Submissions and verdicts stay attached to the revision they were judged on. - A due date can't be moved backwards to make a milestone look on time.
- A verdict is corrected by a new reviewed version with a reason. The original stays public as
superseded. - If a tag moves or a release is deleted, a
source_changedorunavailableevent is added. The stored snapshot and the human verdict are not changed silently. - Withdrawn milestones keep their manifest and timestamps.
Reviewer policy
The review endpoint checks role, author/reviewer separation and the exact criterion and submission hash. An author can't review their own submission from any account. Different accounts don't prove that people are economically independent; every verdict names its reviewer so readers can weigh it. Independent attestation isn't claimed.
Complaints and correction requests go to the operator queue. Moderation can hide a public projection while keeping the audit record that must be retained. Signed public data can't be recalled from copies others already made.
Sources & limits
- Source URLs are parsed into canonical GitHub owner/repo/object IDs; fetches go only to the fixed API origin, without arbitrary redirects or user headers.
- Refresh: once a day, plus bounded manual requests. On GitHub 429 or a deleted release, the previous snapshot stays and a freshness issue is shown.
- Pilot limits: 10 projects, 5 milestones per project, 10 evidence objects per submission, 100 MiB per project. Evidence retention 12 months.
- Timestamps are service time (received/published), not blockchain time.
API
Public versions are readable by project and milestone ID. Reviewer private notes are only served to their roles.
| Endpoint | Purpose |
|---|---|
POST /v1/projects | Create a project identity revision |
POST /v1/identity-challenges | Issue a repository challenge |
POST /v1/milestones | Draft a milestone manifest |
POST /v1/milestones/{id}/publish | Publish with signature + nonce (idempotent on manifest hash) |
POST /v1/submissions | Submit evidence against an exact revision |
POST /v1/reviews | Record a verdict (role + separation checks) |
POST /v1/corrections | Supersede a verdict with a reason |
GET /v1/exports/{milestone} | Public JSON projection |
curl https://buildtrail.app/v1/exports/LUM-2 | jq '.verdicts[0] | {verdict, scope, limitations}'$BTRAIL
Reading the trail is free. Builder workspaces pay for archive and refresh in SOL, or 25% less in $BTRAIL; every $BTRAIL payment is burned on receipt. Holding $BTRAIL gives no influence over reviews, and reviewers aren't paid per outcome. BuildTrail has no rights over any project's dev fees.