Skip to content

docs(readme): add OpenAI Codex to Platform-Specific Setup index - #4

Closed
harmjeff wants to merge 1 commit into
mainfrom
fix/readme-codex-toc-entry
Closed

docs(readme): add OpenAI Codex to Platform-Specific Setup index#4
harmjeff wants to merge 1 commit into
mainfrom
fix/readme-codex-toc-entry

Conversation

@harmjeff

Copy link
Copy Markdown
Owner

Summary

The Platform-Specific Setup index in the README was missing an entry for the OpenAI Codex section, even though the section itself already exists further down in the file. This adds the missing index link.

Changes

  • Add - [OpenAI Codex](#openai-codex) to the Platform-Specific Setup index, after GitHub Copilot.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of the project license.

@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Jun 29, 2026
The Platform-Specific Setup index was missing an entry for the
OpenAI Codex section that already exists in the README.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@harmjeff
harmjeff force-pushed the fix/readme-codex-toc-entry branch from 2b65aa2 to 971d70f Compare June 29, 2026 18:47
Comment thread README.md
- [Cline](#cline)
- [Claude Code](#claude-code)
- [GitHub Copilot](#github-copilot)
- [OpenAI Codex](#openai-codex)
Comment thread README.md
- [Cline](#cline)
- [Claude Code](#claude-code)
- [GitHub Copilot](#github-copilot)
- [OpenAI Codex](#openai-codex)
@harmjeff

Copy link
Copy Markdown
Owner Author

Superseded by upstream PR awslabs#452.

@harmjeff harmjeff closed this Jun 29, 2026
harmjeff pushed a commit that referenced this pull request Jun 30, 2026
…ti-repo (2.1.0) (awslabs#429)

* feat(workspace): promote codekb to repo-level aidlc/codekb/<repo>/

* feat(templates): team output-format overrides — resolver + agent skeleton + sensor verify

* feat(memory): relocate rules to aidlc/memory/; re-point loadRules + per-harness native includes

* test: repair stale rule-path + codekb goldens after P0/P5 relocation

P0 (codekb→aidlc/codekb/<repo>/) and P5 (rules→aidlc/spaces/default/memory/,
neutral basenames) changed display paths + rule-file basenames that these
goldens/fixtures embed. The phases' scoped test runs did not cover t43/t66/t103,
so the goldens went stale. Pure relocation repair — no behavioural change.
Test-only: no version bump (AGENTS.md changelog policy).

* feat(dist): seed workspace shell (spaces/default/memory defaults + native includes) + re-rooted .gitignore

* fix(templates): point sensor template lookup at the shipped memory tree + add P6 seam tripwire

Review of Stage A surfaced one BLOCKER and the writer/reader MAJOR; both addressed here.

BLOCKER — TPL template lookup pointed where nothing ships. The required-sections
dispatcher defaulted --templates-dir to <pd>/aidlc/memory/templates, but P5/SEED ship
the floor at <pd>/aidlc/spaces/default/memory/templates (where the rules resolver and all
3 native includes point). A team's template was silently ignored at the real runtime path;
green only because t155 always injected --templates-dir. Fix: derive the default from the
same MEMORY_SEGMENTS the resolver+packager use, via new exported memoryTemplatesDir()
(and memoryDirFor()) in aidlc-graph.ts; correct the 4 doc/comment refs (manifest,
stage-protocol clause, .gitkeep, sensor-script comment) to the real path. t155 gains 2
regression tests that exercise the DEFAULT path + cross-check it against where dist ships
(proven load-bearing: revert the fix → both fail).

Fail-safe for the P5 reader/writer seam (deferred to P6). P5 re-pointed only the rule
READER; the learnings writer (aidlc-learnings.ts) + practices-promote (aidlc-state.ts)
still write the OLD <harness>/rules/ path the reader no longer reads — a silent-loss
window until P6. New t158 is a test.failing tripwire: green now (round-trip genuinely
does not close — verified persist writes .claude/rules/aidlc-team-learnings.md), flips RED
the moment P6 redirects the writer under aidlc/spaces/<space>/memory/, forcing the seam
closed and the tripwire removed. A companion guard documents the current divergence.

Test-only + a path-correctness fix; no version bump (no user-facing command/flag change;
the feature was non-functional at its real path before this).

* refactor(paths): funnel state/audit/aidlc-docs literals through helpers (no-op)

* feat(workspace): re-root aidlc-docs tree per-intent + key audit lock per-intent (P1 Step B + P3)

Re-roots the record under aidlc/spaces/<sp>/intents/<slug>-<id8>/ and keys
the audit lock per-intent in the same change (the shared-lock cliff makes
them indivisible — re-rooting state per intent while the lock stays
projectDir-keyed would serialize all intents and a SIGKILL would wedge them).

- re-root the whole aidlc-docs record family per-intent; the two engine
  resolvers (resolveArtifactPath, memoryPathFor) re-rooted with intent context
- migration-aware legacy-flat resolution via a SINGLE named legacyFlatFallback()
  (P9/Stage D retires it; t159 tripwire flips RED to force removal)
- migrateFlatLayout: marker-only idempotency, same-fs staging, one atomic
  rename, source never deleted, returns movedFrom for the caller's git-rm
- per-intent audit lock: workspace-sentinel bucket for intents.json writes,
  composite-keyed depth/handler maps, PID+mtime stale-lock reaper (rename-steal,
  unstamped-grace), doctor leaked-lock probe
- emitError holdsAuditLock fix (composite-keyed; was a 5s in-transaction
  self-deadlock after per-intent keying)
- stage-protocol restatement (artifact paths are engine-resolved)
- tests: t159 (fallback tripwire), t160 (record resolution + migration + audit
  shards), t161 (lock keying + reaper); t76/t49 stamp a live lock owner

* feat(workspace): thread space+intent selector through state/orchestrate/audit/runtime/worktree/bolt/swarm

* fix(workspace): stabilize audit shard identity + per-intent lock keying + shard ordering (Stage B review fixes)

Address the HOLD findings from the adversarial Stage B review (1 blocker + 5
majors). The re-root architecture was sound; these fix the cross-process
shard-identity plumbing and lock-bucket keying on top of it.

- BLOCKER: audit shard identity is now per-CLONE (a gitignored aidlc/.aidlc-clone-id
  token), not per-PID — fork and merge subprocesses resolve the SAME shard, so
  Bolt merge no longer fails ("main audit not found") on a migrated project
- MAJ: reaper re-verifies the stamp before the steal-rename (no two-holder race)
- MAJ: state fork/merge wrap their per-intent writes in the per-intent lock bucket,
  not the __workspace__ sentinel (restores P3 isolation)
- MAJ: fragment-fork resolves the space segment once (no write-path/read-path ENOENT)
- MAJ: runtime-compile hook reads the active intent's shard (graph refreshes after
  a transition on the new layout)
- MAJ: cross-shard audit reads order by timestamp, not lexical filename
- t162-per-intent-layout-cli: NEW — drives real CLIs (state transition + Bolt
  fork/merge) against a seeded per-intent layout, the coverage gap that let the
  blocker hide; .aidlc-clone-id gitignored across all 3 harnesses

* fix(workspace): close fork/merge lock-bucket + emitError regression + findLatestEvent ordering + atomic reaper steal (Stage B re-review fixes)

Close the 3 partial majors a targeted re-review found still open after 7607613,
including a regression that commit introduced.

- fork/merge: resolve activeIntent(pd,space,intent) BEFORE the wrapping
  withAuditLock so the lock bucket == the per-intent shard being written
  (state.ts handleFork/handleMerge) — fixes the lost-update window on the
  omitted-intent path
- REGRESSION fix: emitError now takes intent?/space? and keys
  holdsAuditLock(projectDir,intent,space); aidlc-state.ts threads the held
  lock's intent via lockIntent/lockSpace so mid-transaction errors no longer
  hit the 5s blocking-acquire branch or write ERROR_LOGGED to the wrong bucket
- findLatestEvent (aidlc-worktree.ts) delegates to findAllEvents → picks the
  max-Timestamp block (CRLF-normalized), not buffer/lexical position — the
  sibling reader the first fix-pass missed (worktree verify/info on multi-shard)
- reaper steal is now atomic: rename lockDir to a reaper-private nonce first
  (OS-atomic arbiter), re-verify the stamp inside the moved dir, restore on
  miss; residual sub-window documented, not silently labeled fixed
- t163-reaper-steal-race (spawn-contention mutual-exclusion property),
  t164-shard-ordering-and-lock-bucket (regression test for the ordering +
  lock-bucket fixes; fails 3/3 pre-fix)

* feat(workspace): retire --init; engine auto-births intent into active space; space+intent list/switch/create handlers

Stage C / P4 (keystone). Retire the user-facing /aidlc --init + --force; the
engine auto-births the first intent CONDUCTOR-SIDE (read-only engine NAMES the
move via birthPrintDirective, the deterministic aidlc-utility intent-birth
handler mutates). Add the intent/space verb families + the deterministic
listSpaces/listIntents query layer (+--json); intent status lifecycle (birth
in-flight; WORKFLOW_COMPLETED flips to complete under the workspace lock); doctor
readiness checks the shipped shell. Migration wired through the first-/aidlc path.

Two bugs fixed: birth bootstrap stub (cursor binds before full state body) and
appendAuditEvent self-deadlock (lock-aware, mirrors emitAudit). ~25 test files
repointed flat->per-intent via recordDirOf + shard-aware audit reads; harness
sdk-drive/kiro-acp readers repointed. New t165-intent-birth-p4 (concurrent-birth
integrity). Deterministic surface green (typecheck 0, --check clean); t72 a named
live-SDK wedge (flat-fixture assertion correct, no change).

* feat(memory): collapse learnings into practices; drop -learnings slots + 1.5/2.5 tiers

Stage C / P6. A confirmed learning IS a practice (vision §6): the learnings
writer (aidlc-learnings.ts learningsFilePath) and practices-promote
(aidlc-state.ts) now write the relocated aidlc/spaces/<space>/memory/{team,project}.md
via memoryDirFor — CLOSING the Stage-A reader/writer seam. Routed to the fitting
heading (## Corrections default) with ensure-exists (appendUnderHeading throws on
absent). Dropped the team-learnings/project-learnings RULE_FILE_REGEX slots +
the 1.5/2.5 SCOPE_PRIORITY tiers; the chain is clean org->team->project->phase.
Widened the Kiro fs_write allowlist to aidlc/spaces/**. §13 stage-protocol prose
updated in lockstep. The Stage-A t158 test.failing tripwire is CONVERTED to a
passing write->read round-trip (persist a learning -> loadRules reads it back).
Admission conflict-check + full audit trail retained.

Deterministic surface green: typecheck 0, --check clean (3 trees), --ci 193 pass
incl. t88 (clean 4-layer chain), t99 (§13 writes a practice), t158 (round-trip),
t86 (§13 prose). Sole red is t72 — the unrelated P4-era live-SDK wedge (P6 touched
no RE/orchestrate code).

* feat(workspace): multi-repo — sibling repos, per-repo codekb, intent repo-set, --repo through worktree/swarm/bolt

Stage C / P7. Multi-repo is first-class. An intent records the repos it touches
in intents.json (--repos flag or sibling-.git discovery; empty set = lone repo
inferred, no row). RE runs per-repo into aidlc/codekb/<repo>/. --repo threaded
through the construction path (worktree/swarm/bolt) via a shared
resolveConstructionRepo: git worktree add + assertNotSiblingWorktree(repoCwd?)
anchor to the target sibling repo dir, not the (non-git) workspace root —
decoupling 'repo to operate on' from 'the single projectDir'. Single-repo intents
infer the lone repo (no flag); --repo only disambiguates multi-repo.

Also closed 2 e2e tests P4 missed migrating (t66/t67-construction-worktrees — they
read the retired flat aidlc-docs path; applied t63's recordDirOf per-intent pattern).
New t166-multi-repo-construction; t165 extended. Deterministic surface green
(typecheck 0, --check clean, all 8 construction-worktree e2e pass); t72 = unrelated
live-SDK wedge, t66/t78-bolt = contention flakes (proven green in isolation).

* feat(hooks): resolve active intent in hooks + statusline; show active space · intent orientation; resume rebind

Stage C / P8 (final Stage C phase). Thread the active intent through the hooks +
statusline. Statusline gains a '<space> · <intent> · <phase> …' orientation prefix
(the space token renders only when listSpaces().length > 1 — single-team users
never see it; vision §11.2). Session-start gains a resume cursor-rebind OFFER:
stamp the working intent uuid into a per-conversation session→intent map at
SESSION_STARTED, and on SESSION_RESUMED if it diverges from the active-intent
cursor, offer to rebind (never a session rebuild). New session-intent-uuid helpers
in aidlc-lib (read/writeSessionIntentUuid, activeIntentUuid, findIntentByUuid); the
.aidlc-sessions/ map is gitignored (per-user runtime, like active-intent). Fixed
the aidlc-audit-logger includes('aidlc-docs/') gate that dropped ARTIFACT events on
re-rooted per-intent paths; swept residual hook literals (runtime-compile was
already re-pointed in Stage B). New t160 (statusline orientation), t161 (resume
rebind), t162 (audit-logger per-intent), t167 (session→intent helpers).

Deterministic --ci surface green (198 pass; sole red = t72 live-SDK wedge).

* test(workspace): migrate t54/t55 e2e to per-intent audit/state reader; renumber P8 tests off Stage-B collisions

Stage C cleanup (test-only, no version bump). Two fixes both invisible to the
--ci tier (which excludes --e2e):

1. t54/t55 (workflow-audit-completeness, init-then-resume) drove the retired flat
   aidlc-docs/{audit,state} reads after P4's auto-birth + audit-shard re-root —
   the same P4-era escape class as the t66/t67 P7 fixed. Migrated both to the
   layout-aware harness readers (readAuditText/readAuditEvents + stateFilePathFor/
   auditDirFor, per-intent with flat fallback). t54 passes; t55's assertion path is
   now correct (its residual red is live-SDK variance on bare /aidlc --init, same
   wedge class as t72/t126/t138 — verified stateFilePathFor resolves the per-intent
   path correctly after a real birth).

2. P8 (301dc27) committed t160/t161/t162 numbers that already existed from Stage B
   (workspace-record-resolution / per-intent-lock-reaper / per-intent-layout-cli).
   Renumbered P8's tests to the free block: t160→t168 (statusline-orientation),
   t161→t169 (session-resume-rebind), t162→t170 (audit-logger-per-intent); rewired
   covers/describe self-refs + EXPECTED_NONE_TO_CLI + regenerated the registry.
   (t163→t167 was already done.)

typecheck 0, --check clean, t55-drift/t134/gen-coverage + the 3 renamed tests green.

* fix(workspace): birth gate consults the intent registry — no duplicate auto-birth on a multi-intent clone with an unset cursor

The no-state birth gate (Branch 7b valid-scope positional / Branch 9a explicit
--scope flag) in aidlc-orchestrate.ts fired purely on `!stateContent`. But
stateContent is empty in TWO worlds: a truly empty workspace (zero intents →
birth is correct) AND a workspace that already holds intents whose per-user
active-intent cursor is unset. The cursor is gitignored, so a fresh clone of a
>1-intent workspace lands with records on disk but no cursor → activeIntent()
returns null → stateContent empty → the gate would mint a DUPLICATE intent over
the existing ones, violating the P4 hazard 'auto-birth fires only on ZERO
intents'.

Before birthing on either arm, consult the deterministic query layer
(listIntents over the active space): when intents EXIST but none is flagged
active, emit an `ask` directive that lists them and asks the human to pick one
via `/aidlc intent <slug>` instead of birthing. Zero intents still births
unchanged. The engine stays read-only — it NAMES the move, never mutates the
cursor.

Regression: tests/integration/t171-birth-gate-registry.test.ts.

* fix(workspace): migration preserves the pre-migration audit trail into the per-intent shard layout

migrateFlatLayout blind-copied the flat tree, landing the flat
`aidlc-docs/audit.md` FILE at `<record>/audit.md` (a top-level file). But the
audit readers (auditShards / readAllAuditShards) glob the `<record>/audit/` DIR
via auditShardDir, and the single-file flat-fallback fires only when the record
dir is absent — never, post-migration. So the pre-migration WORKFLOW_STARTED /
STAGE / PHASE history was on disk but INVISIBLE to runtime-graph compile,
summary/replay, and every hook — contradicting the in-code claim that the
migrated record 'carries its prior state + audit history' (vision §5.1).

During migration, relocate the flat audit.md into the shard layout
`<record>/audit/<host>-<clone>.md` (auditShardName) so it joins the shard set
the readers already merge-sort. Honours decision #1 (per-clone shards, NOT a
single committed audit.md + merge=union). Guards the no-audit case. The flat
source aidlc-docs/audit.md is untouched, so the caller's gitRmFlatTree is
unaffected; the staged copy (never the source) is what moves.

Regression: tests/integration/t172-migration-audit-trail.test.ts (seeds a
POPULATED flat audit.md — t165's migration block used a header-only file, which
is exactly why this orphaning escaped).

* fix(workspace): thread --repo through the invoke-swarm directive so multi-repo autonomous construction targets the right sibling repo

The tool layer already supported --repo (aidlc-swarm.ts prepare → resolveConstructionRepo),
but the conductor-facing seam never supplied it: the invoke-swarm directive carried only
{kind, units}, the engine emitted it with no repo, and the swarm-prepare prose in all three
harness SKILL.md named `prepare` without --repo. So on a MULTI-REPO intent the conductor ran
prepare without --repo, resolveConstructionRepo threw ('spans N repos'), and autonomous swarm
construction dead-ended.

- Directive contract (aidlc-directive.ts): add optional `repo?: string` to InvokeSwarmDirective
  (+ INVOKE_SWARM_FIELDS, + checkOptionalString in the validator, + a self-test example).
- Engine (aidlc-orchestrate.ts tryEmitSwarm): resolve the repo deterministically via
  intentRepos (read-only — never throws, returns [] for flat-legacy). 0 repos → emit units
  unchanged (no repo field, today's behaviour); 1 repo → emit the lone sibling as `repo`;
  >1 repos → emit without a repo field (the conductor's knowledge call — it supplies --repo
  from the intent's recorded set, per the three-concerns tenet). NOT resolveConstructionRepo
  here, which throws on >1.
- SKILL.md (claude/kiro/codex): the prepare command gains [--repo <name>] + the instruction to
  pass the directive's repo when present, else supply --repo from /aidlc intent --json.repos on
  a multi-repo intent.

Regression: extend t166 (swarm prepare --repo forks inside the target sibling repo; prepare
without --repo dead-ends with 'spans 2 repos') + t113 (invoke-swarm with optional repo → VALID).
t135 (flat-legacy fixtures) stays byte-identical — intentRepos returns [] → no repo field.

* fix(hooks): refresh the session→intent stamp on in-conversation intent switch — no false resume-rebind nag

The resume-rebind stamp (session-start hook) is keyed by session_id, which only
the hook sees. An in-conversation `/aidlc intent <slug>` switch moves the
active-intent cursor via a CLI tool with no session_id, so the live session's
stamp stayed pointing at the OLD intent — resuming THAT SAME conversation then
fired a FALSE rebind nag ('was working X, switch back?') even though this
conversation deliberately switched.

Plumb session-id from the hook (which owns it) to the switch tool via a fixed-name
`.current-session` marker inside the gitignored aidlc/.aidlc-sessions/ dir:
- New lib helpers writeCurrentSessionId / readCurrentSessionId (best-effort).
- The session-start hook writes the marker on EVERY fire (not gated on eventType),
  so it always names the live conversation.
- handleIntent reads the marker after moving the cursor and re-stamps that session
  to the switched-to intent's uuid.

Self-switch: the marker names THIS session → its stamp follows the cursor → no
false nag. Foreign drift (a different session moved the cursor): the marker names
that OTHER session → its stamp moves, not ours → a genuine resume still offers the
rebind. Stays a non-destructive OFFER, best-effort throughout.

Regression: tests/integration/t173-session-switch-restamp.test.ts (spawns the real
hook + the real switch; proves self-switch → no nag, foreign drift → nag fires).
t169 unchanged (it drives foreign drift via raw setActiveIntentCursor).

* fix(hooks): forward session_id/source through the Kiro + Codex SessionStart adapters so resume-rebind is not Claude-only

The core SessionStart hook gates its P8 session→intent stamp + resume-rebind OFFER
on a non-empty session_id, but the per-harness adapters that feed it never forwarded
session_id — so the feature was Claude-only.

- Codex (the clean win): the adapter already forwards a real `source`; now also
  forward session_id when present, so the full P8 path — stamp on SESSION_STARTED,
  OFFER on source=resume — works end-to-end on Codex.
- Kiro: forward session_id when present so the per-session STAMP is written. But
  Kiro's agentSpawn carries no resume discrimination (the adapter reports every
  session-start as source=startup), so SESSION_RESUMED can never fire and the
  resume-rebind OFFER is structurally unreachable on Kiro — documented in the
  adapter comment as a harness limitation, not a bug. No fake resume source.

Regression: extend t149 (codex forwards session_id → stamp written; source=resume
after a cursor drift → OFFER fires) + t147 (kiro forwards session_id → stamp written;
resume-shaped payload → no OFFER, the documented limitation pinned deterministically).

Also refreshes tests/.coverage-registry.json + .coverage-ratchet.json and the
gen-coverage-registry EXPECTED_NONE_TO_CLI allowlist to register the new spawning
integration tests t171/t172/t173 (added by the B1/B2/M2 fixes) — the t134 mechanism-
honesty gate requires the committed registry to carry every test's covers: claims.

* fix(workspace): review minors — space-switch slugify, init-runner description, onboarding --init removal, stale comments

Batch of five review minors:
- aidlc-lib.ts: correct resolveConstructionRepo's stale header — a zero-recorded-repos
  intent with an explicit --repo HONOURS it as a sibling anchor (cwd = the named
  sibling dir), it does NOT error; the comment now matches the code. (comment-only)
- aidlc-utility.ts handleSpace: slugify the switch target before lookup + cursor write,
  mirroring space-create (which stores slugify(raw)). Without this, `/aidlc space
  "My Space"` (stored as my-space) failed 'Unknown space'. (behavior fix)
- aidlc-runner-gen.ts renderInitRunner: the /aidlc-init runner forwarded $ARGUMENTS
  verbatim to intent-birth, but intent-birth reads the freeform description from the
  --arguments FLAG (not a positional), so a description was silently dropped. The
  runner now instructs the conductor to forward recognized flags as-is and pass
  freeform text via --arguments "<text>". (behavior fix)
- onboarding.fills.ts (claude + kiro): drop the retired `/aidlc --init`/`--force`
  scaffold sentence from the title_block heads; replace with the no-init birth-flow
  description (matching codex's already-updated wording). (prose fix)
- t143: fix the drifted line cite for the 'State initialized:' stdout literal
  (:2376 → :2395). (comment-only)

The docs/ getting-started --init sweep is deliberately NOT touched — that is the
disputed finding deferred to P9.

Regression: t165 (space-switch slugify → my-space resolves) + t129 (the shipped
aidlc-init runner names --arguments, no bare intent-birth $ARGUMENTS).

* feat(workspace): retire the legacy-flat fallback bridge — single per-intent layout

Delete legacyFlatFallback() + LEGACY_FLAT_ROOT/LEGACY_FLAT_RELATIVE_PREFIX
from aidlc-lib.ts; null-resolution now resolves to the bare per-intent space
record root (aidlc/spaces/<space>/intents/). Rewrite the orchestrate.ts
resolvers + retire the transitional aidlc-docs gate in the audit-logger hook.
The migration source is kept as a private flat literal only.

Also fix the two shipped sensor manifests' matches-glob from **/aidlc-docs/**
to **/{aidlc-docs,intents}/** — the per-intent layout move made the old glob
DEAD, so required-sections/upstream-coverage never fired on re-rooted paths.
Recompiled into stage-graph.json.

P9/Stage D — discharges the Stage-B carry-forward (bridge must not reach GA).

* test(workspace): migrate the fixture corpus to the per-intent workspace layout

Redirect the fixtures.ts chokepoint (createTestProject / seedStateFile /
seedAuditFile / setupIntegrationProject) + the secondary chokepoints
(tui-fixtures.ts setupTuiProject, custom-harness.ts) to emit the per-intent
layout aidlc/spaces/<space>/intents/<slug>-<id8>/ with a pinned clone-id for
deterministic audit shards. Touch the assertion-hardcoders across the corpus
that embed flat aidlc-docs/ paths. Delete the t159 legacy-flat fallback
tripwire (the bridge it guarded is gone — its test.failing flips RED on
retirement, which is the signal to remove it).

Also repoints the TUI statusline tests for the active-intent orientation
prefix (<slug> · …) the prior phases added.

P9/Stage D.

* test(workspace): space-isolation suite + docs allowlist gate

t175: space-create copies org.md but writes FRESH team/project stubs so the
default space's promoted practices do not leak; a new intent reads the space's
live memory. t174 + tests/fixtures/docs-legacy-refs.json: a closed-predicate
docs allowlist (occurrences == pinned set, ceiling 8, 5 pinned) over the
surviving aidlc-docs/--init references in docs/. Reconcile the coverage
registry + ratchet for the new surfaces.

The rest of the plan's P9 suite list is already pinned by Stage B/C
(t160/t162/t163/t164/t165/t156/t168/t171/t145/t75/t166/t172).

P9/Stage D.

* docs: workspace architecture sweep + version 0.8.0 + CHANGELOG

Sweep ~60 docs/ files to the per-intent workspace model (retire --init prose;
rewrite the aidlc-docs/knowledge paths stale on the knowledge relocation).
Bump the version trio to 0.8.0: core/tools/aidlc-version.ts + README badge +
a ## [0.8.0] CHANGELOG entry carrying the upgrade note (workspace layout,
--init retired, per-clone audit shards, learnings-as-practices). t68 pins the
trio agrees; dist version copies regenerated.

P9/Stage D.

* fix(workspace): domain knowledge is space-level, not per-intent

Align the knowledge layout to the plan/vision (workspace-vision §Spaces, plan
L296): SPACE domain knowledge lives at aidlc/spaces/<space>/knowledge/ — a
free-form, empty-at-bootstrap sibling of memory/codekb/intents that accumulates
across every intent in the space — NOT inside a per-intent record. The engine's
per-agent METHODOLOGY knowledge at <harness>/knowledge/ is distinct and stays
put.

The Stage A/B/C implementation had drifted: birth's ensureWorkspaceDirs created
knowledge per-intent (<record>/knowledge/), and migration's blanket tree-move
dragged the flat aidlc-docs/knowledge/ overlay into the record where the
(repointed) agents would never find it.

- aidlc-lib.ts: new knowledgeDir(projectDir, space?) resolver; migrateFlatLayout
  step 3b relocates the migrated flat knowledge/ up to space-level (merge
  entry-by-entry; source untouched).
- aidlc-utility.ts ensureWorkspaceDirs: knowledge dir → space-level (per-phase +
  verification dirs stay per-intent, correctly).
- 11 agent personas + stage-protocol.md: team-knowledge load paths
  aidlc-docs/knowledge/ → aidlc/knowledge/ (space shorthand); methodology refs
  untouched.
- workspace-scaffold.md + onboarding.md: describe the space-level free-form model
  (empty at bootstrap, no seeded per-agent READMEs, no scaffold command).
- tests: t21/t27 assert space-level knowledge; t07 record-artifact example uses a
  real per-intent stage path; new t160 case asserts migration relocates flat
  knowledge to space-level; custom-harness persona template repointed; coverage
  registry picks up knowledgeDir.

Resolves the docs-accuracy + scaffolding majors the P9 review surfaced.

* docs: team knowledge is space-level free-form, not per-intent scaffolded

Correct the knowledge docs to match the shipped model: team/domain knowledge
lives at the space level (aidlc/spaces/<space>/knowledge/, shorthand
aidlc/knowledge/) — a sibling of memory/codekb/intents that accumulates across
intents — and is free-form and empty at bootstrap. Removes the prior sweep's
fiction that intent birth scaffolds per-agent knowledge subdirectories seeded
with guidance READMEs: the engine ensure-exists an empty knowledge/ dir; the
team creates aidlc-shared/ and per-agent subdirs itself (a convention the agent
personas look for) if it has content for them. Tier-1 engine methodology
knowledge (<harness>/knowledge/) descriptions are unchanged.

28 docs files across guide/reference/harness-engineering, incl. the canonical
07-knowledge.md and the 11 reference/agents/ pages.

* test(workspace): fixture intent uuid ⇄ record-dir consistent by construction

The seeded default intent's record dir name and its intents.json row uuid had
drifted: the dir used suffix 0000000000000001 but idSuffix(uuid) of the seeded
uuid (…8000-000000000001) is 8000000000000001, so listIntents()/
updateIntentStatus() never joined the row to its dir — a layout the runtime can
never produce, leaving fixtures modelling a fiction (P9 review major).

Derive DEFAULT_RECORD_DIR's id8 from a single DEFAULT_INTENT_UUID constant via
the same trailing-16-hex rule the runtime uses, and reference that uuid in both
fixtures.ts and tui-fixtures.ts registries — so the row⇄dir join holds by
construction. Genericize two stale comments (t137/t99) that named the old literal.

* test(workspace): guard the sensor-glob intents arm; refresh designer-export golden

t95 only drove the legacy aidlc-docs/ arm of the framework sensor glob
**/{aidlc-docs,intents}/**, so a regression of the new intents arm (the per-intent
record path every real workflow writes) would leave the suite green while the
sensors went silent — the exact dead-glob bug P9 fixed, unguarded (review major).
Add C1a-intents: a markdown write under the per-intent record dir must fire the 2
markdown sensors via the intents arm.

Also regenerate the designer-export golden for the workspace-scaffold stage's
updated outputs: frontmatter (knowledge is space-level now — the earlier
knowledge-realignment commit changed the stage prose; t66 compares export
byte-for-byte).

* fix(workspace): relocate migration audit+knowledge BEFORE the atomic rename (crash-safety)

migrateFlatLayout relocated the flat audit.md → shard dir and the flat knowledge/
→ space-level AFTER the atomic rename into the leaf but BEFORE the .migrated
marker. Since the rename flips anyIntentRecordExists() true (→ needsFlatMigration
returns false), a crash in that window stranded the audit shard and the team's
knowledge permanently — the migration could never re-fire. Review#2 major.

Shape the STAGING tree to the target layout (audit → audit/<shard>, knowledge →
space-level) BEFORE the rename, so the rename is the SOLE commit point: the only
partial window now produces no aidlc-state.md under intents/ and no marker, so a
crash re-fires cleanly (step 1 rmSyncs any half-staging; the flat source is never
mutated; the space-knowledge move is intent-independent + idempotent).

t160: add merge-into-existing-space-knowledge (no data loss either side) + a
post-crash re-fire test; register function:knowledgeDir coverage (was UNCOVERED).

* docs+test: align onboarding/glossary/comments to space-level knowledge; gate the onboarding surface

Review#2 found the shipped onboarding doc + glossary still described the retired
flat aidlc-docs/ layout and /aidlc --init — and the t174 legacy-ref gate scanned
docs/ only, so it never saw the onboarding template (the source that renders to
the shipped CLAUDE.md/AGENTS.md, the first surface a user reads). That blind spot
is why the stale onboarding shipped green.

- core/templates/onboarding.md: rewrite Conventions/Resumption/Git + the init line
  to the per-intent workspace model (record dirs, space-level knowledge, the real
  gitignore set from the shipped .gitignore); --init retired, no separate init cmd.
- harness/kiro/onboarding.fills.ts: aidlc-docs/ → aidlc/ workspace tree.
- docs/guide/glossary.md: team knowledge is space-level (regression of review#1 #2).
- t174: extend the scan surface to core/templates/onboarding.md so the onboarding
  surface is gated (closes the blind spot).
- Stale-comment minors: t95 (sensor glob is {aidlc-docs,intents}, not unchanged),
  t21/t27/aidlc-utility (knowledge is space-level, not per-intent).
- CHANGELOG 0.8.0: add the space-level knowledge relocation to the upgrade note.

* fix(workspace): guard aidlc-log audit emit against a null-resolved intent (no stray shard in the bare space root)

aidlc-log threads no --intent/--space, so it relies on default intent
resolution. On a fresh shell (pre-birth) or a >1-intent workspace with no
active-intent cursor, activeIntent() returns null and stateFilePath()/
auditFilePath() collapse to the BARE space record root
(aidlc/spaces/<space>/intents/). An unguarded emit there drops a state/audit
shard DIRECTLY into the bare intents root, breaking the invariant that no
aidlc-state.md / audit/ ever lives in the bare intents root (aidlc-lib.ts).

aidlc-log was the lone audit emitter missing the "no active workflow → clean
error / no-op" guard every other emitter has: the hooks no-op via
`if (!existsSync(stateFilePath(...)))`, emitError() gates ERROR_LOGGED on the
same check, and handleEnableTestRun() dies on it. Mirror that idiom — resolve
the project dir, assert the resolved aidlc-state.md exists, else emit a clean
error to stderr and exit 1 (orchestrator-called per-question → a missing
workflow is a misuse, not a routine no-op).

Sweep result: all 21 writeStateFile callers SAFE (state.ts/jump.ts/bolt.ts read
an existing state first or thread a resolved intent; utility.ts is behind a
stateFilePath existence check, an explicit --intent/--space, or the birth path);
of the audit emitters, every hook is guarded (existsSync stateFilePath/auditFile
or an underRecord check) and every tool emit is gated behind a state read,
explicit intent, or the birth/init cursor — aidlc-log was the only at-risk one.

t31 updated: the suite previously documented emitting into the bare space root
as expected (the buggy behavior); its emit-success cases now seed a real
active intent (state-mid-ideation.md) so a valid record resolves, and four new
cases (g1-g4) prove decision/answer with no resolvable intent error cleanly and
leave NO aidlc-state.md / audit/ in the bare intents root.

dist regenerated; bun scripts/package.ts --check clean.

* feat(workspace): orchestrator offers a 2nd intent on unrelated new-work (P4 completion)

Completes the one unbuilt piece of P4 (the workspace refactor's auto-birth/intent
phase): the vision promised that once an intent is active, describing a genuinely
new, unrelated piece of work prompts the orchestrator to OFFER a second intent
alongside (you confirm). The engine is correctly read-only — with an intent active
it advances it (Branch 10) and every birth arm is !stateContent-gated — so the
offer is conductor PROSE (knowledge->LLM, judgement->human), NOT a new engine branch.

Adds an additive subsection after Routing to all three per-harness orchestrator
skills (harness/{claude,kiro,codex}/skills/aidlc/SKILL.md): recognise new-work vs
continuation (default to continuation; compare against the active intent via
'intent --json'), OFFER via the harness question surface (never auto-birth), and
on confirm run the existing 'intent-birth' tool then re-run 'next' — the same
run-then-continue shape the print directive already uses. The offer surfaces the
proposed --scope so the human can correct it, and pins the affirmative option to
lead with 'Yes' so the answerScript matches deterministically. Kept cleanly
separable so the Stage F reviewer-mechanism rebase reconciles without a tangle.

Tests: t176-new-work-offer-second-intent (SDK) drives the live offer beat
(offer fires -> confirm -> intent-birth -> 2 registry rows); gated on claude-CLI
presence, skips-with-reason when absent. Non-vacuous via the (b)+(c) conjunction:
with an intent active, a 2nd intent can ONLY arise from offer->confirm->birth, so
'State initialized:' (birth-only literal) + 2 rows prove the offer; question TEXT
is not asserted (non-deterministic). The deterministic birth/isolation half stays
covered by t165. No version bump — folds one bullet into the unshipped 0.8.0 entry
(Stage F owns the 2.0.0 trio).

bun scripts/package.ts --check clean; bun run typecheck 0.

* test(workspace): multi-repo/intent/space live journey — shared fixture + logic-half (SDK·ACP·exec) all 3 harnesses

* test(workspace): render-half journey (Claude TUI) — statusline orientation + gate

* test(workspace): ACP journey drives the full 5-beat composed flow + fix coverage-registry gate

Review (ultracode, 15 agents) found Stage E NOT-FINISHED. This closes the
blockers it raised:

- B2: the Kiro ACP leg drove only beats 1-2. A live spike proved multi-turn
  ACP IS drivable (the driver's session-reuse + keepAlive + stopAfterToolTitle
  pace dependably when each turn stops at a TOOL boundary). Extend the leg to
  the full 5 beats: beats 1-3 through the production `aidlc` conductor (beat 3
  via the authorized offer->confirm flow, SKILL.md:104), beats 4-5 through the
  `aidlc-developer-agent` (space verbs have no authorized conductor routing, so
  the production agent forwards them to `next` — the developer agent, lacking
  the forwarding override, is the drivable surface; documented, not faked).
  Beat-2 codekb stop made disk-condition-based (tolerant of root- or
  space-scoped codekb) to fix a pre-existing per-repo-ordering flake.
- B1: regenerate tests/.coverage-registry.json + add the codex journey spawner
  to EXPECTED_NONE_TO_CLI (the 6 new Stage-E files changed the coverage
  universe; gen-coverage-registry.test.ts is a deterministic unit-tier gate).
- Soften the kiro-acp-drive.ts multi-turn NOTE (comment only) to match the
  spike finding.

Live-verified: 212 ACP tool_call events, intent-birth/space-create/space
verbs all fired (trace 2026-06-19T12-27-54Z). Test-only, no version bump.

* feat(workspace): route space/intent navigation verbs through the conductor

Completes the P4 workspace-verb deliverable. The handlers (handleSpace,
handleIntent, handleSpaceCreate) shipped in P4 but were only reachable by
calling aidlc-utility.ts directly — the conductor forwards `$ARGUMENTS` to
`aidlc-orchestrate.ts next`, which had no branch for the switch/list verbs, so
`/aidlc space teamB` was swallowed as freeform text and the engine advanced the
active intent instead of switching (Branch 8 ask on a fresh workspace, Branch 10
advance with an active intent). The vision (§3 "/aidlc space <name> is the
explicit cd") and the P4 card ("/aidlc space <name> moves between teams")
both promise these as working user commands.

Fix mirrors the READ_ONLY_FLAGS routing pattern:
- WORKSPACE_VERBS set beside READ_ONLY_FLAGS.
- parseNextFlags recognizes a leading (i===0) space/space-create/intent token as
  a workspaceVerb + optional <name> arg (guarded so freeform prose merely
  containing "space"/"intent" mid-sentence is untouched).
- A new branch in handleNext at Branch-1 altitude (before resolveProjectDir /
  loadState, so a switch works with OR without an active workflow) emits a
  terminal print directive naming `aidlc-utility.ts <verb> [<arg>]`. All verbs
  are terminal prints (switch/create/list echo + stop; nothing for next to
  advance into); list-vs-switch stays in the unchanged deterministic handler.

No SKILL.md change: the print row already covers "a workspace command". t114
gains 5 cases (switch/list/create routing + an i===0 freeform regression guard).
Version trio → 0.8.1.

* test(workspace): correct codex journey header — render-half is Claude-TUI-only (Kiro has no statusline either)

MAJOR-2 reconcile: the codex journey header said the render-half matrix is
'Claude + Kiro TUI', but Kiro ships no statusline surface (no dist/kiro
settings.json statusLine row; AGENTS.md + SKILL.md state 'there is no
statusline'), so there is no Kiro orientation leg. Corrected to Claude-TUI-only;
Kiro + Codex are logic-half only for the render-half, by surface limitation.
Matches the t-tui-journey-orientation + t-acp-kiro journey headers. Comment-only.

* test(workspace): drive journey beats 4-5 through the real conductor; drop the workarounds

Now that d44828b routes the space/intent navigation verbs through the conductor
(next emits a terminal print directive naming aidlc-utility.ts <verb>), the
journey's space beats can drive the verbs the real user way — `/aidlc space
teamB` — instead of routing around the conductor. Removes:

- ACP: the `driveDevVerb` helper (drove space verbs through aidlc-developer-agent,
  a delegation target, because the production conductor couldn't route them).
  Beats 4-5 now use single-turn driveKiroAcp on the `aidlc` conductor; the trace
  shows `next <verb>` → `aidlc-utility.ts <verb>` for space-create/space/default.
- SDK + Codex: the `spaceSwitchPrompt` "Run this exact command … do NOT run next"
  steer. Beats 4-5 now drive the plain `/aidlc space <name>` command; the
  conductor forwards to next, gets the print directive, runs the tool.

All on-disk assertions unchanged. Each leg spike-confirmed live then re-verified
green on the full 5-beat journey (ACP 2/2 clean when the forward lands; SDK +
Codex green on re-run). Headers/comments rewritten to the conductor-routed path;
the obsolete "the conductor cannot route these" / "space default left the cursor
on teamb" rationale removed. Test-only, no version bump.

* test(workspace): repoint 4 stale TUI assertions after rule + knowledge relocation

Four e2e TUI tests carried path/string assertions from the v2-unified import
(7b824b3) that the workspace-anchor relocations made stale — verified test debt,
not regressions: none of the Stage-E commits (495e48f..fc8f093) touched these
files, and both relocations are ancestors of the Stage-D base. Pure repoints,
mirroring the sibling fix c3a193b ("repair stale rule-path goldens").

- t29: the no-state recovery string is "…or by naming a scope (/aidlc --scope
  <scope>)" (aidlc-orchestrate.ts:1245-1247), not "Name a scope to start a
  workflow" — assert the stable "naming a scope" substring.
- t50: knowledge moved from the per-intent record to the SPACE level
  (aidlc/spaces/<space>/knowledge, b29ced6), ensured at birth for every scope
  by ensureWorkspaceDirs. Repoint via a new spaceKnowledgeDirFor() helper in
  sdk-drive.ts (mirrors recordDirFor's space-cursor resolution).
- workshop: rules relocated to the harness-neutral aidlc/spaces/default/memory/
  with neutral basenames (fe7f470) — read team.md there, not
  .claude/rules/aidlc-team.md.
- custom-harness: same relocation — the compiled stage node bakes
  aidlc/spaces/default/memory/project.md (verified against the actual emitted
  rules_in_context array); repoint both the assertion and the rule-file read.

The fifth flagged test (t-tui-kiro-status) is left unchanged: its failure is NOT
a stale path but the known conductor-forwarding reliability item — the live Kiro
conductor rolls `/aidlc --status` into stage execution instead of running
next --status, so the status block never renders. Out of scope here.

Test-only; no version bump (AGENTS.md changelog policy).

* fix: make Kiro read-only/nav commands deterministic mid-workflow — turn-scoped no-op-next guard + preToolUse backstop (v0.8.2)

On the Kiro CLI harness, over an active workflow, `/aidlc --status` / `--doctor`
/ `--help` / `--version` and the navigation verbs `space` / `space-create
<name>` / `intent <name>` could "roll forward": the live conductor relayed the
seam's injected output but then ran a flag-less bare `next`, the engine returned
a run-stage for the active intent, and the conductor executed it — advancing the
workflow when the user only asked to look or switch.

The userPromptSubmit seam (shipped earlier in 0.8.2) dispatches these terminal
commands off-band, but Kiro's userPromptSubmit can only inject context, not block
the turn — so the seam alone did not stop the trailing bare `next`. This change
neutralizes that bare `next` deterministically, keyed off a turn-scoped latch:

- Seam turn-clock (harness/kiro/hooks/aidlc-kiro-adapter.ts): the verb-intercept
  bumps a per-turn counter on every fire and stamps a latch on a read-only flag
  or a workspace verb.
- Engine no-op-next guard (core/tools/aidlc-orchestrate.ts, harness-neutral):
  a truly bare advancing `next` whose latch turn equals the current counter (the
  same turn) emits a terminal `done` — the forwarding loop's only formal exit —
  instead of a run-stage. Inert on Claude/Codex (no seam writes the latch there).
- preToolUse backstop (adapter `pretool-block` target, Kiro-only): if the
  conductor retries the bare `next` past the engine's `done`, the hook hard-blocks
  it (exit 2). All conductor hooks still route through the single adapter.

The `done` reason names the command and states the workflow is unchanged, so the
conductor relays the output and stops without falsely announcing completion
(live-verified on the ACP and TUI surfaces).

Live-gate verified: t-acp-kiro-status, t-acp-kiro-utilities,
t-acp-kiro-journey-workspace (3/3) and t-tui-kiro-status (2/2).

Tests:
- t148: expected conductor hook-key set updated (preToolUse + userPromptSubmit).
- t-acp-kiro-status / t-acp-kiro-utilities: read-only/nav now run off-band, so the
  tool_call assertions are repointed to stopReason==end_turn + on-disk no-op;
  config-change (a mutation) is unchanged. Byte-verbatim output stays covered by
  the SDK/CLI twins (t20/t22/t23/t27/t31).
- t-tui-kiro-status: assert the status display name ("Requirements Analysis"),
  matching what the status tool renders (not the stage slug).
- t178 (new): deterministic unit test for the shared classifyTerminalCommand
  classifier + READ_ONLY_FLAGS / WORKSPACE_VERBS sets.

dist/** regenerated; CHANGELOG 0.8.2 entry amended (no version re-bump).

Review hardening (ultracode review of this fix, ALIGNED-WITH-FIXES):
- Engine done-guard exemption reaches true parity with the preToolUse backstop —
  a bare `next --single` / `next --test-run` is never swallowed to `done`.
- t179: deterministic test for the engine no-op-next guard (fresh latch -> done,
  stale -> run-stage, --status -> print, --single -> run-stage, no-latch -> inert);
  proven to fail if the guard is reverted.
- t180: deterministic test for the Kiro seam — verb-intercept turn-counter +
  latch stamp (read-only / nav / freeform), and the preToolUse exit-2 backstop.

* chore(workspace): rebase onto v2; reconcile reviewer + kiro-ide harness; version trio → 2.1.0

Terminal P11 of the workspace-anchor effort: rebases the P0…P10 stack onto the
moved-main v2 base (origin/v2 @ f3ce1b8) and reconciles the two features that
landed on v2 during the build — the reviewer mechanism and the Kiro IDE harness
— with the workspace refactor. Reconcile-and-prove: the P0…P10 stack replayed
plus this one consolidating commit on top.

Conflicts resolved keep-both:
- t01-file-structure.test.ts — v2's 13-agent + 65-path structural assertions
  AND our mem() helper + the two relocated-memory path repoints.
- glossary.md — v2's dual-Kiro (CLI + IDE) row AND our space-level Knowledge row.
- aidlc-orchestrate.ts auto-merged clean: our roll-forward Branch 0 guard
  (handleNext) and v2's reviewer block (buildRunStageDirective) are in distinct
  functions, so both survive. t178/t179/t180 pass.

Reconcile the workspace memory relocation with v2's new agent surfaces (this
refactor moved core/rules/ → core/memory/, emptying the .kiro/steering/ dir the
v2 agents loaded their method from):
- Repoint all 5 Kiro IDE agents and the 2 Kiro CLI reviewer personas
  (product-lead, architecture-reviewer) from file://.kiro/steering/*.md to
  file://aidlc/spaces/default/memory/**/*.md, so the AIDLC method actually loads
  on those agents (matching the conductor + non-reviewer agents).
- Ship dist/kiro-ide/.gitignore (manifest dot-gitignore row + authored file) so
  the committed-vs-ignored split holds on Kiro IDE — cursors + machine-local
  runtime ignored, the shared work committed (the per-clone audit-shard scheme
  depends on the clone-id token staying gitignored).
- Rewrite the Kiro IDE onboarding (AGENTS.md) off the retired /aidlc --init +
  flat aidlc-docs/ model to the workspace shell + auto-birth wording.
- Harden t156 tests 5 + 7 to DERIVE the harness + agent lists from disk (was a
  hardcoded claude/kiro/codex + 3-agent list that let the kiro-ide tree and the
  two reviewer personas slip through). Negative-control verified: reverting any
  Kiro-family agent to the steering glob now fails t156.

Reconcile the Kiro IDE CONDUCTOR surface (two more surfaces the stack skipped —
on origin/v2 the kiro and kiro-ide SKILL.md were byte-identical, and the stack
diverged kiro CLI while leaving kiro-ide a stale fork that shipped green because
no test reads a per-harness conductor SKILL or write-grant):
- harness/kiro-ide/agents/aidlc.json — add aidlc/spaces/** to
  toolsSettings.fs_write.allowedPaths (matching kiro CLI). The workspace layout
  writes every artifact/diary/state/audit shard under aidlc/spaces/<space>/
  intents/…; without the grant a kiro-ide conductor is prompted on every
  framework write (Kiro gates writes outside the allowlist). The stale
  aidlc-docs/** + .kiro/steering/** entries are left in place to keep kiro ==
  kiro-ide byte-for-byte.
- harness/kiro-ide/skills/aidlc/SKILL.md — re-sync to the kiro CLI SKILL for the
  5 workspace deltas it was missing: drop --init from the utilities list + add
  the "intent and space verbs" tail; the print-directive routing word init →
  intent-birth (the engine emits intent-birth --scope, aidlc-orchestrate.ts:323);
  the swarm --repo flag + multi-repo paragraph; and the entire "offer a second
  intent" P4-completion section. The diff proved zero IDE-specific divergence
  existed (subagent-only swarm, no-statusline note, numbered-prose questions,
  "(Kiro CLI harness)" title are byte-identical in both), so the re-sync brought
  across exactly the 5 deltas and lost no IDE specific.
- tests/unit/t181-conductor-skill-parity.test.ts — new deterministic gate so the
  fork cannot recur (the unmet "extend the docs-sweep to the 4th tree"
  obligation). Derives the harness-SKILL list FROM DISK (mirrors t156 §7,
  readdirSync+filter+floor — no hardcoded triple) and gates every shipped
  conductor SKILL in both directions: the retired bare --init token must be
  ABSENT (same predicate as t174) and the workspace vocabulary (intent-birth,
  --repo, "offer a second intent", "intent and space verbs") must be PRESENT.
  Negative-control proven both ways.

Version trio → 2.1.0 (a minor bump over v2's 2.0.2, reflecting the partly-breaking
workspace layout change): aidlc-version.ts, README badge, and one consolidated
## [2.1.0] CHANGELOG heading folding the former 0.8.0/0.8.1/0.8.2 notes above
v2's 2.0.x blocks. t68 green.

Also fixes stale flat-layout prose in docs/guide/harnesses/kiro-ide.md (a v2 file
that predated the P9 workspace refactor): /aidlc --init → workspace auto-birth,
aidlc-docs/ → the per-intent record dir. Restores t174 (docs legacy-refs gate).

All four dist trees (claude, kiro, codex, kiro-ide) regenerated from merged
source; bun scripts/package.ts --check clean.

---

Docs-freshness sweep (folded in): bring the prose docs up to date with the
workspace refactor + reviewer + Kiro IDE — discharging the Documentation Policy
(grep docs/ for stale refs and fix in the same commit as the rename). Pure-doc
+ test-only per the Changelog Policy carve-out, so no version re-bump (trio
stays 2.1.0). 57 files: 44 authored docs/prose, 4 harness SKILL.md, 3 test
files + 1 fixture, 8 regenerated dist renders.

- Rules relocation: .claude/rules/ (+ .kiro/steering/, .codex/aidlc-rules/,
  core/rules/) → aidlc/spaces/<space>/memory/{org,team,project}.md +
  phases/<phase>.md across guide/reference/harness-engineering, README, AGENTS,
  onboarding template, and all 4 orchestrator SKILL.md. Neutral filenames
  (org/team/project.md), read via each harness's native include.
- Learnings → practices: dropped the retired *-learnings.md surface and the
  1.5/2.5 SCOPE_PRIORITY tiers; confirmed learnings now land as practices in
  memory/{team,project}.md (clean integer chain org:0/team:1/project:2/phase:3).
- Audit shards: flat audit.md → per-clone audit/<host>-<clone>.md, and fixed a
  contradiction (15-troubleshooting said audit.md was gitignored; it is
  committed per 13-artifacts + 09-state + dist .gitignore).
- Agent count: per-occurrence 11→13 only where a file total or all-agents
  enumeration omitted the 2 reviewers; kept "11 domain experts" where correct.
- Documented missing features as sections in existing chapters (no new chapter):
  glossary terms (Space, Intent, Record dir, Reviewer, Multi-repo intent), the
  reviewer mechanism (05-agents + 15-stage-definition schema + 04-stage-protocol
  step), multi-repo (11-cli-commands + 13-artifacts), and the Kiro IDE 4th-harness
  enumerations.
- Gate extensions so the debt can't recur: t174 now derives its scanned file
  list from disk (docs/ + core/templates/*.md + harness/*/skills/aidlc/SKILL.md)
  and adds rules-dir + *-learnings.md token lanes (negative-control proven); t55
  PATH_PATTERNS gains the learnings-log lane (dotted-rules lane deferred to t174
  to avoid duplicating 77 legitimate native-include survivors). t06 positive
  layout anchor repointed to the relocated space-memory path. core/aidlc-common/
  reroot (410 aidlc-docs refs) deliberately deferred to its own migration.

* docs(aidlc-common): reroot aidlc-docs → per-intent record dir

Reroot the retired flat `aidlc-docs/<phase>/<stage>/...` workspace layout to
the per-intent record dir `<record>/...` (= `aidlc/spaces/<space>/intents/
<slug>-<id8>/`) across the 36 engine-parsed stage + protocol .md files under
core/aidlc-common/. These carried the OLD flat paths from before the P0–P11
workspace refactor; the engine already resolves the new per-intent forms.

- 410 → 1 `aidlc-docs` occurrences (the 1 survivor is the stage-definition.md
  rule prose where `aidlc-docs/…` is an explicit anti-pattern example).
- 18 flat `audit.md` path refs → per-clone shard `<record>/audit/<host>-<clone>.md`;
  shard-model semantics preserved (append-never-overwrite, header-on-create,
  .bak-on-corruption reworded for "this clone's shard").
- 29 `outputs:` frontmatter lines → relative artifact names (engine-resolved form).
- 40 `{unit-name}` per-unit construction segments preserved (moved out of
  `outputs:` into body cross-stage read paths).
- workspace-detection.md scanner/brownfield-marker refs → workspace root `aidlc/`.

Regenerated all 4 dist trees (claude/codex/kiro/kiro-ide); package.ts --check OK.
No version bump: a path-only reroot of engine prose with no change to any
user-invoked command/flag/error (outputs: is non-load-bearing).

Test fallout (the migration's own verifying tests), all repointed to the new
canonical forms preserving intent:
- t35/t43/t44 — path-pin assertions → `<record>/` forms.
- t66 designer-export golden regenerated (pure outputs:/path reroot diff).

Verified: typecheck 0; construction e2e 10/10 PASS (8 scopes + bolt-fork +
swarm-referee); full default tier 210 files / 3466 assertions / 0 fail.

* feat(workspace): deterministic per-repo codekb placement via codekb-path tool + isCodekb resolver

Reverse-engineering wrote its 9 codekb artifacts to an LLM-discretion location
(prose named the path; two live runs drifted to two wrong places). Make placement
deterministic by giving the engine the canonical path and having RE defer to it.

- New read-only `/aidlc codekb-path [--repo <name>] [--json]` verb prints the
  space-level per-repo codekb dir `aidlc/spaces/<space>/codekb/<repo>/` (no mkdir,
  no state, no audit — a read-only query verb like `intent`/`space`).
- aidlc-lib: `codekbDir` / `relativeCodekbDir` / `codekbRepoName` (mirror
  `knowledgeDir` / `relativeRecordDir`; codekbRepoName is 2-way: lone recorded
  repo, else basename(projectDir)).
- aidlc-orchestrate: `isCodekb` keyed on KNOWN_CODEKB_STAGES (reverse-engineering)
  — NO frontmatter marker (stage-schema rejects it). New resolver arm in
  resolveArtifactPath keeps the aidlc/spaces/<space>/ stem and drops the
  intents/<slug> tail, so the directive JSON + audit + consumes[] agree with the
  tool. A small {projectDir,space,codekbRepo} ctx is threaded down the same spine
  recordPrefix travels (every emit site).
- RE stage prose defers to the tool (run codekb-path, write where it prints,
  never hand-compose); 3 consumer stages repointed to the space-level read.
  memory.md stays in the record dir (the intentional split).
- Version trio 2.1.0 -> 2.1.1 (version.ts + README badge + CHANGELOG); docs
  carve-out in 16-artifact-vocabulary.md + the utility-handler note in
  11-contributing.md.
- Tests: new deterministic guard t182 (helpers + verb + resolver branch) + new
  live SDK re-verify t183 (drives RE, asserts 9 artifacts land at the space-level
  codekb, none in the record dir); repointed t116/t154/t43/t-journey/t72/t50;
  coverage registry + ratchet regenerated (new units credited), gen-coverage
  reclassification pin updated.
- dist regenerated for all 4 harness trees.

* fix(codekb): repoint re-artifacts.md shorthand to space-scoped path + extend t154 sweep to knowledge tree

The RE artifact-template knowledge doc (aidlc-developer-agent/re-artifacts.md)
still carried the bare `aidlc/codekb/<repo>/` shorthand after the
codekb-determinism placement fix made the store space-scoped. It is live
knowledge the reverse-engineering stage reads (reverse-engineering.md:91), so
the stale path is misleading. Repoint it to the space-scoped
`aidlc/spaces/<active-space>/codekb/<repo>/` form (the dir the codekb-path tool
resolves), matching the RE stage prose.

t154's bare-codekb guard (test 6) swept only aidlc-common/stages/, so this
residual escaped. Add test 7 to walk the knowledge tree recursively for the same
bare form, closing the guard gap.

* feat(workspace): active-space following — resolver + harness includes follow the cursor (#1) + templates framework-default branch (#4) + space-create skeleton (#5)

Makes AIDLC's method, its harness-native rule includes, and its own rule
resolver follow the active-space cursor instead of being pinned to `default`.
Single-team/default users are unaffected (zero churn). Bumps to 2.2.0.

#1 — resolver follows the cursor:
- aidlc-graph.ts: memoryDirFor()/memoryTemplatesDir() take an optional `space?`
  defaulting to activeSpace(projectDir) (cursorless → default), via a new
  memorySegmentsForSpace() helper mirroring the lib.ts space?-param precedent.
  The learnings/practices writers + the templates sensor follow the cursor for
  free. rulesDir()/memoryDisplayPath() stay default-pinned — rules_in_context is
  display paths frozen at PACKAGE time (not a runtime content channel), so the
  load-bearing rule delivery is the native includes + the writers.
- aidlc-includes.ts (NEW): repointHarnessIncludes(projectDir, space?) surgically
  rewrites ONLY the pointer segment of the active harness's native include in
  place — Claude @-stub, Kiro agents/*.json resources glob, Codex AIDLC_RULES_DIR.
  The include files stay COMMITTED (each carries load-bearing engine wiring the
  CLI reads at startup before any hook could regenerate it — gitignoring them is
  a fresh-clone chicken-and-egg). Idempotent: a no-op at `default`, so a
  single-team committed tree never churns. Preserves vision §11.6 "reference,
  not copy" (a committed pointer has no rule content to drift).
- Wired into the space switch (handleSpace), bootstrap (ensureWorkspaceDirs),
  the SessionStart ensure-step, and the --doctor readiness check (pinned to
  DEFAULT_SPACE). Retires the stale "fast-follow / out of scope" deferral.

#4 — templates framework-default branch:
- frameworkTemplatesDir() (NEW) + dispatcher threads --framework-templates-dir;
  the required-sections sensor resolves team → framework-default → floor
  (resolveTemplatePath, first hit wins); stage-protocol.md agent clause matches.
  Ships ZERO default files (the middle tier exists + is extensible; behaviour is
  unchanged until a default is authored).

#5 — space-create skeleton:
- handleSpaceCreate now seeds the full {memory, codekb, knowledge, intents} shape
  (codekb/ + knowledge/ with .gitkeep floors), matching default.

Folded-in cleanups (internal build + test fixture; no version impact):
- #7: remove the dead `{ src:"rules", dst:"steering" }` manifest row from
  harness/kiro + harness/kiro-ide (core/rules/ is gone; .kiro/steering/ was never
  a committed output — Kiro reads the agents/*.json resources glob now). Keep
  `rulesRename: "steering"` — it independently rewrites in-prose steering mentions
  + compiled-data paths (package.ts:87-89,383-388). dist byte-identical.
- t66: regenerate the stale designer-export golden (export.json:718 still said
  flat aidlc/codekb/<repo>/; live emits aidlc/spaces/<active-space>/codekb/<repo>/
  from the codekb merge). t66 green 86/0.

Tests: new t-active-space-includes (9); t155 +4 middle-branch tests; t165 stale
"pure cursor write" comment fixed; three journey tests updated for the #5 shape
(t-journey-workspace.sdk — verified live; t-acp-kiro-journey — verified live;
t-exec-codex-journey — edit matches, codex-exec flaked upstream so unverified-live).
coverage registry regenerated (function 77→78). Version trio → 2.2.0 + CHANGELOG +
README badge (t68). Docs + vision §8/§9 reflect shipped reality.

* docs: add Spaces and Intents user-guide chapter + workspace sections

Adds a dedicated, standalone-shareable chapter teaching how to use spaces
and multiple intents, plus cross-guide sections, all verified against source
on this branch.

- New docs/guide/03-spaces-and-intents.md: the workspace layout (annotated
  tree), intents (auto-birth, offer-a-second-intent, switching), spaces
  (create/list/switch, active-space following), multi-repo, and the
  committed-vs-gitignored split. Reads in sequence after Your First Workflow
  and stands alone as a link.
- Renumber: old guide chapters 03-13 -> 04-14 to free the 03 slot; all
  cross-references across docs/ + README rewritten; closes the pre-existing
  13->15 gap into a contiguous 00-17. Guide Map + nav pointers updated.
- Harness Engineer Guide: "Spaces: knowledge for more than one team" section
  in 07-team-knowledge.md (the per-space, data-not-code angle).
- Developer Reference: "The workspace: spaces and intents" data-model section
  in 01-architecture.md (the aidlc/ tree, cursor resolution, commit split).
- aidlc-sensor-fire.ts first-run banner: drop the literal doc-chapter path
  (now "See the AI-DLC documentation"), decoupling docs from shipped code so
  the renumber can't stale it. Regenerated dist copies.
- Fix stale audit-shard comment <host>-<pid>.md -> <host>-<clone>.md in
  aidlc-lib.ts and the four dot-gitignore files (the code uses the clone-id,
  not the PID); regenerated dist.

Comment/string/docs only — no logic change, no version bump (advisory stderr
text + comments are not user-invocable behavior).

* chore(version): reconcile workspace-anchor to 2.1.0 per roadmap

The roadmap assigns the per-intent workspace feature (this branch,
feature/workspace-anchor) to the 2.1.0 minor cut, reserving 2.2.0 for the
later reviewer-as-verifier work. The branch had drifted to 2.2.0 because the
codekb and active-space sub-parts each took their own minor bump
(2.1.0 -> 2.1.1 -> 2.2.0), but they are all part of the one workspace feature
that ships as a single minor.

- aidlc-version.ts: 2.2.0 -> 2.1.0 (+ regenerated dist copies)
- README badge: 2.2.0 -> 2.1.0
- CHANGELOG: consolidate the 2.2.0 (active-space following) and 2.1.1 (codekb
  placement) entries up into the single 2.1.0 (per-intent workspace) entry,
  dated 2026-06-24; add the Spaces and Intents chapter pointer.

t68 (version/CHANGELOG/README sync) green; headings unique; no dist drift.

* test(codex): live-verify the method-include seam — closes the t156 doc-only flag

Adds a gated live e2e probe that finalizes what t156 test 8 could only
DOC-VERIFY: that Codex resolves an @aidlc/spaces/default/memory/<file> mention
against the SHIPPED dist/codex tree and pulls the relocated method content into
context. An earlier spike hung at exit 124 and left the seam flagged untested;
it now reproduces green on codex-cli 0.139.0 (openai.gpt-5.5 on Bedrock).

- New tests/e2e/t-exec-codex-memory-include.serial.test.ts: injects a unique
  sentinel into the active space's org.md, drives `codex exec` with an @-path
  mention, asserts the sentinel round-trips. Gated by AIDLC_CODEX_EXEC_LIVE=1
  (skips cleanly otherwise); joins the t-exec-codex-* live-driver family.
- t156: drop the "FLAGGED untested / DOC-VERIFIED ONLY / exit 124" framing from
  test 8 and the file header; point at the new e2e test. Static unit-tier
  assertions unchanged (zero-LLM contract intact).

Verified: new e2e 1/1 green live; t156 9/9; t55 + coverage-registry freshness
green; typecheck clean. Test-only — no version/CHANGELOG bump.

* docs(spaces-and-intents): make the engine-dir references harness-neutral

The chapter described the engine directory as `.claude/` throughout, reading as
Claude-only. Reframe to match the guide convention (harness-neutral prose, Claude
as the shown example with variants named): the engine dir is the one
harness-specific directory (`.claude/` / `.kiro/` / `.codex/`), the workspace tree
notes the substitution inline, and the prose points at "the engine directory"
rather than `.claude/`. The active-space-following section already named all
three harnesses; left as-is. Command prefix stays `/aidlc` (the guide-wide
canonical form; the Codex `$aidlc` variant is documented in its harness chapter).

* docs(install): copy the aidlc/ workspace shell alongside the engine dir

A collaborator testing PR #429 on Kiro IDE followed the install steps literally
(engine dir only) and `/aidlc --doctor` failed its "workspace shell ready" check:
aidlc/spaces/default/memory/ was absent. Root cause: the aidlc/ workspace shell
ships as a SIBLING of the engine dir (.claude/.kiro/.codex) in every dist tree,
but the install instructi…
harmjeff added a commit that referenced this pull request Jul 6, 2026
…en packager, bump 2.3.0

Compose hook (review #1/#2/awslabs#6/awslabs#7/awslabs#10/awslabs#11/awslabs#12): fold compose.sh +
compose-contributions.ts + compose-fragments.ts into a single portable
compose.ts (bun). Removes the shell-portability bug class — GNU-only
`sed -i` → replaceAll, BSD/coreutils>=9.2 `cp -rn` clobber → existsSync
no-clobber guard, swallowed `2>/dev/null || true` → recordDrop to
aidlc/.aidlc-hooks-health/plugin-compose.drops. Anchors validated +
escaped (skip-with-log, never a thrown regex); splices idempotent via
sentinel markers; compare-before-write; recompile only when changed.

Packager (review #3/#4): emit the kiro-ide projection too (four harness
trees now); `--check` byte-parity drift-guards dist/plugins/ (verified it
catches a tampered projection file).

Compose read half (review awslabs#5/awslabs#8): handle the inline-empty `field: []`
form; normalize CRLF once so every block/list regex is newline-safe.

Docs (awslabs#9/awslabs#13): README repo-layout adds plugins/ + dist/plugins/;
doc 18 gets a Kiro folder-drop security note (no install-time trust gate)
and drops stale two-helper / three-host references.

Also: remove spikes/dist-probe/ from the PR; bump 2.2.0 → 2.3.0
(version.ts + README badge + CHANGELOG); update t188 for compose.ts +
the four-harness projection set.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
harmjeff added a commit that referenced this pull request Jul 7, 2026
…en packager, bump 2.3.0

Compose hook (review #1/#2/awslabs#6/awslabs#7/awslabs#10/awslabs#11/awslabs#12): fold compose.sh +
compose-contributions.ts + compose-fragments.ts into a single portable
compose.ts (bun). Removes the shell-portability bug class — GNU-only
`sed -i` → replaceAll, BSD/coreutils>=9.2 `cp -rn` clobber → existsSync
no-clobber guard, swallowed `2>/dev/null || true` → recordDrop to
aidlc/.aidlc-hooks-health/plugin-compose.drops. Anchors validated +
escaped (skip-with-log, never a thrown regex); splices idempotent via
sentinel markers; compare-before-write; recompile only when changed.

Packager (review #3/#4): emit the kiro-ide projection too (four harness
trees now); `--check` byte-parity drift-guards dist/plugins/ (verified it
catches a tampered projection file).

Compose read half (review awslabs#5/awslabs#8): handle the inline-empty `field: []`
form; normalize CRLF once so every block/list regex is newline-safe.

Docs (awslabs#9/awslabs#13): README repo-layout adds plugins/ + dist/plugins/;
doc 18 gets a Kiro folder-drop security note (no install-time trust gate)
and drops stale two-helper / three-host references.

Also: remove spikes/dist-probe/ from the PR; bump 2.2.0 → 2.3.0
(version.ts + README badge + CHANGELOG); update t188 for compose.ts +
the four-harness projection set.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
harmjeff added a commit that referenced this pull request Jul 8, 2026
…en packager, bump 2.3.0

Compose hook (review #1/#2/awslabs#6/awslabs#7/awslabs#10/awslabs#11/awslabs#12): fold compose.sh +
compose-contributions.ts + compose-fragments.ts into a single portable
compose.ts (bun). Removes the shell-portability bug class — GNU-only
`sed -i` → replaceAll, BSD/coreutils>=9.2 `cp -rn` clobber → existsSync
no-clobber guard, swallowed `2>/dev/null || true` → recordDrop to
aidlc/.aidlc-hooks-health/plugin-compose.drops. Anchors validated +
escaped (skip-with-log, never a thrown regex); splices idempotent via
sentinel markers; compare-before-write; recompile only when changed.

Packager (review #3/#4): emit the kiro-ide projection too (four harness
trees now); `--check` byte-parity drift-guards dist/plugins/ (verified it
catches a tampered projection file).

Compose read half (review awslabs#5/awslabs#8): handle the inline-empty `field: []`
form; normalize CRLF once so every block/list regex is newline-safe.

Docs (awslabs#9/awslabs#13): README repo-layout adds plugins/ + dist/plugins/;
doc 18 gets a Kiro folder-drop security note (no install-time trust gate)
and drops stale two-helper / three-host references.

Also: remove spikes/dist-probe/ from the PR; bump 2.2.0 → 2.3.0
(version.ts + README badge + CHANGELOG); update t188 for compose.ts +
the four-harness projection set.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants