Ship the P4 STE Structural Check: sentence-length Opt-In - #697
Merged
Conversation
The fleet-map STE evaluation left one hook open: the adoption decision lands in GOVERNANCE.md when the first structural check ships. This is that check. The rule caps a Markdown prose sentence at ASD-STE100's 25-word descriptive limit and ships opt-in like sentence-split, since it counts 1686 over-cap sentences in the corpus at landing, so a default or CI gate would fail whole files nobody is editing. The decision (structural half adopted, controlled dictionary rejected) is recorded in GOVERNANCE.md under Sentence Structure, with the full house-style rules in the comment-and-doc-style skill. OPERATIONS.md's runbook trailed #692: its mirrored prose gate omitted dead-path and its rule counts predated it, fixed here alongside the new rule's inventory entries.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an opt-in sentence-length structural prose check (ASD-STE100 25-word cap) and records the fleet decision to adopt STE structure as house style, while keeping enforcement incremental to avoid breaking the existing corpus.
Changes:
- Add
sentence-lengthrule and constant toscripts/prose_lint.py, with opt-in behavior and exemptions for non-prose Markdown structures. - Add new unit tests covering the sentence-length behavior, exemptions, and opt-in status.
- Record the decision and update runbook and skill docs to reflect the new rule and CI parity (
dead-path).
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| scripts/prose_lint.py | Implements the new sentence-length rule and exposes SENTENCE_WORD_CAP. |
| scripts/test_prose_lint.py | Adds tests validating cap behavior, structure exemptions, and opt-in status. |
| OPERATIONS.md | Updates the CI-mirroring prose-lint invocation list and documents the opt-in rules. |
| GOVERNANCE.md | Records the STE structural house style decision under Documentation Style Conventions. |
| docs/fleet-map.md | Updates the STE evaluation section with the formal decision and roadmap status. |
| .agents/skills/comment-and-doc-style/SKILL.md | Documents sentence-structure house style and the sentence-length check in the skill. |
| .claude-plugin/fleet-skills/skills/comment-and-doc-style/SKILL.md | Mirrors the same skill update in the Claude plugin output. |
| .claude-plugin/fleet-skills/.source-digest | Updates the skill source digest stamp for the regenerated plugin content. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
US English closes a sentence inside the quotes, so blanking the whole span removed the boundary and merged the sentence into its neighbor, inflating the sentence-length count. The terminator now survives outside the blank, pinned by a case that fails on the merged form.
ptr727
added a commit
that referenced
this pull request
Aug 15, 2026
…Python CI Gates (#718) Thirty-one squashes, `56f4d7d..d54862a`. 115 files, +20436/-5298. **Merge with a merge commit, never a squash, and never with `--delete-branch`.** This pull request's head is `develop` itself. ## What lands **Fleet Skills.** The `.agents/skills/` source tree, the generated `.claude-plugin/` distribution, `scripts/build_dist.py` with its `--check` gate, and `scripts/skills_install.py` with its host stamp (#676). Packaged as skills on top of the scaffold: PR review conduct and Copilot instructions upkeep (#677), comment and doc style (#678), resync-a-repo and fleet-conformance-check (#679), the per-language codestyles (#680), git commit conventions and operational vs release workflow (#681), stand up a repo (#683), and repo-worktree (#717). Coverage gaps closed in three passes (#690, #691, #692) plus the P4 sentence-length opt-in (#697). **Host setup.** The Windows host-setup tooling and its PowerShell gate (#674), the Windows bootstrap loader (#682), Docker install and upgrade on Linux and Windows with a version floor (#701, #705), a `uv` floor in `spec/host-tools.json` (#698), self-healing of a shadowing `uv`, `jq`, or `git-restore-mtime` copy (#689), node's real winget package id (#696), and a README for the Linux host-setup nuances (#710). **Python and CI.** Python tooling in CI with the script tests moved to `scripts/tests` (#704), `ruff format` adopted and gated (#709), and the PSScriptAnalyzer claim conditioned on repos that carry `.ps1` files (#686). **Conduct rules.** Triage-order and scope guardrails in pr-review-conduct (#684), `pr_review.py wait` requesting a review rather than only polling for one (#685), a tech-agnostic signed-commit verification (#708), execution rather than analogy to verify platform-specific code (#715), and a unique worktree for every task (#717). **Docs.** The fleet map and gap register with peer messaging declared (#687), mermaid flow diagrams in the kept-authority docs (#702), and the map pointed at the shipped diagrams and current tooling (#703). ## Issues this promotion closes Each landed on `develop` on its own pull request. The keyword fires only on a merge into `main`, so it sits here rather than on the feature pull requests. Closes #700 Closes #707 Closes #711 Closes #712 Closes #714 Closes #688 #699 stays open on purpose: #717 shipped the layout convention and the skill, and the physical migration of existing checkouts is still tracked there. ## Review record Every squash closed its own Copilot loop on its own pull request before merging to `develop`. This promotion carries no new content of its own, so its review is the merged tree as a whole. ## Consequence worth stating The `GOVERNANCE.md` and `AGENTS.md` sections these squashes changed become the canonical the moment this reaches `main`, and every carrying repository reads as drifted from that point until it resyncs. That is the ordinary consequence of a canonical moving rather than a defect. The Skills installer added here is also how a machine picks the new skills up, so a session that keeps restating a rule already packaged as a skill is the signal to run it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes out the actionable half of the fleet-map P4 roadmap item on STE structural checks.
What
sentence-lengthrule inscripts/prose_lint.py: flags a Markdown prose sentence over 25 words, ASD-STE100's descriptive cap. Opt-in likesentence-split(not inDEFAULT_RULES, not in CI), because the rule counts 1686 over-cap sentences in the corpus at landing, so a default gate would fail whole files nobody is editing. A table row, a heading, a link definition, and a blockquote are exempt, an inline code span and a double-quoted quotation each count as one word. Eight new cases inscripts/test_prose_lint.py, including one pinning the opt-in status.Sentence Structuresubsection in GOVERNANCE.mdDocumentation Style Conventions, the full house-style rules in thecomment-and-doc-styleskill (plugin regenerated), and aDecisionparagraph plus P4 row edit indocs/fleet-map.mdper the maintenance rule.--check dead-pathafter Close the P3 Audit-Depth Gaps: G4 G5 G7 #692 added it to CI, and its rule counts predated the rule. Both now match CI, and the opt-in note names both unlinted rules.Why opt-in
The corpus measures 26 percent of sentences over 20 words and 1686 over the 25-word cap, so the house style is adopted for new prose while the check stays reachable by name and by
--diffscoping. Promotion intoDEFAULT_RULESor CI is a separate decision, taken if and when the corpus converges. The changed lines of this PR lint clean under the new rule.Verification
python3 scripts/test_prose_lint.py(243 tests),test_repo_gate.py,test_pr_review.py,test_build_dist.py,spec/audit.py --selftest,gh-write-guard.py --selftest: all passrepo_gate.py,build_dist.py --check, the CI prose gate includingdead-path,charset-unknownsummary (0 findings),spec/validate.py,jqsweep,markdownlint-cli2on the changed files: all cleanruffat latest adds no new finding over develop's pre-existing nine,mypypassesGenerated with Claude Code