Skip to content

feat(claude): local SDD overrides that survive gentle-ai, and the pipeline as a workflow - #4

Draft
NicolasMarino wants to merge 3 commits into
mainfrom
feat/sdd-local-overrides
Draft

feat(claude): local SDD overrides that survive gentle-ai, and the pipeline as a workflow#4
NicolasMarino wants to merge 3 commits into
mainfrom
feat/sdd-local-overrides

Conversation

@NicolasMarino

@NicolasMarino NicolasMarino commented Aug 31, 2026

Copy link
Copy Markdown
Owner

Two work units from an audit of the SDD setup against what Claude Code can do
today. Draft — nothing here has run against a real change yet.

Why

I measured the 10 archived SDD changes in reels-lab before touching anything.
The pipeline found zero implementation defects by code review:

3 FAIL verdicts all missing tests — every report says the code was correct
1 change with 6 remediation rounds one requirement that never enumerated its entry points
6 changes clean in one pass

So the bottleneck is upstream, in sdd-spec and sdd-tasks, not in sdd-apply.
That killed the obvious hypothesis (raise the apply model) and pointed the rules
somewhere else entirely. Raw table in the knowledge vault under
03_Resources/Tech/IA Engineering/.

The two commits

cf28eb0 — local SDD rules that survive a sync. L1–L7 in
claude/gentle-ai-overrides/, plus the reconciler that keeps them alive.

The durability rule is the interesting part. InjectMarkdownSection rebuilds
CLAUDE.md as before + block + after per gentle-ai marker, so anything past
the last marker survives untouched — that is where the block goes, under its
own sentinels. Agent definitions get no such courtesy (WriteFileAtomic per
embedded file, no merge), so memory: project on the six reviewer agents is
re-applied instead. reconcile.sh runs from the installer, from a gentle-ai
wrapper in zsh/functions.zsh after install|sync|upgrade, and as --check
for CI.

7e1944d — wire the new suite into CI. The override tests only ran locally.
Two portability fixes were needed for the Linux runner (md5 -q is macOS-only;
neither suite's scripts find rg on the runner image), and the installer's
parse-check glob stopped at claude/*.sh, so reconcile.sh was never
syntax-checked.

ed4219e — the SDD DAG as a Workflow script. claude/workflows/sdd-chain.js.
Exploration fans out, spec and design run in parallel (neither ever depended on
the other), apply and verify pipeline per work unit. Parallel writers are gated
on a proven file partition — any unit sharing a file drops back to serial.

Verification

  • claude/test-overrides.sh — 22/22 locally and on the Linux CI runner, against a throwaway CLAUDE_DIR
  • claude/test-hooks.sh — 35/35, unchanged
  • shellcheck, gitleaks — clean
  • scripts/claude.sh end to end — the settings merge preserved SessionStart,
    UserPromptSubmit, autoMode and outputStyle
  • Drift simulated: deleted memory: project from jd-judge-a, --check
    reported it, the wrapper restored it, file byte-identical to the original

Two things to weigh

This is ~980 lines, over the 400-line budget. The two commits are
independent — ed4219e reverts cleanly on its own — so it can become two
chained PRs if reviewing it as one is too much.

sdd-chain.js has never been executed. Running a workflow needs explicit
per-call opt-in. The syntax parses and it installs, but L1–L7 and the partition
logic stay unproven until a real change runs through them.

Not in scope

Deferring the RDD contract's always-on load. It lives inside the
gentle-ai:sdd-orchestrator marker, which is rewritten on every sync, and a
local rule cannot unload text already in context. That one needs a change in
the gentle-ai repo.

gentle-ai owns ~/.claude/skills/, ~/.claude/agents/ and most of CLAUDE.md,
so local rules that outrank it had nowhere durable to live. Two different
durability rules turn out to apply, and this change uses both.

InjectMarkdownSection rebuilds CLAUDE.md as before + block + after for one
gentle-ai marker at a time, so anything past the last marker survives a sync
untouched. CLAUDE.local-overrides.md is appended there under its own
sentinels. Agent definitions get no such courtesy — every file in the embed
is overwritten wholesale — so `memory: project` on the six reviewer agents is
re-applied instead.

The rules themselves (L1-L7) come from measuring 10 archived SDD changes in
reels-lab, where the pipeline found zero implementation defects by code
review: every FAIL was a missing test, and the one change that needed six
remediation rounds was a single requirement that never enumerated its entry
points. They push that work upstream into spec and tasks rather than paying
for it in verification rounds.

reconcile.sh is idempotent and runs from three places, so drift never needs
fixing by hand: the installer, the gentle-ai wrapper (after install, sync and
upgrade — the only commands that cause drift), and --check for CI. It refuses
to edit a CLAUDE.md whose gentle-ai markers are unbalanced, because that means
an interrupted sync and the block would land inside a region about to be
rewritten.

Verification:
- claude/test-overrides.sh: 22/22 pass, against a throwaway CLAUDE_DIR
- claude/test-hooks.sh: 35/35 still pass
- shellcheck --exclude=SC1091,SC2088: clean
- scripts/claude.sh end to end: settings merge preserved SessionStart,
  UserPromptSubmit, autoMode and outputStyle
- drift simulated by deleting `memory: project` from jd-judge-a: --check
  reported it, the wrapper restored it, file byte-identical to the original

Rollback: delete claude/gentle-ai-overrides/ and claude/test-overrides.sh,
revert the reconcile block in scripts/claude.sh and the wrapper in
zsh/functions.zsh. Nothing else depends on them.
The SDD dependency graph lived only in prose, so the orchestrator had to
re-derive the phase order, the gatekeeper and the review-workload guard from
23k tokens of instruction every session. sdd-chain.js makes the execution
order a script and leaves the model the judgment.

Three phases stop being accidentally serial. Exploration is breadth-first and
read-only, so it fans out across current-state, prior-art and entry-point
readers before one synthesis. Spec and design run in parallel — both read only
the proposal, so nothing ever required ordering them. Apply and verify are
pipelined per work unit rather than barriered, so a unit is verified while the
next is still being written.

Parallel writers are gated on a proof, not a promise: the task schema makes
every work unit declare the files it writes, and any unit sharing a file with
another, or declaring a dependency, drops back to serial. Two agents on one
file overwrite each other, which costs a whole run rather than saving one.

The schemas also replace most of the prose contract-conformance gate, since a
phase returning the wrong shape is retried at the tool-call layer. The verify
schema requires every CRITICAL to be classified coverage, spec_ambiguity or
implementation, with an explicit instruction not to default to the last —
that is what keeps the measurement behind L1-L7 fed by each run instead of
needing to be excavated from the archives again.

Verification:
- syntax parsed as an async function body with the runtime's globals
- scripts/claude.sh links it into ~/.claude/workflows/ and both suites pass
- N/A for a runtime harness run: executing a workflow needs explicit per-call
  opt-in, and this change only installs the script. The DAG is unproven until
  a real change runs through it.

Rollback: delete claude/workflows/ and revert the symlink block in
scripts/claude.sh. The overrides in the previous commit do not depend on it.
The override tests only ran locally, from scripts/claude.sh. A suite CI never
runs is a suite that rots, and this one guards edits to CLAUDE.md and to agent
frontmatter — exactly the code where silent breakage is expensive.

Two portability fixes were needed to run it on the Linux runner: `md5 -q` is
macOS-only, so digest() falls back to md5sum, and both suites drive scripts
that call rg, which the runner image does not ship.

The installer's parse-check glob also stopped at claude/*.sh, so reconcile.sh
was never syntax-checked. It now includes the nested directory.

Verification: 22/22 locally on macOS after the digest change; shellcheck clean.
Rollback: revert this commit — the suites still run from scripts/claude.sh.
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