Skip to content

style: remove every em dash outside the frozen artifacts - #230

Merged
imran-siddique merged 2 commits into
mainfrom
style/no-dashes-spec
Aug 27, 2026
Merged

style: remove every em dash outside the frozen artifacts#230
imran-siddique merged 2 commits into
mainfrom
style/no-dashes-spec

Conversation

@imran-siddique

Copy link
Copy Markdown
Member

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:

  1. c9923c2 — 407 lines across 69 files, everything except spec/ and examples/
  2. 667e248 — 83 lines across the two current specifications

The 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-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 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:

-  This chain proves the key was generated inside the attested enclave — not by an operator process.
+  This chain proves the key was generated inside the attested enclave, not by an operator process.

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 in agentrust-trace-tests, with test_generators_reproduce_fixtures pinning 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.md 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. The checker's exemption list names this file individually rather than the whole spec/ tree.

Nothing normative moves

Punctuation only. No requirement keyword, field name, claim, error code or conformance statement changes. test_requirement_keywords_are_attributable and test_vector_completeness both 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_range and two generator fixture comparisons, all path-separator or line-ending issues). No new failures.

🤖 Generated with Claude Code

https://claude.ai/code/session_014NL8o3PXq6kfs2SdmBv6ak

imran-siddique and others added 2 commits August 27, 2026 09:57
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
imran-siddique requested a review from a team as a code owner August 27, 2026 16:59
@imran-siddique
imran-siddique merged commit 60610c5 into main Aug 27, 2026
6 checks passed
@imran-siddique
imran-siddique deleted the style/no-dashes-spec branch August 27, 2026 17:04
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.
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