Skip to content

chore(aiwf): catch up to v0.1.1#7

Merged
23min merged 51 commits intomainfrom
chore/aiwf-v0.1.1
May 3, 2026
Merged

chore(aiwf): catch up to v0.1.1#7
23min merged 51 commits intomainfrom
chore/aiwf-v0.1.1

Conversation

@23min
Copy link
Copy Markdown
Owner

@23min 23min commented May 3, 2026

Summary

  • Bump aiwf to v0.1.1 (binary already installed locally; this catches the consumer repo up to the new surface).
  • Drop deprecated actor: key from aiwf.yaml; pin aiwf_version: v0.1.1. Doctor now clean.
  • CLAUDE.md: extend verb list (update, upgrade, show, whoami, authorize, full contract surface, --audit-only); add provenance/principal note; add tdd_phase Hard Rule for logic-bearing ACs.
  • M-067 & M-068: tighten 2 vague AC titles (m-E25-01M-066, README → golden-output-canary.md); add tdd_phase: red to logic-bearing open ACs (selective per the new rule). AC-9 / AC-14 titles kept short — bodies already carry the detail.

Verification

  • aiwf doctor: clean; pin matches binary v0.1.1; skills byte-equal; hooks installed.
  • aiwf check: 0 findings.
  • aiwf show M-067 / M-068: phase column populated correctly per the selective rule.
  • AC shape audit (one-shot script, not committed): 0 findings across 68 milestones — confirms (4) status reconciliation and (5) shape/numbering are clean tree-wide.

Out of scope (separate PRs / branches)

  • Provenance backfill of historical untrailered entity commits. v0.1.1's aiwf check filtering may make this unnecessary — the historical warnings disappeared after this branch pushed. Will re-evaluate after this PR merges; if needed, that PR must be merged with --no-ff (squash would destroy the audit trailers).
  • M-066 and M-069 AC tightening + tdd_phase adoption. To be applied directly on milestone/M-066-edge-flow-authority-decision after this PR squash-merges and main is merged back into the milestone branch (M-066 is in-progress there with 2 ACs unique to that branch; M-069 doesn't exist on main yet).
  • Spec body cleanup of legacy planning shortnames (m-E25-01/02/03 references in M-066/067/068 bodies). Belongs on the milestone branch.

Test plan

  • aiwf doctor clean
  • aiwf check: 0 errors, 0 warnings
  • aiwf show M-067 and M-068 show phase: red on the correct ACs
  • Reviewer confirms tightened AC text (M-067/AC-1, M-068/AC-3) matches intent
  • Squash-merge to main

🤖 Generated with Claude Code

23min and others added 30 commits May 1, 2026 19:37
… migration

- install Go 1.22.10 via tarball in init.sh (devcontainer Go feature fails
  on the .NET base image's stale yarn apt source)
- install aiwf via go install + branch-tip SHA resolved through git ls-remote
  (go install rejects slash-named branches like poc/aiwf-v3)
- hardcode user home in remoteEnv PATH; ${containerEnv:HOME} doesn't resolve
  for new entries in this devcontainer setup
- pin aiwf-extensions and wf-rituals plugins via .claude/settings.json
  (Project scope; manual edit because /plugin install confused itself across
  per-project bookkeeping)
- commit auto-generated devcontainer-lock.json for reproducible feature pins

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- living plan for re-platforming from v1 (.ai submodule + sync.sh +
  generated adapters) to v3 (aiwf Go binary + ai-workflow-rituals
  plugin marketplace)
- Phase 0 closed: 6 open questions settled (history scope, ID stability,
  ADR path, hook timing, plugin scope, devcontainer Go install)
- Phase 1 closed: aiwf installed, doctor self-check 22/22 green, rituals
  plugins enabled, skill audit done from cache (3 acceptable gaps, no
  blockers)
- migration log appended; archives to work/migration/completed/ on cutover
- Q4 (hook timing) closed by upstream change to aiwf core: self-guarding
  pre-push hook landed on poc/aiwf-v3 (commit ≤53393ed) plus an
  Options.SkipHook flag for husky/lefthook composition

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- project_e22.py: uv PEP-723 script-mode projector (ruamel.yaml,
  LiteralScalarString for body); reads E-22 spec, synthesizes frontmatter
  from prose **ID:** / **Status:**, strips H1+ID+Status from body, emits
  single-entity aiwf import manifest
- e22-spike.yaml: generated single-entity manifest (regenerable)
- aiwf import --dry-run reports zero error findings, exit 0
- finding logged: aiwf derives destination dir slug from title, not source
  dir name; settle slug-preservation decision before Pass B mass projection

Phase 2 Pass A complete. Plan updated with passes A–G, status-mapping table,
authoritative aiwf status sets per kind.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…green dry-run

- project_epics.py replaces project_e22.py: accepts list of E-NN ids
  (Pass B = E-13/E-14/E-15/E-22), per-epic loop, accumulator manifest,
  skip-log.md emission
- status mapping covers planning/proposed/paused/in-progress/superseded/
  absorbed/active/cancelled/complete/done; case-insensitive lookup
- handles three new input shapes: missing **Status:** (default proposed
  + skip-log), `superseded by ...` prose (maps to cancelled), parenthesized
  qualifier on **Status:** line (preserved as `> **Status note:** ...`
  blockquote prepended to body)
- emits skip-log.md only when findings exist; cleans up stale log otherwise
- delete e22-spike.yaml + project_e22.py (Pass A artifacts subsumed)
- aiwf import --dry-run on epics-active.yaml: 4 plans, 0 findings, exit 0
- plan updated with Pass B Q&A settlements (E-14 cancelled, E-18 active,
  paused→active, in-progress→active, superseded→cancelled)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…dry-run

- project_epics.py extended for milestones: discover m-EXX-NN-*.md (excluding
  -tracking and -log siblings), parse two H1 shape variants (prose **ID:**
  line vs. id-embedded H1 `m-EXX-NN — Title`), map statuses, resolve
  depends_on within manifest scope, emit id-map.csv
- Q2 revised: explicit M-NNN computed by projector (deterministic order:
  epic-id ascending, milestone-old-id ascending within epic) instead of
  `id: auto`. Reason: aiwf manifest reference fields (depends_on) can only
  resolve against ids that are explicitly declared at manifest time
- depends_on filtering: milestone-target deps mapped through id-map; epic-
  target deps (e.g. m-E18-01 → E-20) dropped from frontmatter with skip-log
  finding (body retains the prose)
- E-18 (in-progress) → active per status mapping
- 11 m-E18-NN milestones → M-001..M-011 (statuses all `done` from `complete`)
- aiwf import --dry-run on epics-active.yaml: 16 plans, 0 errors, exit 0

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

- find_epic_dir walks both work/epics/ and work/epics/completed/
- is_completed_dir helper detects completed/ parents
- dir-location override extended to milestones: completed/ epic dir →
  all child milestones forced to status `done` regardless of source
- two new shape variants handled:
  - YAML frontmatter (`--- ... ---`) for E-23, E-24 epics + milestones
  - full-slug `**ID:**` values (m-E16-NN-rest-of-slug) normalized via
    MILESTONE_OLD_ID_RE
- H1 separator broadened from `[—-]` to `[:—-]` (E-23/E-24 use `:`)
- milestone status falls back to YAML frontmatter `status:` when prose
  `**Status:**` line absent
- yaml_id matched against expected epic prefix (E-23-slug, E-24-slug)
- aiwf import --dry-run epics-active.yaml: 12 epics + 53 milestones = 65
  writes, 0 errors, exit 0
- id-map.csv now 53 entries (M-001..M-053)
- skip-log: 12 findings (10 noise from `**Epic:**` field carrying title
  instead of id; 2 real: E-13 default-status, m-E18-01 epic-dep)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…5 milestones

- generalize milestone-id matching via _MILESTONE_ID_PATTERNS alternation:
  M-10\.NN (E-12) | m-ec-pN[a-z]?\d? (E-10) | m-svui-NN (E-11) | m-E\d+-\d+
  (generic). Single MILESTONE_OLD_ID_RE / MILESTONE_SPEC_RE built from the
  list — adding new patterns is one line
- discover_milestone_specs filename filter excludes -tracking, -log, -review
  (E-10 has review docs that aren't milestones)
- derive_title_from_h1 helper strips `Milestone:` prefix and id-with-slug
  prefix; handles `# Milestone: m-svui-01-scaffold — Title`,
  `# m-ec-p1 — Title`, `# m-E23-01: Title` uniformly
- yaml-id matching uses the same alternation regex (any kind of milestone id)

Pass E achieves full Phase 2 scope coverage:
- 15 epics: 5 active (E-13/14/15/18/22) + 9 completed-id'd + E-11 (active
  outlier)
- 65 milestones: 53 generic + 7 m-ec-pN (E-10) + 2 m-svui-NN (E-11) +
  3 M-10.NN (E-12)
- aiwf import --dry-run epics-active.yaml: 80 writes, 0 errors, exit 0
- id-map.csv: 65 entries (M-001..M-065)
- skip-log: 25 findings, mostly noise from `**Epic:**` field carrying epic
  title instead of id; ~3 real (E-13 default-status, m-E18-01 epic-dep,
  E-11 default-status)

Phase 2 (projector) closed. Phase 3 (pre-process source) and Phase 4
(import) are next.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ities total)

- parse_decisions splits work/decisions.md by `## D-YYYY-MM-DD-NNN:` H2
  headings; reads body verbatim between headings; extracts status from
  prose `**Status:**` line (active → accepted, superseded → superseded,
  withdrawn → rejected); sorts by (date, seq); allocates D-001..D-053
- parse_gaps splits work/gaps.md by `## ` H2 headings (skipping the
  "Open Questions" footer per GAP_NON_ENTITY_HEADINGS); uses git blame
  --date=short to recover per-line creation dates; sorts by (date, line);
  allocates G-001..G-033; status from `(resolved YYYY-MM-DD)` title-suffix
  → addressed, else open
- title cleanup for gaps: `(resolved YYYY-MM-DD)` suffix stripped from
  title (body retains it as historical context if mentioned in prose)
- build_manifest extended to emit decision + gap entries alongside
  epics + milestones in a single combined manifest
- id-map.csv now includes both milestones (m-EXX-NN → M-NNN) and
  decisions (D-YYYY-MM-DD-NNN → D-NNN); gaps are new-only (no v1 ids)
- aiwf import --dry-run epics-active.yaml: 166 plans, 0 errors, exit 0
- 25 findings, all carried from prior passes (Epic-field noise + 3 real)

Phase 2 (full projector) closed.

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

- rewrite_body_text segments fenced code blocks (```...```) and inline
  code spans (`...`) as placeholders, applies id-map substitutions on
  remaining prose, then restores placeholders. Code stays historically
  accurate (e.g., `git log --grep "m-E18-13"` example commands continue
  to reference the literal commit-trailer text in git history)
- regex per old-id: (?<![\w-]){escaped}(?:-[a-z0-9-]+)?(?![\w-]) —
  matches both bare-id (m-E18-13) and full-slug (m-E18-13-session-
  evaluator) forms; collapses both to bare new id (M-010). Word-boundary
  lookarounds prevent matching inside larger identifiers
- substitutions ordered by len(old_id) DESC so longest patterns match first
  (defense in depth against prefix collisions, even though word boundaries
  also guard against them)
- applied during projection (Q2 settled: inline; single source of truth)
  after full id-map is built (milestones + decisions); epics keep ids,
  gaps have no v1 id
- verified: 0 occurrences of m-E18-13 post-rewrite; 7 of M-010; E-22 body
  references M-002, D-045, M-043 etc. cleanly
- aiwf import --dry-run epics-active.yaml: 166 plans, 0 errors, exit 0

Phase 2 (projector) closed. Manifest is import-ready. Phase 3 (pre-process
source — relocate non-id'd completed/ dirs to work/archived-epics/, fix
the 3 real findings in skip-log) is next, then Phase 4 (real import).

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

Phase 3 (pre-process source) per Q1 settlement and the 3 real skip-log findings:

- relocate 17 non-id'd dirs from work/epics/completed/ to work/archived-epics/
  via git mv (history preserved). work/epics/completed/ now contains only the
  9 E-NN dirs; pre-E-NN-convention historical work stays grep-able on disk
  but out of aiwf's walked roots
- E-13/path-analysis/spec.md: add `**Status:** proposed` (no roadmap signal
  to override the missing-status default; explicit beats implicit)
- E-11/svelte-ui/spec.md: add `**Status:** paused` (matches roadmap's
  "paused after M6"; maps to aiwf `active` per the v1→v3 status table)
- m-E18-01's `**Depends on:** E-20` (epic-target) accepted as-projected:
  aiwf milestone.depends_on requires milestone targets and body prose
  retains the dep
- re-projection: skip-log shrinks from 25 → 23 findings (1 real + 22
  noise from `**Epic:**` field carrying title); aiwf import --dry-run
  166 plans, 0 errors, exit 0

Phase 3 closed. Manifest is import-ready; Phase 4 is the cutover.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
aiwf-verb: import
aiwf-actor: human/peter
aiwf init writes:
- aiwf.yaml (consumer config; aiwf_version=dev, actor=human/peter)
- .gitignore append for materialized skill cache:
    .claude/skills/.aiwf-owned
    .claude/skills/aiwf-*/

aiwf init also installs (not tracked):
- .git/hooks/pre-push (runs aiwf check; self-guards on missing aiwf.yaml)
- .git/hooks/pre-commit (runs aiwf status --format=md to regenerate STATUS.md)
- 8 materialized skills under .claude/skills/aiwf-{add,check,contract,history,
  promote,reallocate,rename,status}/SKILL.md

Verified:
- aiwf doctor: all green (config ok, 8 skills byte-equal to embed, no
  collisions, hook + pre-commit ok, plugin detected)
- aiwf check: 0 errors + 4 warnings (gap-resolved-has-resolver — those 4
  gaps were marked addressed at projection but have no addressed_by; not a
  blocker; can be enriched in Phase 5)
- aiwf-* skills picked up by Claude Code session (visible in skill list)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Phase 4 closed — manifest imported atomically, aiwf init complete, doctor
green, check clean, all surfaces (history/render/status) functional.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CLAUDE.md surgical rewrites:
- header: replace "AI Framework v2 at .ai/" with v3 narrative (aiwf binary
  + ai-workflow-rituals plugins; 6 entity kinds)
- session-start: drop work/decisions.md / work/gaps.md / work/agent-history
  pointers; point at `aiwf status` and the migration plan instead
- hard rules: drop ".ai/rules.md" pointer; drop "identify the agent first"
  (covered by plugin agent prose)
- agent routing: rewrite table to point at aiwfx-* skills + plugin agents
  rather than .claude/agents/*.md generated paths; flag the wrap-milestone
  → dead-code-audit chaining gap (mitigation: builder/reviewer prose)
- delete "Framework Sources" section entirely (no v3 equivalent — `aiwf
  doctor` and `/plugin install` replace the pointer-doc model)
- replace "Resolved Artifact Layout" table with "Repo Layout" + verb list
- update Workflow Artifact Layout subsection to reference aiwf.yaml + the
  aiwfx-track convention rather than .ai-repo/config/artifact-layout.json
- update Milestone Status Sync to use aiwf promote semantics

CLAUDE.md Current Work section: 80+ lines of dense old-id references
rewritten via id-map.csv using the same body-rewrite logic from Pass G
(rewrite_claude_md.py — one-off helper). m-E18-13 → M-010, D-2026-04-15-032
→ D-045, etc. Verified zero residual v1 ids in CLAUDE.md.

.claude/settings.json: remove SessionStart hooks (bash .ai/tools/scratch-
audit.sh and .ai-repo/bin/wf-graph) — both pointed at v1 paths that
disappear in Group C. Kept statusLine + enabledPlugins.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…delete v1 generated content

Repo-private skills now committed (newly trackable after .gitignore update):
- .claude/skills/dead-code-audit/SKILL.md (ported from .ai/skills/) +
  3 recipes (.claude/skills/dead-code-audit/recipes/dead-code-{dotnet,
  rust,typescript}.md) ported from .ai-repo/recipes/. Recipe-path refs
  inside SKILL.md sed-rewritten from .ai-repo/recipes/ to the new home.
- .claude/skills/devcontainer/SKILL.md (was on disk, gitignored; now
  committed)
- .claude/skills/ui-debug/SKILL.md (same)

.gitignore: drop wholesale `.claude/skills/` ignore (no longer needed
since v1's sync.sh isn't writing there). Keep `.claude/skills/aiwf-*/`
+ `.claude/skills/.aiwf-owned` ignores from `aiwf init` (aiwf core
materializes these; owns regeneration). Keep `.claude/agents/` ignored
(no plan to commit project-local agent overrides; v3 ships agents via
the rituals plugin cache).

Disk-only deletes (gitignored — no git op):
- 21 .claude/skills/wf-*/ dirs (v1 framework-generated; replaced by
  rituals plugin cache for the 4 ported wf-* skills)
- 4 .claude/agents/*.md files (replaced by aiwf-extensions plugin)
- .github/skills/ tree (22 dirs — Copilot adapter; v1 sync.sh output)

Git-tracked deletes:
- work/agent-history/{builder,planner,reviewer}.md (3 files;
  discontinued — v3 uses `aiwf history` instead)
- work/decisions.md (398 lines; replaced by 53 D-NNN files in
  work/decisions/)
- work/gaps.md (1140 lines; replaced by 33 G-NNN files in work/gaps/)

Verified: `aiwf check` still green (0 errors, 4 informational warnings
unchanged). Skill list in Claude Code session shows only v3 surface
(aiwf-*, repo-private dead-code-audit/devcontainer/ui-debug, and
wf-patch/wf-tdd-cycle/wf-review-code/wf-doc-lint from the rituals
plugin cache).

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

Both v1 source dirs and v3 imported dirs coexisted on disk after the
import (different title-derived slugs). With v3 entities verified import-
clean and `aiwf check` green, the v1 sources are duplicates and can go.

Deleted:
- 6 v1 active-dir epics:
    work/epics/E-11-svelte-ui/
    work/epics/E-13-path-analysis/
    work/epics/E-14-visualizations/
    work/epics/E-15-telemetry-ingestion/
    work/epics/E-18-headless-pipeline-and-optimization/
    work/epics/E-22-model-fit-chunked-evaluation/
- 9 v1 completed-dir epics:
    work/epics/completed/E-10..E-24 (all 9 E-NN-prefixed dirs;
    work/epics/completed/ now empty and auto-pruned by git)
- work/epics/epic-roadmap.md (handwritten roadmap; replaced by
  `aiwf render roadmap` → ROADMAP.md from frontmatter)

Kept:
- 15 v3 epic dirs at work/epics/E-NN-<title-slug>/ (the imported entities)
- work/epics/unplanned/ (13 slug-only exploration dirs; out of migration
  scope per Q1; left as historical/proposal context)

Verified post-delete: `aiwf check` still passes (0 errors / 4 warnings;
unchanged from pre-delete state).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
v1 framework teardown — final step of Phase 5:

- delete `.ai/` git submodule (handwritten v1 framework — agents,
  skills, sync.sh, paths.md, rules.md, templates, tools). Steps:
  edit .gitmodules to drop the [submodule ".ai"] block, deinit, git rm,
  remove .git/modules/.ai cached metadata
- delete `.ai-repo/` (entire 7.6 MB tree — config overrides, recipes,
  rules, scratch, agents, skills, bin). 11 tracked files; .ai-repo/bin/
  was gitignored

Residual cleanup:
- .claude/rules/ai-framework.md (v1 sync.sh output; gitignored, not
  tracked, just removed from disk)
- .github/copilot-instructions.md (same)
- .claude/settings.json: drop the statusLine block (the referenced
  .claude/statusline.sh was a v1 sync.sh output, also gone)
- .gitignore: drop legacy v1 entries that are no longer relevant
  (.github/copilot-instructions.md, .github/skills/, .claude/rules/
  ai-framework.md, .claude/statusline.sh, .codex/instructions.md
  duplicate). Keep .codex/ (Codex tooling, line 56) and the aiwf-*
  cache rules (lines 113-114, owned by aiwf init/update)

Verified: aiwf doctor all green; aiwf check 0 errors / 4 unchanged
warnings (gap-resolved-has-resolver informational).

Phase 5 closed. v1 framework no longer present in this repo.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Upstream aiwf landed I2 (acceptance criteria as first-class kernel concept)
on 2026-05-01: milestone schema gains optional `acs[]` and `tdd` fields;
composite ids `M-NNN/AC-N`; per-AC status (open/met/deferred/cancelled)
and tdd_phase (red/green/refactor/done); kernel validates body coherence
(`### AC-N — Title` headings paired by id with frontmatter acs[]).

After /plugin update aiwf-extensions and a fresh `aiwf schema milestone`
showed the new optional fields, this lift writes the structured form:

- work/migration/scripts/lift_acs.py — one-off helper. Parses each
  milestone's body `## Acceptance criteria` section across four observed
  v1 shapes:
    a) checkbox list  `- [ ] / - [x] <content>`
    b) numbered list  `1. <content>` / `1. **AC-N: Title.** <prose>`
    c) plain dash bullets without checkboxes
    d) H3-AC-style — each `### AC1 — Title` (or `### AC-1: Title`) IS the
       AC, with rich prose underneath
  Mode (a/b/c) gets body section rewrite (replace list with `### AC-N —
  Title` blocks). Mode (d) keeps body prose intact, just normalizes
  heading shape (`### AC1` → `### AC-1 — Title`) for kernel coherence.
- 65 milestone files updated in place: frontmatter `acs:` field added with
  id, title, status; body section restructured per mode

Status mapping:
- For milestones with `status: done`: every AC → `met` (avoids
  `milestone-done-incomplete-acs` finding; the milestone is done so the
  work happened — v1 used checkboxes loosely)
- For non-done milestones: checkbox `[x]` → met, `[ ]` → open;
  numbered/plain/H3-AC items default to `open`
- TDD field omitted (defaults to `none`; we have no historical TDD-phase
  records to backfill)

Final tally: 588 ACs across 65 milestones (581 met / 7 open — the 7 are
M-062 Run Orchestration, E-11's only in_progress milestone). `aiwf check`
clean (0 errors, 4 unchanged informational warnings). `aiwf status` now
renders AC progress per milestone (e.g., "M-007 — Sensitivity Analysis ·
ACs 13/13 met").

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

Upstream aiwf landed G20 (commit 4b13a0f) on 2026-05-01 23:24: an
acs-title-prose warning fires when an AC title is >80 bytes UTF-8, contains
markdown formatting (`**`, `__`, backticks), contains link brackets, has
newlines, or looks multi-sentence. Our initial AC lift wrote v1 content
verbatim into title fields, tripping the detector on 533/588 ACs.

This refactor:

- work/migration/scripts/refactor_ac_titles.py — pairs with lift_acs.py.
  Detector mirrors aiwf's IsProseyTitle (byte length, not rune count —
  Go's `len()` counts bytes; em-dash is 3 bytes UTF-8). For each prose-y
  title, derives a short label by stripping markdown / `AC-N:` prefix /
  trailing detail, preferring "label. detail" or "label: detail" splits
  if a clean head exists, otherwise truncating at 70 bytes at word
  boundary.
- 63 milestones updated (2 already-clean): 533 AC titles shortened. Body
  `### AC-N — <old title>` headings rewritten to use the new label;
  original full content preserved as body prose under the heading (only
  injected when no prose was already there, avoiding duplication for
  multi-line-continuation cases and H3-AC-style milestones).
- Upgraded aiwf binary to 4b13a0f0bb26 (latest poc/aiwf-v3).

Verified: aiwf check 0 errors / 4 unchanged warnings (informational
gap-resolved-has-resolver). aiwf show M-007 displays clean short labels
with full detail preserved in body prose.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
20 commits implementing a full re-platform of the AI workflow framework
from v1 (.ai submodule + sync.sh + generated adapters) to v3 (aiwf Go
binary + ai-workflow-rituals Claude Code plugin marketplace).

Phases (full record in work/migration/aiwf-v3-plan.md):

- Phase 0: planning + 6 design Q&As (history scope, ID stability, ADR
  path, hook timing, plugin scope, devcontainer Go install)
- Phase 1: devcontainer adds Go 1.22 + aiwf install in init.sh; aiwf
  doctor self-check 22/22 green; aiwf-extensions + wf-rituals plugins
  enabled at Project scope
- Phase 2: projector (work/migration/scripts/project_epics.py, ~600
  lines, passes A–G). Produced 166-entity manifest (15 epics +
  65 milestones + 53 decisions + 33 gaps) with id-map.csv (118
  entries) and skip-log.md (25 findings; 22 noise + 3 real)
- Phase 3: pre-process source — relocated 17 non-id'd completed/ dirs
  to work/archived-epics/; patched E-11 (paused) and E-13 (proposed)
  source statuses
- Phase 4: cutover — aiwf import landed all 166 entities atomically
  (commit 40840ad with aiwf-verb: import / aiwf-actor: human/peter
  trailers); aiwf init wrote aiwf.yaml + materialized 8 aiwf-*
  skills + installed self-guarding pre-push + STATUS.md pre-commit
  hooks
- Phase 5: v1 teardown — 4 commits removing CLAUDE.md v1 references,
  SessionStart hooks, .claude/skills/wf-*/, .claude/agents/*,
  .github/skills/, work/agent-history/, work/decisions.md,
  work/gaps.md, 15 v1 epic dirs, .ai/ submodule, .ai-repo/
- I2 alignment: 588 ACs lifted into structured milestone frontmatter
  (matched upstream aiwf I2 release; acs[] field with id/title/status;
  ### AC-N — Title body headings)
- G20 alignment: 533 prose-y AC titles refactored into short labels
  with full detail preserved as body prose

Final tree state:
- aiwf doctor: all green
- aiwf check: 0 errors, 4 informational gap-resolved-has-resolver
  warnings (gaps marked addressed without addressed_by — opportunistic
  enrichment future work)
- 15 epics, 65 milestones, 588 ACs (581 met / 7 open), 53 decisions,
  33 gaps — all kernel-validated

Migration scratch (work/migration/) retained for historical reference;
id-map.csv stays grep-able for old-id ↔ new-id lookups indefinitely.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Caught after the migration merge — surfaces v1 left behind that aren't
tied to .ai/ or .ai-repo/:

- work/graph.yaml (52KB) — v1 wf-graph canonical artifact
- work/graph-seed-report.md (14KB) — v1 wf-graph seed report
- work/graph-scan.json (109KB, gitignored) — wf-graph scan output
- work/graph.yaml.lock (empty, gitignored) — wf-graph advisory lock
- work/milestones/README.md — v1 "compatibility stub" doc
- work/releases/ (empty dir) — pre-existing empty placeholder

The wf-graph tooling lived in .ai-repo/bin/ which Phase 5 Group C deleted
(commit b80d4c3); these are the artifacts it produced. aiwf v3 has no
equivalent — `aiwf check` and `aiwf history` cover graph-validation.

.gitignore: drop the wf-graph entries (work/graph-scan.json,
work/graph.yaml.lock) since the tool that produced them is gone.

aiwf check: still 0 errors / 4 unchanged informational warnings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…d, submodule metadata

Three more v1 leftovers caught after the migration merge:

- ai_old/ — 22 tracked files (96 KB) under a non-dotfile dir; a v1
  framework backup (agents/instructions/skills/README) predating the
  .ai/ submodule entirely
- current_status.md (2026-04-13) — hand-maintained session-handoff
  context doc. v3 generates STATUS.md automatically via the pre-commit
  hook; the hand-maintained file is now stale and redundant
- .git/modules/ai-workflow/ (6.2 MB) — cached submodule metadata for
  the .ai/ submodule. Phase 5 Group C cleared .git/modules/.ai/ but
  the actual submodule key in .gitmodules was "ai-workflow" (not
  ".ai"), so this directory was missed. Cleared now.

aiwf check: still 0 errors / 4 unchanged informational warnings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
aiwf-verb: rename
aiwf-entity: E-18
aiwf-actor: human/peter
Per the archeology: all four warning-flagged gaps were resolved by
chore/ patch branches (not aiwf milestones), so addressed_by had no
direct entity to point at. Linking each to its contextually-related
epic instead — honest semantic association without claiming a specific
milestone owned the fix.

- G-015 (silent grep-guard scripts; created + resolved 2026-04-08 via
  chore/grep-guard-cleanup) → addressed_by: E-19 (was the active epic
  whose merge sanity check surfaced the bug)
- G-027 (ProvenanceEmbedder dead path), G-028 (GridDefinition rename),
  G-029 (Template Legacy aliases) — all filed retroactively 2026-04-26
  to document work that landed 2026-04-25 in chore/e-24-cleanup-wave
  (merge 86c6549) → addressed_by: E-24

aiwf check: ok — no findings (was: 4 gap-resolved-has-resolver warnings).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… follow-up

aiwf v3's gap schema has `discovered_in` (entity context) but no
`discovered_by` field for original-author. The migration's bulk
`aiwf import` collapses per-entity provenance into one undifferentiated
trailer, losing the per-gap author signal. Archeology can recover this
from git blame on the deleted v1 work/gaps.md (preserved as
work/migration/scripts/gap_archeology.py), but applying it now is
premature — wait for upstream to ship an improved provenance model.

Adds a "Deferred follow-ups" section to CLAUDE.md (sits between Repo
Layout and Project-Specific Rules) so it surfaces every session.
Convention: each entry names trigger + action; remove when done.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
aiwf cancel G-021 --reason "v1 framework adapter-ignore concept no
longer exists post-migration; .ai/, .ai-repo/, sync.sh, and the
adapter-generation pipeline were all removed in Phase 5 (commits
98deaa2..b80d4c3). The .codex/ ignore-list concern is structurally
moot in v3."

(Cancel transition succeeded; commit failed due to a stale .git/
index.lock so manual commit follows.)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… close G-030/G-031

Two gaps (G-030 FFI-based engine evaluator, G-031 backend language choice for session service) read as design exploration with watchpoints, not deferred engineering work. Per v3 truth-discipline (notes = exploration, gaps = deferred work items), they belong in docs/notes/.

Adds docs/notes/ffi-vs-subprocess-engine-boundary.md (from G-030 body) and docs/notes/session-service-language-choice.md (from G-031 body). Both gaps closed as wontfix with body-frontmatter edits (aiwf cancel attempts hit stale .git/index.lock before they could commit). aiwf check: ok — no findings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two read-only scripts produced during post-migration gap review:

- gap_archeology.py — recovers per-gap creation date + author from git blame on the deleted v1 work/gaps.md; parses body for explicit Surfaced/Discovered-during signals + first milestone/epic reference. Backs the deferred-follow-up entry in CLAUDE.md (re-run when aiwf ships improved provenance to backfill discovered_by/discovered_in).

- survey_gaps.py — read-only audit reporting (1) frontmatter-vs-body status mismatches; (2) dead file references; (3) topic clusters (≥2 gaps sharing a token like dag-map / heatmap / FFI / crystal-ball). Useful for periodic gap currency review; surfaced G-021 as moot post-Phase-5.

Both scripts idempotent and read-only; safe to re-run anytime.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…en full parameter set is provided"

aiwf-verb: add
aiwf-entity: G-034
aiwf-actor: human/peter
23min and others added 21 commits May 2, 2026 15:00
Fixed in src/FlowTime.TimeMachine/Orchestration/RunOrchestrationService.cs CreateRunAsync — gates TryReuseExistingRunAsync short-circuit on !DryRun. Test: RunOrchestrationServiceTests.CreateRunAsync_DryRun_DoesNotReuseExistingDeterministicRun.

aiwf-verb: promote
aiwf-entity: G-034
aiwf-actor: human/peter
aiwf-to: addressed
…034)

- RunOrchestrationService.CreateRunAsync short-circuited via
  TryReuseExistingRunAsync before checking DryRun, so a dryRun:true request
  with deterministicRunId:true silently returned the cached real run as
  { isDryRun: false, wasReused: true, plan: null, metadata: <existing> }.
- Gate the reuse short-circuit on !effectiveRequest.DryRun. Dry-runs now
  always fall through to the per-mode planning path and return a plan,
  regardless of whether a run already exists at the deterministic id.
- New regression test
  RunOrchestrationServiceTests.CreateRunAsync_DryRun_DoesNotReuseExistingDeterministicRun
  pins the contract.
- UI: run-config-panel.svelte coerces template parameter defaults to their
  declared type (the templates API hands back numerics as strings).
- E2E: tests/ui/specs/svelte-run-orchestration.spec.ts adds a Playwright spec
  covering all 7 M-062 ACs against the live Sim API + Svelte dev server.

Closes G-034.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Verified by tests/ui/specs/svelte-run-orchestration.spec.ts (live Sim API + Svelte dev server) in commit d9e2dfc.

aiwf-verb: promote
aiwf-entity: M-062/AC-2
aiwf-actor: human/peter
aiwf-to: met
Verified by tests/ui/specs/svelte-run-orchestration.spec.ts (live Sim API + Svelte dev server) in commit d9e2dfc.

aiwf-verb: promote
aiwf-entity: M-062/AC-3
aiwf-actor: human/peter
aiwf-to: met
Verified by tests/ui/specs/svelte-run-orchestration.spec.ts (live Sim API + Svelte dev server) in commit d9e2dfc.

aiwf-verb: promote
aiwf-entity: M-062/AC-4
aiwf-actor: human/peter
aiwf-to: met
Verified by tests/ui/specs/svelte-run-orchestration.spec.ts (live Sim API + Svelte dev server) in commit d9e2dfc.

aiwf-verb: promote
aiwf-entity: M-062/AC-5
aiwf-actor: human/peter
aiwf-to: met
Verified by tests/ui/specs/svelte-run-orchestration.spec.ts (live Sim API + Svelte dev server) in commit d9e2dfc.

aiwf-verb: promote
aiwf-entity: M-062/AC-6
aiwf-actor: human/peter
aiwf-to: met
Verified by tests/ui/specs/svelte-run-orchestration.spec.ts (live Sim API + Svelte dev server) in commit d9e2dfc.

aiwf-verb: promote
aiwf-entity: M-062/AC-7
aiwf-actor: human/peter
aiwf-to: met
…M-062)

- M-062 Run Orchestration: status open -> done. All 7 ACs flipped to met
  via aiwf promote (visible in prior commits 09e4d17..b4b5df5; AC-1 +
  M-062 frontmatter flip got dropped by an interrupted commit and is
  swept into this commit).
- E-11 Svelte UI: status active -> done. M-061 + M-062 in tree both done;
  M5 Inspector + M8 Polish absorbed into E-21; M7 Dashboard deferred.
- G-034 (addressed): set addressed_by: [M-062] so aiwf check sees the
  resolver, clearing the gap-resolved-has-resolver warning.
- CLAUDE.md Current Work: E-11 entry now reads "completed (2026-05-02)"
  with a one-line summary of the fix and G-034.
- STATUS.md regenerated by aiwf — no in-flight epics now visible.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CLAUDE.md was 250 lines; now 153. Cuts that were either duplicating aiwf
state or actively conflicting with it:

- Removed Current Work catalog (~67 lines). Project state lives in
  `aiwf status` + `STATUS.md` (auto-rendered) + per-epic `wrap.md`.
- Removed Hard Rule "Update CLAUDE.md Current Work after starting or
  wrapping a milestone" — duplicate surface that drifts; aiwf owns it.
- Removed `work/epics/completed/E-NN-<slug>/` row from Repo Layout —
  convention isn't actually followed; only one epic was ever moved
  there, aiwf doesn't walk that subtree, and we just reverted an attempt
  to move E-11 across that boundary because refs wouldn't resolve.
- Removed Milestone Status Sync section — restated aiwf behavior as if
  they were rules. Kept the one rule that's still useful — "don't edit
  entity status by hand" — and folded it into Project Layout.
- Fixed Truth Discipline precedence — referred to non-existent
  work/decisions.md (decisions live in work/decisions/D-NNN-*.md per
  the same file's Repo Layout). Now points at decision entities + ADRs.
- Merged duplicate Project Layout sections (workflow tree + source
  tree) into one. Added ui/ (was missing) and Svelte port 5173.
- Collapsed duplicate Conventional Commits guidance (Hard Rules + the
  Branching & Versioning section both said the same thing).
- Folded the Tooling section into Coding Conventions.
- Moved the gap-archeology deferred follow-up out of CLAUDE.md and into
  work/migration/aiwf-v3-plan.md where migration follow-ups belong.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The routing table in CLAUDE.md drifted from what the agents in
~/.claude/plugins/.../aiwf-extensions/agents/*.md actually declare. Cross-
checked each agent's "Skills you drive" list against the table and fixed:

- builder: added aiwfx-record-decision (mid-implementation decisions).
- reviewer: added wf-doc-lint and aiwfx-record-decision; dropped the
  "status promotions via `aiwf promote`" gloss (aiwf promote is a CLI
  verb anyone uses, not a skill the reviewer specifically drives).
- deployer: added wf-patch (for hotfixes between wrap and tag) and
  aiwfx-record-decision.
- planner: matches the spec; unchanged.

Also noted the aiwfx-wrap-epic skill orphan: the plugin ships it but no
agent's frontmatter Skills list claims it. The reviewer's description
mentions "verifies milestone or epic wrap" so reviewer drives it in
practice; flagged inline so the gap is visible.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…Output Canary"

aiwf-verb: add
aiwf-entity: E-25
aiwf-actor: human/peter
aiwf-verb: rename
aiwf-entity: E-25
aiwf-actor: human/peter
Engine-correctness investigation + testing rigor epic — the prerequisite
for E-22 Time Machine and ideally also E-15 Telemetry Ingestion.

Three milestones (decision-first sequencing as a hard constraint):

- m-E25-01 Edge-flow authority decision — ratify the G-032 design call
  (expr nodes vs. topology edge weights vs. both-must-agree) as a D-NNN.
  Default to D-NNN consistent with this repo's pattern (docs/adr/ empty,
  D-053 is the most recent comparable architectural call).
- m-E25-02 Engine + template alignment — implement the chosen authority,
  edit affected shipped templates so ExpectedRunWarnings entries reset
  to zero, add val-warn delta gate to the existing Phase 2 baseline
  canary as a bridge.
- m-E25-03 Golden-output canary — fixture infrastructure under
  tests/fixtures/golden-templates/, sanctioned-regeneration workflow,
  initial pinning across all shipped templates, documentation.

Closes G-032 + G-033 on epic completion. Builds on D-053 (Phase 2
baseline canary deferred the full golden canon — this picks it up).
Sequenced before E-22 (model fit needs trustworthy engine output) and
E-15 (canonical-bundle replay parity benefits from golden canary as the
synthetic-side reference) per D-045 Option A reasoning.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
aiwf-verb: add
aiwf-entity: M-066
aiwf-actor: human/peter
aiwf-verb: add
aiwf-entity: M-067
aiwf-actor: human/peter
aiwf-verb: add
aiwf-entity: M-068
aiwf-actor: human/peter
aiwf-verb: render-roadmap
aiwf-actor: human/peter
Three milestones decompose E-25 Engine Truth Gate per the epic spec's
decision-first sequencing constraint:

- M-066 Edge-Flow Authority Decision (9 ACs) — produce a ratified D-NNN
  naming the edge-flow authority backed by a footprint analysis for all
  three G-032 options. No code, no template edits. Closes G-032's design
  portion. Depends on: nothing.

- M-067 Engine + Template Alignment (13 ACs) — implement the chosen
  authority in the engine, edit the affected shipped templates, reset
  their ExpectedRunWarnings entries to zero in coordinated commits, and
  add the val-warn delta gate to the existing Phase 2 baseline canary.
  Forward-only no-coexistence-window for the rejected authority path.
  Depends on: M-066.

- M-068 Golden-Output Canary (14 ACs) — stand up the golden-output canary
  as a sibling test class, pin all 12 shipped templates with per-fixture
  READMEs, build the sanctioned-regeneration workflow, document the
  canary's contract at docs/testing/golden-output-canary.md, prove the
  canary fires under deliberate perturbation. Closes G-033. Depends on:
  M-067.

Also fixed a propagation error from earlier in the conversation: epic
spec success criteria and M-068 AC-14 referenced moving the epic dir to
work/epics/completed/E-25-…/. That convention is pre-aiwf v1; aiwf v3
keeps epic dirs in place at work/epics/E-NN-<slug>/ regardless of
status (truth lives in frontmatter, not the path). Both references
now correctly say the epic dir stays put and call out the pre-aiwf
convention as not applicable.

Skeleton id-allocation commits already on branch (5d41973 M-066,
e51e124 M-067, 8625916 M-068, fe2bbe1 roadmap regen). This commit lands
the body fills + epic Milestones list refresh.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- aiwf.yaml: drop deprecated actor key; pin aiwf_version to v0.1.1
- CLAUDE.md: extend verb list (update/upgrade/show/whoami/authorize,
  contract subverbs, --audit-only); add provenance/principal note;
  add tdd_phase Hard Rule for logic-bearing ACs
- M-067, M-068: tighten 4 vague AC titles; add tdd_phase: red to
  logic-bearing open ACs (selective per the new rule)

aiwf check: 0 errors; remaining 8 warnings are historical
untrailered-commit findings — addressed in a follow-up PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- M-067/AC-9: revert title to "TDD red-green for engine change"
  (body section already covers the cycle in detail)
- M-068/AC-14: revert title to "Epic closure housekeeping complete"
  (body section already enumerates aiwf promote/wrap.md/ROADMAP regen)
- M-067 body L72: sync AC-1 heading to match new frontmatter title
  (m-E25-01 → M-066)
- M-068 body L84: sync AC-3 heading to match new frontmatter title
  (...and README → ...documented in golden-output-canary.md)

aiwf check: 0 findings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@23min 23min merged commit 0e5425c into main May 3, 2026
1 check passed
23min added a commit that referenced this pull request May 3, 2026
- aiwf.yaml: drop deprecated actor key; pin aiwf_version to v0.1.1
- CLAUDE.md: extend verb list, add provenance/principal note, add tdd_phase Hard Rule
- M-067, M-068: tighten 2 AC titles; add tdd_phase: red selectively to logic-bearing open ACs

aiwf check: 0 errors.

Re-do of #7 after that PR's squash inadvertently collapsed the v3 migration history. Migration history restored on main first via revert (#8); this is the genuine 2-commit catch-up.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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