Skip to content

ASDD Wave 3: apply path, closure gate, fork-vs-hook ADR#7

Merged
MikeBengtson merged 6 commits into
mainfrom
feat/asdd-wave-3
May 13, 2026
Merged

ASDD Wave 3: apply path, closure gate, fork-vs-hook ADR#7
MikeBengtson merged 6 commits into
mainfrom
feat/asdd-wave-3

Conversation

@MikeBengtson
Copy link
Copy Markdown
Collaborator

Summary

Wave 3 of the ASDD core. Stacked on top of #6 (wave 2). Three beads closed.

  • gm-v0sp.6 — Nonce-gated apply (internal/spec/apply/ + gemba spec apply). Idempotency via .gemba/.apply.log.jsonl keyed on (nonce, anchor, kind). Mid-apply failure triggers Rollback: reverses creates by closing with rollback: note, reverts updates from captured FieldChange.From. Lockfile save only on success path — atomic at spec-reconcile boundary. Refuses if Plan.NonceStale unless --force-nonce.
  • gm-v0sp.12 — Closure gate (internal/spec/hooks/ + gemba spec close-check + scripts/bd-pre-close.sh). Refuses epic close if any mapped story bead is still open and not marked Resolution: wontdo in the lockfile. --force --reason "..." bypass emits spec.close.gate.bypass via slog. Lockfile gains a Mapping.Resolution field (backward-compatible — old lockfiles parse fine).
  • gm-v0sp.20 — ADR 0001: Spec Kit integration strategy. Decision: stay hook-layer only (option a) for v1. Defer upstream PR (c) until adoption hits ~10 repos. Fork (b) last-resort.

Test plan

  • go build ./... clean
  • go test ./internal/spec/... ./internal/cli/... — 395 tests pass in 16 packages
  • gemba spec apply --dry-run shows planned ops without mutating
  • gemba spec apply replayed with same nonce is a no-op (idempotency)
  • gemba spec close-check --epic <id> refuses when stories open
  • scripts/bd-pre-close.sh symlinked into a bd hook dir gates real bd close

Merge order

Wave 2 (#6) must merge first — this PR's base is feat/asdd-wave-2.

Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

MikeBengtson and others added 6 commits May 13, 2026 05:29
Finalize the fork-vs-hook decision for ASDD Phase 1+. Adopt option (a):
hook-layer only as the v1 strategy. Defer option (c) (upstream backend
knob) until adoption justifies the maintenance commitment. Treat option
(b) (fork) as a last resort.

Adds:
- docs/design/adr/0001-spec-kit-integration-strategy.md
- Decisions section in docs/design/asdd-whitepaper.md cross-linking the ADR

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds `gemba spec close-check` plus the underlying `internal/spec/hooks`
package. The gate walks every Story anchor in spec.md, looks up its
mapped bd bead via the lockfile, queries bd status through
reconcile.BeadLister, and refuses the close when any mapped story is
neither bd-closed nor lockfile-resolved=wontdo.

- Backwards-compatible Mapping.Resolution string field (omitempty);
  legacy lockfiles continue to load (covered by TestLoad_Legacy...).
- Force=true with non-empty Reason emits a spec.close.gate.bypass slog
  audit event and returns Allow=true.
- scripts/bd-pre-close.sh wraps the CLI for operators to wire into bd's
  pre-close hook directory; doc block at the top of the script explains
  the symlink-based install path.

Tests: 386 pass. go build clean.
Adds internal/spec/apply/ — the executor that turns a reconcile.Plan into
real bd mutations under an X-GEMBA-Confirm nonce gate. Refuses stale-nonce
plans (ErrNonceStale), takes a pre-apply snapshot when requested, and
rolls back prior successes on any mid-apply failure. The BDMutator
emulates header propagation via a (nonce, anchor, kind) sidecar log
(.gemba/.apply.log.jsonl) so the same plan can be safely replayed after
a partial success — already-applied tuples are skipped.

Wires `gemba spec apply <spec.md>` into the CLI with --dry-run, --prune,
--lockfile, --bd-stub, --force-nonce, --no-snapshot, --apply-log, --json.
Lockfile save is deferred until every op succeeds (atomic at the spec-
reconcile boundary).

Audit hook (spec.apply.start/op/complete/failed) emits via a narrow
Auditor interface; failures there never block apply.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Base automatically changed from feat/asdd-wave-2 to main May 13, 2026 11:00
@MikeBengtson MikeBengtson merged commit 8e267d6 into main May 13, 2026
5 of 8 checks passed
@MikeBengtson MikeBengtson deleted the feat/asdd-wave-3 branch May 13, 2026 11:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant