Skip to content

Fall back to master for the base branch; pass decision bodies through a quoted heredoc (DL-090, DL-091) - #105

Merged
jimutt merged 11 commits into
mainfrom
claude/base-and-bodies
Nov 2, 2026
Merged

jimutt merged 11 commits into
mainfrom
claude/base-and-bodies

Conversation

@jimutt

@jimutt jimutt commented Nov 2, 2026 •

Copy link
Copy Markdown
Owner

#101 to #104 are now on main, and main has been merged into this branch (4cc34e9). The diff shows only this PR's work.

The end-to-end run for #104 turned up two problems that are already on main. This PR fixes both before rc.6.

DL-090: master repositories (amends DL-071, DL-076)

Problem: the base-branch lookup only tried origin/HEAD, origin/main and main. So in a repo whose main branch is master, with no remote, check-decision-edits gave no protection, and list-proposed exited 1 without listing anything.

Fix:

  • The lookup now tries origin/master, then master, after main. A repo that has both still resolves to main.
  • Without --base, when no base resolves, list-proposed lists every proposed decision as unknown, warns, and exits 0.
  • A base that is set explicitly but doesn't resolve still fails, whether it comes from --base or from base_branch.
  • /dld-implement shows the unknown lines with none selected. If list-proposed fails for another reason, it reads the records directly.
  • resolve-base help, the reindex skill and the configuration spec now describe the new order.

DL-091: decision bodies through a quoted heredoc

Problem: /dld-decide, /dld-plan and /dld-retrofit piped the body through printf "...". In double quotes the shell ran anything in backticks or $(...) as a command, and printf mangled %. Decision bodies very often contain code in backticks.

Fix:

  • The skills now use create-decision ... --body-stdin <<'DLD_BODY' with real newlines. Titles and tags are single-quoted, and the skills say where the closing delimiter goes.
  • The skill generator enforces this. In a template's code blocks, it rejects any create-decision --body-stdin command that has something piped into it or doesn't use a quoted heredoc. Backslash-continued lines are joined first, and prose mentions aren't checked.

OVERVIEW.md now covers DL-090 and DL-091.

Testing

  • Unit and CLI tests: 551 unit tests and 17 CLI tests, re-run after the merge. Lint, typecheck and check:generated pass.
  • End to end in the synthetic master repo:
    • resolve-base finds master.
    • An edit to the prose of a decision that's on master is caught (exit 3).
    • With neither main nor master, list-proposed lists the decision as unknown and warns.
  • End to end for the heredoc form:
    • A body containing backticks, $subtotal, $(whoami), %s, %% and a literal \n was recorded byte for byte, with nothing executed.
    • So was a title with an apostrophe and backticks, written in the new single-quoted form.
  • Review: a review subagent found no critical issues. I fixed all of its moderate findings and most of the minor ones.

Changeset: patch.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GmUuswDi3BJNN76DyoJHCG

docs/releasing.md now lists everything semver covers from 1.0.0: decision records,
annotations, the config schema, the setup and CI commands and the Decision-Edit
trailer, skill names, distribution channels and file names, and the Node support
policy; the README points to it and the record format spec says unknown frontmatter
fields are kept and ignored. Node 20 is end-of-life, so engines, the build target,
@types/node, the CI matrix (22, 24) and every compatibility line move to Node 22.
package-lock.json catches up with @changesets/cli.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GmUuswDi3BJNN76DyoJHCG
Add the installed layout and rule-block markers, the --agent names, the skill and
dld-common names, every install channel, PRACTICES.md and the config location to the
contract, and the section headings the CLI reads. Reserve the x- prefix for projects'
own frontmatter fields and config keys, and stop warning about x- config keys. Test
Node 26, now active LTS. Skills that edit frontmatter by hand keep unknown fields, and
the 0.x upgrade guide states the Node requirement.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GmUuswDi3BJNN76DyoJHCG
…e/review-settings

# Conflicts:
#	skills/dld-snapshot/SKILL.md
#	templates/skills/dld-snapshot/SKILL.md
…087 to DL-089)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GmUuswDi3BJNN76DyoJHCG
…7 to DL-089)

dld.local.yaml holds one developer's review settings for a checkout, over
dld.config.yaml; it accepts only the review keys and x- keys, and init and update add
it to .gitignore. review_model, implement_review_model and plan_review_model pick the
reviewers' model, and plan_review adds a review subagent to /dld-plan. The new
internal command review-settings resolves them for the implement and plan skills.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GmUuswDi3BJNN76DyoJHCG
Warn when dld.local.yaml is committed, respect a deliberate !dld.local.yaml rule,
reject multi-line or padded model names, document `default` as the reset, drop the
unused Config.implementReview, keep the developer's global git excludes out of the
test fixture, and complete the skills' report lines and plan-review placeholders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GmUuswDi3BJNN76DyoJHCG
… a heredoc (DL-090, DL-091)

resolve-base tries origin/master and master after main, and list-proposed lists every
proposed decision as unknown, with a warning, when no base branch is found. The decide,
plan and retrofit skills pass the body to create-decision through a quoted heredoc
instead of printf, so backticks, $ and % are recorded as written; the generator rejects
a template that pipes printf into create-decision.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GmUuswDi3BJNN76DyoJHCG
A configured base_branch that doesn't resolve fails list-proposed, like --base. The
generator now checks every create-decision --body-stdin command in a code block, across
continued lines: no pipe into it, and a quoted heredoc. The skills single-quote titles
and tags and say where the closing delimiter goes, the reindex skill and resolve-base's
docs give the new order, /dld-implement says what to do if list-proposed fails, and the
records and tests cover the remaining cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GmUuswDi3BJNN76DyoJHCG
@github-actions

github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Unit test coverage

Lines Functions
Total 99.77% 98.78% (+0.01)

Changes are relative to main.
The floor is 90% of lines and functions in each file; ⚠️ marks files below it.

Per file
File Lines Functions
scripts/release.ts (new) 100.00% 100.00%
src/cli/command.ts 96.88% 100.00%
src/cli/commands/base-option.ts 100.00% 100.00%
src/cli/commands/check-decision-edits.ts 100.00% 100.00%
src/cli/commands/collect-active-decisions.ts 100.00% 100.00%
src/cli/commands/commit-reindex.ts 100.00% 100.00%
src/cli/commands/create-config.ts 100.00% 100.00%
src/cli/commands/create-decision.ts 100.00% 100.00%
src/cli/commands/create-directories.ts 100.00% 100.00%
src/cli/commands/create-empty-index.ts 100.00% 100.00%
src/cli/commands/detect-snapshot-changes.ts 100.00% 100.00%
src/cli/commands/find-annotations.ts 100.00% 100.00%
src/cli/commands/find-collisions.ts 100.00% 100.00%
src/cli/commands/find-missing-amends.ts 100.00% 100.00%
src/cli/commands/find-stale-mentions.ts 100.00% 100.00%
src/cli/commands/init.ts 100.00% 100.00%
src/cli/commands/install-rule.ts 100.00% 100.00%
src/cli/commands/list-proposed.ts 100.00% 100.00%
src/cli/commands/list-taken-ids.ts 100.00% 100.00%
src/cli/commands/next-id.ts 100.00% 100.00%
src/cli/commands/plan-renames.ts 100.00% 100.00%
src/cli/commands/regenerate-index.ts 100.00% 100.00%
src/cli/commands/related-decisions.ts 100.00% 100.00%
src/cli/commands/rename-decision.ts 100.00% 100.00%
src/cli/commands/resolve-base.ts 100.00% 100.00%
src/cli/commands/restore-decision-prose.ts 100.00% 100.00%
src/cli/commands/review-settings.ts 100.00% 100.00%
src/cli/commands/session-context.ts 100.00% 100.00%
src/cli/commands/update-audit-state.ts 100.00% 100.00%
src/cli/commands/update-snapshot-state.ts 100.00% 100.00%
src/cli/commands/update-status.ts 100.00% 100.00%
src/cli/commands/update.ts 100.00% 100.00%
src/cli/commands/verify-annotations.ts 100.00% 100.00%
src/cli/index.ts 100.00% 100.00%
src/cli/install.ts 100.00% 100.00%
src/core/annotations.ts 100.00% 93.75%
src/core/audit.ts 100.00% 100.00%
src/core/commit-reindex.ts 100.00% 100.00%
src/core/config.ts 100.00% 92.86%
src/core/decision-edits.ts 99.47% 100.00%
src/core/decisions.ts 100.00% 100.00%
src/core/errors.ts 100.00% 100.00%
src/core/files.ts 100.00% 100.00%
src/core/git.ts 100.00% 100.00%
src/core/ids.ts 100.00% 100.00%
src/core/index-file.ts 98.21% 100.00%
src/core/init.ts 100.00% 100.00%
src/core/mentions.ts 100.00% 100.00%
src/core/open-prs.ts 100.00% 100.00%
src/core/project.ts 100.00% 100.00%
src/core/proposed.ts 100.00% 100.00%
src/core/records.ts 100.00% 100.00%
src/core/reindex.ts 99.37% 100.00%
src/core/related.ts 97.56% 100.00%
src/core/rename-plan.ts 100.00% 100.00%
src/core/rename.ts 100.00% 100.00%
src/core/review-settings.ts 100.00% 100.00%
src/core/snapshot.ts 100.00% 100.00%
src/core/state.ts 97.92% 100.00%
src/generate/adapters.ts 100.00% 100.00%
src/generate/generate.ts 99.38% 96.15%
src/generate/gitattributes.ts 100.00% 100.00%
src/generate/gitignore.ts 100.00% 100.00%
src/generate/harnesses.ts 100.00% 100.00%
src/generate/install.ts 100.00% 100.00%
src/generate/plugins.ts 100.00% 100.00%
src/generate/rule.ts 100.00% 98.33%
src/generate/template.ts 100.00% 100.00%
src/node-context.ts 97.09% 95.56%
templates/rules/dld-workflow.md 100.00% 100.00%

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GmUuswDi3BJNN76DyoJHCG
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GmUuswDi3BJNN76DyoJHCG
@jimutt
jimutt merged commit 046ba19 into main Nov 2, 2026
7 checks passed
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.

2 participants