Skip to content

Concepts

Lex edited this page Aug 21, 2026 · 3 revisions

Concepts

The core ideas behind SpecGit:

evidence not assertion   — acceptance is derived from git, PR, and CI facts
fail-closed not hopeful  — anything unverifiable is "unknown", never "accepted"
git is the contract      — the branch, the PR, and the checks are the deliverable

SpecGit does not manage plans, specs, or task lists. By the time it looks at your work, the work already exists as a branch, issues, a pull request, and CI checks. Its only job is to verify — from real evidence — that the delivery is complete.

The three-tier file model

SpecGit's entire footprint is three tiers of files:

Tier Files Committed?
Authoritative spec_git/policy.yaml (required checks, created by init), .specgit.yaml (this delivery's binding, created by issue), optional spec_git/providers.yaml (declared GitLab host) Yes
Derived harness .github/workflows/specgit-accept.yml (the SpecGit Acceptance job) and the managed block in AGENTS.md/CLAUDE.md — regenerate with init --force, never hand-edit Yes
Local integration Guard hooks (.git/hooks/pre-push, .opencode/hooks/*) and setup entry points — agent conveniences, merged non-destructively, never acceptance inputs Your choice

No artifact folders, no caches, no global stores. Verdicts are never persisted — they are computed on every run, so nothing can lie about itself.

The delivery binding

Every delivery is one aggregate, declared in the record file .specgit.yaml:

Part What it is
Delivery A kebab-case id (add-login-flow)
Execution context A branch, or a linked worktree plus its branch — always resolved from live git at evaluation time
Issues 1..N forge issue numbers the delivery closes
Pull request Exactly one PR (or MR) that merges the delivery
Required checks CI check names that must pass at the PR head (from the policy)

One PR may close N issues (Closes #123, Fixes #124, …). Every bound issue must be closed by the PR's closing references — missing any one fails acceptance with the missing numbers listed.

One issue = one independently verifiable WHY

The unit of scope is the issue: each one must be verifiable on its own evidence. If a deliverable cannot be verified on its own, split it before binding. One delivery binds N issues to one PR that closes them all.

Fail-closed acceptance

Delivery states — unbound, draft, bound, accepted, rejected, unknown — are computed on every invocation, never stored. Evaluation runs eleven gates in order, from cheapest local facts to live forge evidence:

  1. Record present and valid
  2. Policy present and valid
  3. Completeness (≥1 issue, exactly 1 PR)
  4. Context matches live git
  5. Origin resolves to a forge repository
  6. Provider reachable and authenticated
  7. Issues exist (and are issues, not PRs)
  8. Sequence (when ordered issues is on)
  9. PR exists, open or merged, head matches the context branch, same repository
  10. PR body closes every bound issue
  11. Every required check is green at the PR head commit

Outcomes:

  • All evidence gathered, ≥1 gate failed → rejected (exit 1) with complete evidence
  • Evidence could not be gathered → unknown (exit 3) — never accepted
  • Every gate passed with evidence → accepted (exit 0)

Consequences: finish offline can return unknown, never accepted; a dirty working tree never fails acceptance (acceptance is about the PR head, not local edits); a draft PR always fails (pr_draft).

What SpecGit deliberately is not

Not a spec framework (no proposal/task artifacts), not a git wrapper (reads facts, never rewrites history), not an issue tracker or CI system (verifies against your forge and existing CI), not a plugin platform.


核心概念

SpecGit 的核心理念:

证据而非断言    —— 验收结论从 git、PR、CI 事实推导
fail-closed    —— 无法验证的一律是 "unknown",绝不 "accepted"
git 即契约     —— 分支、PR、检查就是交付物本身

SpecGit 不管理计划、规格或任务清单。当它审视你的工作时,工作已经以分支、issue、PR 和 CI 检查的形式存在。它唯一的职责是凭真实证据验证交付是否完成。

三层文件模型

SpecGit 的全部文件足迹分三层:

层级 文件 是否提交
权威文件 spec_git/policy.yaml(必需检查项,init 创建)、.specgit.yaml(本次交付的绑定,issue 创建)、可选 spec_git/providers.yaml(声明的 GitLab 主机)
派生护栏 .github/workflows/specgit-accept.ymlSpecGit Acceptance 任务)和 AGENTS.md/CLAUDE.md 中的受管区块 —— 用 init --force 重新生成,切勿手工编辑
本地集成 守卫 hooks(.git/hooks/pre-push.opencode/hooks/*)和 setup 入口 —— agent 便利设施,非破坏性合并,不作为验收输入 自定

没有产物目录、缓存或全局存储。结论永不持久化 —— 每次运行都重新计算,因此任何状态都无法自证为完成。

交付绑定

每次交付是一个聚合体,声明在记录文件 .specgit.yaml 中:

部分 含义
Delivery kebab-case 标识(如 add-login-flow
执行上下文 分支,或 linked worktree 加分支 —— 评估时始终从实际 git 状态解析
Issues 本次交付关闭的 1..N 个 forge issue 编号
Pull request 恰好一个合并该交付的 PR(或 MR)
必需检查 必须在 PR head 通过的 CI 检查名(来自策略)

一个 PR 可以关闭 N 个 issue(Closes #123Fixes #124 等)。每个绑定的 issue 都必须被 PR 的关闭引用关闭 —— 缺少任何一个都会验收失败,并列出缺失的编号。

一个 issue = 一个可独立验证的 WHY

范围的基本单位是 issue:每个 issue 必须能凭自身证据独立验证。如果一个交付物无法独立验证,绑定前先拆分。一次交付把 N 个 issue 绑定到一个关闭它们的 PR。

Fail-closed 验收

交付状态 —— unbounddraftboundacceptedrejectedunknown —— 每次调用都重新计算,永不存储。评估按顺序运行十一个门禁,从最廉价的本地事实到实时 forge 证据:

  1. 记录存在且有效
  2. 策略存在且有效
  3. 完整性(≥1 个 issue,恰好 1 个 PR)
  4. 上下文与实际 git 匹配
  5. Origin 能解析为 forge 仓库
  6. Provider 可达且已认证
  7. Issues 存在(且是 issue 而非 PR)
  8. 顺序性(开启 ordered issues 时)
  9. PR 存在、open 或 merged、head 与上下文分支一致、同一仓库
  10. PR 正文关闭每个绑定的 issue
  11. 每个必需检查在 PR head commit 上为绿

结果:

  • 证据全部收集、至少一个门禁失败 → rejected(退出 1),附完整证据
  • 证据无法收集 → unknown(退出 3)—— 绝不 accepted
  • 所有门禁凭证据通过 → accepted(退出 0)

推论:离线运行 finish 可能返回 unknown,但绝不返回 accepted;脏工作区不会导致验收失败(验收针对 PR head,不是本地改动);draft PR 必然失败(pr_draft)。

SpecGit 刻意不做的事

不是规格框架(没有提案/任务产物),不是 git 封装(只读事实,不改写历史),不是 issue 跟踪器或 CI 系统(对着你的 forge 和现有 CI 做验证),不是插件平台。

Clone this wiki locally