Skip to content

feat: itd-80 intent-lifecycle slice 1 — native spec store + abcd intent/spec verbs - #22

Merged
REPPL merged 5 commits into
mainfrom
auto/intent-lifecycle-slice-1
Jul 11, 2026
Merged

feat: itd-80 intent-lifecycle slice 1 — native spec store + abcd intent/spec verbs#22
REPPL merged 5 commits into
mainfrom
auto/intent-lifecycle-slice-1

Conversation

@REPPL

@REPPL REPPL commented Jul 11, 2026

Copy link
Copy Markdown
Owner

First wired vertical of the intent-lifecycle automation (itd-80, slice 1). Delivers the native spec store and the abcd intent / abcd spec verbs that reach it. Reconcile and the fidelity audit land in follow-up phases on this branch.

What's in this PR

  • internal/core/spec — minimal directory-as-truth native spec store. Specs live under .abcd/development/specs/{open,closed}/spc-N-<slug>.md; the bucket is the status (no status: field). Load / NextID / Create / Close / Lookup / ByIntent, with the ID-anchored intent: link. NextID mints max(spec files ∪ intent spec_id) + 1, so it respects itd-3's reserved spc-1 without a backing file (first mint is spc-2).
  • internal/core/intentPlan / Link / Status. abcd intent plan <itd-N> validates the ## Acceptance Criteria gate (itd-1), mints a spec, writes the bidirectional link + kind: standalone, and moves the intent drafts/ → planned/. Fail-closed by construction: the only transient frontmatter state is lint-valid in both buckets, and Plan is retry-safe (reuses an existing spec for the intent rather than minting a duplicate).
  • internal/core/frontmatter — shared frontmatter line-scanner, extracted so spec and intent share one copy instead of a third (one-canonical-primitive). spec migrated onto it; lint and memory copies flagged for a later behaviour-preserving migration.
  • CLI wiringabcd intent (bare render + plan / link) and abcd spec (bare render + close), through the existing render() / --json / exitError patterns. Bare invocation renders lifecycle status and never mutates.

Not in this PR (follow-up phases on this branch)

  • Phase 3 — the deterministic reconcile inside abcd spec close (spec close → linked intent planned → shipped) + a spec_lifecycle record-lint rule.
  • Phase 4 — the host-delegated verdict-ingest transport → ## Audit Notes (security-reviewed — trust boundary).
  • Phase 5 — dogfood: drive itd-80 through the whole pipeline.

Quality

  • Test-first throughout; make preflight and make record-lint both exit 0.
  • ruthless-reviewer pass: verdict SHIP, no FIX-FIRST. Its two substantive NICE-TO-HAVEs (retry-safe Plan; route spec.Create through the shared atomic-writer to regain the fsync + delete the third copy) plus symlink-guard and clobber-refusal hardening were applied in the fix: commit, test-first.
  • No new dependencies.

Part of itd-80; the intent is the pipeline's dogfood payload and ships through this machinery once Phases 3–5 land.

Assisted-by: Claude:claude-opus-4-8

REPPL added 5 commits July 11, 2026 17:48
itd-80 is the dogfood payload for the intent-lifecycle pipeline: a
standalone intent whose acceptance criteria ARE the steel thread, to be
driven drafts->planned->shipped through the machinery it specifies.
Records the build sign-off, the option-b dogfood approach, and the
spc-N minting rule (max(spec files U intent spec_id)+1 => first mint spc-2).

Assisted-by: Claude:claude-opus-4-8
Minimal directory-as-truth spec store: specs live under
.abcd/development/specs/{open,closed}/spc-N-<slug>.md, the bucket IS the
status (no status: field). Exposes Load / NextID / Create / Close /
Lookup / ByIntent with the ID-anchored intent: link. Trust-boundary
guards: spc-/itd- id regexes validated before any path is built,
symlink refusal, regular-file + size cap; missing specs/ is soft,
malformed frontmatter is a hard error. Dependency-free (private copy of
the lint frontmatter line-scanner; no YAML lib).

NOT wired yet — Phase 2 adds the abcd intent / abcd spec verbs that reach
it. Part of itd-80.

Assisted-by: Claude:claude-opus-4-8
Consolidates the frontmatter line-scanner (leading ---…--- block,
top-level keys, first-key-wins, 1-based lines, IsNull) into one home and
migrates internal/core/spec onto it, deleting spec's private copy. Behaviour-
preserving: spec's tests pass unchanged. lint's and memory's copies remain
(pre-existing) and are flagged for a later migration — one-canonical-primitive.

Assisted-by: Claude:claude-opus-4-8
…ose)

New internal/core/intent (Plan/Link/Status) wired via internal/surface/cli:
- abcd intent            bare render of lifecycle status (read-only)
- abcd intent plan <itd-N>   validate ## Acceptance Criteria, mint a native
                             spec, write the bidirectional link + kind:standalone,
                             move drafts/->planned/ (fail-closed: the only
                             transient frontmatter is lint-valid in both buckets)
- abcd intent link <itd-N> <spc-N>   retroactively link an existing spec
- abcd spec              bare render of spec status
- abcd spec close <spc-N>    marks a spec done (open->closed); the linked-intent
                             reconcile lands in phase 3

record-lint stays green across a plan (TestPlanResidualPassesRecordLint runs the
real lint engine). Part of itd-80.

Assisted-by: Claude:claude-opus-4-8
… clobber guards

From a ruthless-review pass (verdict SHIP, no blockers):
- Plan is now retry-safe: refuses a draft that already carries a spec_id,
  and reuses an existing spec for the intent (via store.ByIntent) instead
  of minting a duplicate when a prior rename failed mid-flight.
- spec.Create routes through fsutil.WriteFileAtomic (regains the fsync +
  parent-dir sync) and the private atomicWrite third copy is deleted
  (one-canonical-primitive); spec markdown mode aligned to 0o644.
- maxIntentSpecNum gains the symlink-dir refusal the other readers enforce.
- Plan and spec.Close refuse to overwrite an existing rename destination
  (fail-closed; no silent data loss). Part of itd-80.

Assisted-by: Claude:claude-opus-4-8
@REPPL
REPPL merged commit 9bc0587 into main Jul 11, 2026
12 checks passed
@REPPL
REPPL deleted the auto/intent-lifecycle-slice-1 branch July 11, 2026 16:57
REPPL added a commit that referenced this pull request Jul 12, 2026
The acceptance test for itd-80's own slice: itd-80 driven drafts->planned->
shipped by the machinery it specifies, not by hand. Live cycle on the on-main
pipeline (PRs #22/#24/#26):
  abcd intent plan itd-80   -> mints spc-2 (spc-1 reserved by itd-3 skipped),
                               links, moves drafts->planned
  abcd spec close spc-2     -> reconcile ships itd-80 planned->shipped, parks
                               OWED review rcp-1c213fa02f85
  abcd intent review ingest -> machine fidelity audit written to ## Audit Notes;
                               re-ingest is a verified no-op
Rollup 6 MET / 1 MET_WITH_CONCERNS / 0 NOT_MET / 0 INCONCLUSIVE. The one concern
(ac-3): the review request references the delivered diff as host-supplied rather
than abcd-captured — a deliberate adr-25 transport-agnostic divergence. Adds the
spc-2 native spec record (closed). record-lint green throughout (spec_lifecycle
cross-check on the new spc-2<->itd-80 link passes).

Assisted-by: Claude:claude-opus-4-8
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