Skip to content

feat(source-control): neutral tool-agnostic convention SSOT via convention_source - #1149

Merged
kyle-sexton merged 3 commits into
mainfrom
feat/1141-convention-ssot
Jul 23, 2026
Merged

feat(source-control): neutral tool-agnostic convention SSOT via convention_source#1149
kyle-sexton merged 3 commits into
mainfrom
feat/1141-convention-ssot

Conversation

@kyle-sexton

Copy link
Copy Markdown
Contributor

Closes #1141

Summary

Author-directed reopen of #913's recorded "no YAML / no path rename" decision — the four reopen grounds (author directive, a real consuming machine hand-syncing three byte-identical regex copies, the ecosystem's prose-only AGENTS.md pointer standard with no machine format, and the plugin-audit recurring-concerns memory contradicting the decline) are recorded in #1141; a comment recording the outcome goes on #913 at merge.

The team-tracked .claude/source-control.md may now declare ## convention_source: a repo-relative flat-scalar YAML file (subject_pattern, pr_title_pattern, optional pr_body_required_sections list or none, optional dialect: defaulting posix-ere) that enforcement (commit-msg hooks, CI) and drafting (any agent) consume as one source. Key contract points, all recorded in the commit-convention seam README:

  • Back-compat absolute: no pointer → today's markdown-H2 behavior, zero action for existing consumers.
  • Everything repo-declared: the path is the consuming repo's call (no hardcoded doc root; no well-known search list in V1 — recorded decision with rationale). The Conventional Commits keyword and the pr-title deferral marker work identically on both surfaces.
  • Per-key precedence: the neutral file is authoritative for keys it carries; omitted keys fall back to the markdown H2; plugin-only keys (trailer_policy, pr_body_attribution) stay .claude/-side; user/local overlay layers unchanged.
  • Enforcement contract unchanged: POSIX ERE only, unresolved = no enforcement, team-only policy floor — including the pointer itself (an overlay cannot redirect the gate). A declared-but-broken pointer (absolute/backslash/.. path, missing file) or a non-posix-ere dialect fails closed with a diagnostic, never a silent markdown fallback that could enforce a migration-retired pattern.
  • Incumbent steelman documented: markdown-H2's doubles-as-documentation purposes tested against the move (YAML # comments + prose pointer doc); frontmatter-hybrid re-examined and declined for V1 with rationale.
  • setup apply gains the offer-and-migrate path: repo-chosen path, YAML write, pointer declaration, and retiring duplicated markdown keys so both surfaces are never authoritative for the same key. Monorepo per-directory scoping: out of scope V1, recorded.

lib/resolve-convention-pattern.sh extended; the guardrails vendored copy synced byte-identical via scripts/sync-resolve-convention-pattern.sh (gate: resolve-convention-pattern-sync), with guardrails 0.12.3 → 0.13.0 + CHANGELOG per the bump gate. source-control 0.22.0 → 0.23.0 + CHANGELOG.

Test plan

  • bash lib/resolve-convention-pattern.test.sh: 44 cases, 0 failed — 14 new neutral-SSOT cases: quoted/double-quoted/unquoted YAML values, CC keyword and deferral marker in YAML, explicit posix-ere dialect, non-ERE dialect → fail closed, missing-file pointer → fail closed with no stale markdown fallback, absolute/traversal pointer rejection, omitted-key markdown fallback, YAML-wins-over-unretired-duplicate, comment/blank inertness, overlay-pointer ignored (team-only floor).
  • scripts/sync-resolve-convention-pattern.sh --check: guardrails copy byte-identical.
  • skill-quality:check on setup: PASS, 0 errors.
  • jq -e validates both manifests and the evals file; new setup eval 18 covers the apply migration path.

Related

🤖 Generated with Claude Code

…ntion_source (0.23.0)

Author-directed reopen of #913's "no YAML / no path rename" decision
(four grounds recorded in #1141: author directive, a real consuming
machine hand-syncing three byte-identical regex copies, the ecosystem's
prose-only AGENTS.md pointer standard with no machine format, and the
audit checklist's recurring-concerns memory contradicting the decline).

The team-tracked .claude/source-control.md may declare
## convention_source: a repo-relative flat-scalar YAML file
(subject_pattern, pr_title_pattern, optional pr_body_required_sections
list or none, optional dialect: defaulting posix-ere) consumed by
enforcement and drafting as one source. Absent pointer = today's
behavior, zero action for existing consumers. Path always repo-declared
(no hardcoded doc root; no well-known search list in V1 — recorded).
CC keyword + pr-title deferral marker identical on both surfaces.
Neutral file authoritative per key, markdown-H2 fallback; plugin-only
keys stay .claude/-side; user/local overlays unchanged. Enforcement
contract unchanged: POSIX ERE only, unresolved = no enforcement,
team-only policy floor incl. the pointer itself; broken pointer
(absolute/backslash/.. path, missing file) or non-posix-ere dialect
fails closed with a diagnostic, never a silent markdown fallback.

lib/resolve-convention-pattern.sh extended; guardrails vendored copy
synced byte-identical (guardrails 0.13.0 + CHANGELOG); 14 new resolver
test cases (44 total, all pass). Incumbent markdown-H2 steelman and
format decision walk-through recorded in the commit-convention seam
README. setup apply gains the offer-and-migrate path that retires
duplicated keys (spoke section + Gotcha + eval 18). Monorepo
per-directory scoping out of scope V1, recorded.

Closes #1141

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 1s —— View job


I'll analyze this and get back to you.

@claude

claude Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 0s —— View job


I'll analyze this and get back to you.

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown

Warning

Automated review did not complete — this is an infrastructure failure, not a review verdict.

Treat any Claude comment on this PR (including a placeholder like "I'll analyze this and get back to you") as incomplete, not "no findings."

Re-running the job, or pushing a new commit, will retry the review.

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown

Warning

Automated security review did not complete — this is an infrastructure failure, not a review verdict.

Treat any Claude comment on this PR (including a placeholder like "I'll analyze this and get back to you") as incomplete, not "no findings."

Re-running the job, or pushing a new commit, will retry the review.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 42b8cec308

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread lib/resolve-convention-pattern.sh
…pointer

The lexical path checks (absolute, backslash, ..) did not stop a
repo-relative pointer naming a symlink — or sitting under a symlinked
directory — whose physical target is outside the repository, letting
untracked external content steer or disable the gate. The resolver now
requires a REGULAR file whose physical directory (pwd -P, canonicalizing
every symlinked segment) stays under the physical repo root; pure bash,
no realpath dependency for the vendored hook copy. Codex review finding
on PR #1149, classified VALID. Guardrails copy re-synced; symlink test
cases added (auto-skip on filesystems where ln -s cannot symlink).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 1s —— View job


I'll analyze this and get back to you.

@claude

claude Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 1s —— View job


I'll analyze this and get back to you.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6e94c21510

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugins/source-control/skills/setup/reference/apply-convention.md
Comment thread lib/resolve-convention-pattern.sh
…ages neutral file with pointer

Two Codex findings on PR #1149, both classified VALID:

- A neutral file carrying `subject_pattern:` with an empty value was
  treated as an omitted key and silently fell back to the stale markdown
  H2 — the opposite of the carried-key-is-authoritative contract. A
  present-but-empty machine key now fails closed with a diagnostic
  (delete the line to opt into markdown fallback); checked at top level
  so the exit propagates, both keys checked for pr_title_pattern since
  the deferral marker re-reads subject_pattern.
- The setup spoke's team-write verification staged only
  .claude/source-control.md, so a fresh neutral file could be left
  untracked — a committed pointer without its target hands every fresh
  checkout the missing-file fail-closed path. The SSOT section now
  requires staging the neutral file by explicit path in the same
  verification, with an ignore-rule match on it treated as a hard STOP.

Guardrails copy re-synced; two empty-key test cases added (46 total).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 1s —— View job


I'll analyze this and get back to you.

@claude

claude Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error after 1s —— View job


I'll analyze this and get back to you.

@kyle-sexton

Copy link
Copy Markdown
Contributor Author

Pre-merge CI classification

  • 25/25 checks green on head c6f302e, including resolve-convention-pattern-sync (47 resolver test cases; symlink cases exercised on ubuntu) and the guardrails bump gate.
  • claude-review / claude-security-review: known instant infra failure (ci: claude-review + claude-security-review workflows infra-fail instantly (0-1s, cost 0) on every attempt #1122, 0–1s, rerun-proof) — fail-open by workflow design; not a review verdict.
  • Codex review: three findings across two rounds, all classified VALID and fixed — P2 symlink escape on the pointer (6e94c21), P2 present-but-empty carried key silently falling back to stale markdown (c6f302e), P1 setup staging the pointer without its neutral-file target (c6f302e). All threads replied and resolved; final sweep: zero unresolved.

Merging per the drive-to-merged directive on record for this issue chain (#1138#1141).

@kyle-sexton
kyle-sexton merged commit a3d02ba into main Jul 23, 2026
25 checks passed
@kyle-sexton
kyle-sexton deleted the feat/1141-convention-ssot branch July 23, 2026 15:42
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.

source-control: neutral tool-agnostic convention SSOT — author-directed reopen of #913

1 participant