style: remove every em dash outside the frozen artifacts - #230
Merged
Conversation
House style is no em dashes in anything we publish. The repository carried 601 of them across 73 files, because prose review does not catch a dash in a workflow comment, a table cell, a docstring or a changelog heading. 407 lines rewritten across 69 files. The dominant shape here is label-then-definition, where a colon is the right mark, so that is the default. Three cases needed something else: Keep a Changelog version headings take a hyphen. A colon would be worse than wrong: `## [0.9.0]: 2026-08-09` is markdown's link-reference-definition syntax, so the line stops rendering as a heading at all. Paired dashes bracketing a clause take commas. Two colons in one sentence is not grammatical. A dash followed by a continuation word (and, but, not, which, so) takes a comma, because what follows is not a definition. 22 of those were found by scanning the diff for exactly that shape and fixed by hand, which is the pass a blanket rule cannot do. En dashes in ranges are written out: "3 to 9 members", "50 to 200 ms". Two trees are exempt, for different reasons, and both exemptions should shrink. examples/ holds conformance vectors and the generators that emit them. These are published data that third-party implementations score against, shipped in agentrust-trace-tests, and test_generators_reproduce_fixtures pins each generator to its committed output. The sweep initially rewrote a description string inside four canonicalization vectors and broke that test, which is the right outcome: changing a vector is a release-affecting change with its own review discipline, not a style edit. Reverted and excluded. spec/ is normative text, held back so its prose changes get read on their own rather than inside a 400-line diff. tools/check_dashes.py holds the line, wired into CI after the lint step. It builds its offender table from code points rather than literals, because a checker containing the characters it bans reports itself, and the fix somebody reaches for at that point is an exemption for the checker. Three tests fail locally on Windows before and after this change (test_safe_integer_range and two generator fixture comparisons, all line-ending or path-separator issues). No new failures: 802 passed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014NL8o3PXq6kfs2SdmBv6ak
Completes the sweep started in the previous commit, held back so the normative prose changes get read on their own rather than inside a 400-line diff. 83 lines across spec/trace-v0.2.md and spec/server-provenance-v1.md. Same rule: the dominant shape is label-then-definition and a colon is the right mark. No continuation-word cases turned up here, so nothing needed a comma; the spec's dashes are almost entirely table cells, reference lists and defined terms. | Version | 0.2: Draft | - **RATS / EAT (RFC 9711)**: wire envelope and claim model. | `cnf` | Confirmation key: binds record to TEE-held signing key | The wall is not technical capability: it is evidence. spec/trace-v0.1.md is deliberately NOT swept, and the checker's exemption list now names it individually rather than the whole spec/ tree. It carries a "Superseded by TRACE v0.2" banner and appears in the docs nav as "TRACE v0.1 (superseded)". Someone citing v0.1 section 3.2 should find the text as it was; it is a record, not living prose. Same reasoning that keeps the conformance vectors out: a published artifact somebody else may be holding to is not something to edit for style. Punctuation only. No requirement keyword, field name, claim, error code or conformance statement moves, and the tests that check requirement keywords are attributable and that the vector corpus is complete both pass. Three tests fail locally on Windows before and after, as in the previous commit. 802 passed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014NL8o3PXq6kfs2SdmBv6ak
imran-siddique
added a commit
to rajnisht7/trace-spec
that referenced
this pull request
Aug 27, 2026
Conflict was CHANGELOG.md only: this branch and agentrust-io#225 each added a Fixed entry next to the TraceAGTAdapter one. Kept all three. Took main's copy of the shared TraceAGTAdapter line rather than this branch's. The dash sweep in agentrust-io#230 rewrote it there, and the repository now has a CI check banning em dashes, so the branch's copy would fail it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014NL8o3PXq6kfs2SdmBv6ak
imran-siddique
added a commit
to rajnisht7/trace-spec
that referenced
this pull request
Aug 27, 2026
Conflict was CHANGELOG.md only: agentrust-io#225, agentrust-io#227 and this branch each added a Fixed entry next to the TraceAGTAdapter one. Kept all four. Took main's copy of the shared TraceAGTAdapter line, since the dash sweep in agentrust-io#230 rewrote it there and CI now bans em dashes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014NL8o3PXq6kfs2SdmBv6ak
lywinged
added a commit
to lywinged/trace-spec
that referenced
this pull request
Aug 27, 2026
Completes what #6 began and deferred while upstream PRs agentrust-io#225 and agentrust-io#227 were editing those functions. Those landed. agentrust-io#229 closed provenance.tool_catalog_hash; the other three were untouched, because _as_object guards fields inside a record and no guard on a field can reach the record's own type. provenance.verify_record and provenance.check_tool_catalog leaked 11 AttributeErrors of 12 non-object inputs apiece, which is not the ProvenanceError verify_record documents. content_marking.verify_assertion never checked that record_bytes were bytes, and bytes(5) is five zero bytes, so an int was hashed, failed to match, and the caller was told the record at the URL had changed: a specific and false accusation about somebody else's server. Every public entry point in the package now reports zero leaks under the sweep. Thirty-two tests, each shown load-bearing by removing the guard it covers (12, 11 and 10 failures). Also repairs the changelog sentence the agentrust-io#230 em dash sweep broke into "an object that is an array", which check_dashes.py cannot catch because the removal was clean and the sentence is what broke. 1031 passed, 1 skipped. Ruff clean.
lywinged
added a commit
to lywinged/trace-spec
that referenced
this pull request
Aug 27, 2026
…not have (#11) Upstream's agentrust-io#230 removed every em dash outside the frozen artifacts and added tools/check_dashes.py. It reached the files both trees share and could not reach the fifteen this fork carries alone, so the checker reported 142 here on a tree upstream reports clean. The convention was measured from what agentrust-io#230 itself did: ': ' 157 times, ', ' 36, removed 17. Applied as a colon for a single dash, commas for a pair since a colon cannot be paired, a hyphen between digits, and a hyphen for a dash alone in a table cell where it means "none". Reading the result found two faults the rule produced. Nineteen colons landed before a coordinating conjunction and are now commas. Three parentheticals contain commas of their own, so wrapping them in commas merged them into the surrounding list; those take parentheses. 1033 passed, 1 skipped. Ruff unchanged at 13 lines, none added or removed. check_canonicalizer.py and mutation_report.py still exit 0, which matters because six of the fifteen files are those scripts.
9 tasks
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.
House style is no em dashes in what we publish. This repository carried 601 across 73 files.
Two commits, so the normative prose can be reviewed on its own:
c9923c2— 407 lines across 69 files, everything exceptspec/andexamples/667e248— 83 lines across the two current specificationsThe rule, and the three places it does not apply
The dominant shape here is label-then-definition, where a colon is the right mark. Three cases needed something else, and each is why a blanket find-and-replace would have been wrong:
Keep a Changelog headings take a hyphen. A colon is worse than wrong:
## [0.9.0]: 2026-08-09is markdown's link-reference-definition syntax, so the line stops rendering as a heading at all.Paired dashes bracketing a clause take commas. Two colons in one sentence is not grammatical.
A dash followed by a continuation word takes a comma.
— and,— not,— which,— so: what follows is not a definition. I found these by scanning the diff for exactly that shape and fixed 22 by hand. That is the pass a rule cannot do:En dashes in ranges are written out: "3 to 9 members", "50 to 200 ms".
Two things deliberately left alone
examples/holds conformance vectors and the generators that emit them. Published data that third-party implementations score against, shipped inagentrust-trace-tests, withtest_generators_reproduce_fixturespinning each generator to its committed output.The sweep initially rewrote a description string inside four canonicalization vectors and broke that test. That is the right outcome and the reason for the exclusion: changing a vector is a release-affecting change with its own review discipline, not a style edit. Reverted.
spec/trace-v0.1.mdcarries a "Superseded by TRACE v0.2" banner and appears in the docs nav as "TRACE v0.1 (superseded)". Someone citing v0.1 section 3.2 should find the text as it was. It is a record, not living prose. The checker's exemption list names this file individually rather than the wholespec/tree.Nothing normative moves
Punctuation only. No requirement keyword, field name, claim, error code or conformance statement changes.
test_requirement_keywords_are_attributableandtest_vector_completenessboth pass.The guard
tools/check_dashes.py, wired into CI after the lint step. It builds its offender table from code points rather than literals, because a checker containing the characters it bans reports itself, and the fix somebody reaches for at that point is an exemption for the checker.Verified both ways: passes clean, and fails on a planted dash.
Tests
802 passed. Three fail locally on Windows before and after this change (
test_safe_integer_rangeand two generator fixture comparisons, all path-separator or line-ending issues). No new failures.🤖 Generated with Claude Code
https://claude.ai/code/session_014NL8o3PXq6kfs2SdmBv6ak