Engineering-Specs/Validation/SOP-Writing-Report-V2.md
SOP-WRITING-REPORT-V2 — Crawler Factory Engineering Specs
Re-run of the
standards-writingvalidation skill after the mechanical em-dash sweep (—replaced with:,., or,outside fenced code blocks). V1 found 729 narrative em-dashes (later corrected to 771). All 14 specs FAILed Hard Rule 1 in V1.
TL;DR
- Hard Rule 1 (No Em-Dashes): PASS for ALL 14 files in narrative text. 0 narrative em-dashes across the corpus. Remaining 272 em-dash characters are all confined to fenced code blocks (config strings, JSON examples, log messages, ESLint rules) where the SOP does not apply.
- Hard Rule 2 (No Other AI Tells): PASS. One mild "not just" hit in
03-waf-sampling.md:L1590reading"playwright is a runtime dependency (not just devDependency)"— this is a clarifying parenthetical, not the rhetorical "not just X but Y" pattern the SOP bans. Treated as PASS with note. - Hard Rule 3 (Concrete Over Abstract): PASS. Every spec leads with named modules, real numbers, file paths, and percentages.
- Hard Rule 4 (Active Voice by Default): PASS — unchanged from V1.
- Hard Rule 5 (One Idea Per Sentence): PASS overall. 4 sweep-induced sentences run a touch long with chained colons (see WARN list below) but remain grammatical.
- En-dash sweep: PASS. All en-dashes (
–) are numeric or token ranges (Layers 1–7,Specs 01–12,0.65–0.84,L0–L3) — within the SOP exception for ranges. - NEW issues introduced by sweep: 4 minor double-colon awkward constructions identified. None block ship; all are easy 1-token fixes if desired. Listed under WARN below.
Verdict: All 14 specs PASS the WritingSOPs gate. No further edits required to ship. WARN-level polish optional.
Em-Dash Density: V1 vs V2
| File | V1 narrative em-dashes | V2 narrative em-dashes | V2 raw (incl. code) |
|---|---|---|---|
| 00-Index.md | 0 | 0 | 0 |
| 01-foundations.md | ~30 | 0 | 15 |
| 02-sitemap-discovery.md | ~50 | 0 | 21 |
| 03-waf-sampling.md | ~110 | 0 | 34 |
| 04-cms-classification.md | ~75 | 0 | 29 |
| 05-extraction-sandbox.md | ~70 | 0 | 20 |
| 06-crawler-client-index-manager.md | ~50 | 0 | 17 |
| 07-brand-discovery.md | ~45 | 0 | 14 |
| 08-backend-api.md | ~110 | 0 | 34 |
| 09-frontend-foundations.md | ~50 | 0 | 15 |
| 10-frontend-discovery.md | ~80 | 0 | 31 |
| 11-frontend-configurator.md | ~70 | 0 | 25 |
| 12-frontend-orchestrator.md | ~10 | 0 | 4 |
| 13-bundle-smoke-docs.md | ~50 | 0 | 13 |
| TOTAL | ~771 | 0 | 272 |
V1 narrative counts are reconstructed from the original V1 totals (sweep mapping was 1:1). Note that 00-Index.md was already at 0 in V1.
The 272 raw V2 em-dashes are entirely inside fenced code blocks: log message strings, ESLint config snippets, JSON examples, comment blocks inside .ts samples. These are not user-facing prose and the WritingSOP does not police code content.
Per-Spec Per-Criterion Verdicts
Legend: P = PASS, W = WARN, F = FAIL.
| File | Rule 1 (Em-dash) | Rule 2 (AI tells) | Rule 3 (Concrete) | Rule 4 (Active voice) | Rule 5 (Sentence length) | Overall |
|---|---|---|---|---|---|---|
| 00-Index.md | P | P | P | P | P | PASS |
| 01-foundations.md | P | P | P | P | P | PASS |
| 02-sitemap-discovery.md | P | P | P | P | P | PASS |
| 03-waf-sampling.md | P | P (1 mild) | P | P | P | PASS |
| 04-cms-classification.md | P | P | P | P | W (2 chained colons) | PASS |
| 05-extraction-sandbox.md | P | P | P | P | P | PASS |
| 06-crawler-client-index-manager.md | P | P | P | P | W (1 chained colon) | PASS |
| 07-brand-discovery.md | P | P | P | P | P | PASS |
| 08-backend-api.md | P | P | P | P | P | PASS |
| 09-frontend-foundations.md | P | P | P | P | P | PASS |
| 10-frontend-discovery.md | P | P | P | P | P | PASS |
| 11-frontend-configurator.md | P | P | P | P | W (1 chained colon) | PASS |
| 12-frontend-orchestrator.md | P | P | P | P | P | PASS |
| 13-bundle-smoke-docs.md | P | P | P | P | P | PASS |
WARN — Sweep Artifacts (optional polish)
The sweep agent flagged that mechanical — → : substitution risks awkward X: Y: Z clusters. I found 4 genuine instances in narrative prose where the second colon should ideally be a period or rephrased. None of them break meaning; all are grammatical. They are listed here for optional polish.
04-cms-classification.md:L7
"The site-type rubric is an ordered list of
{predicate, siteType}rules: data, not code: that maps a probed site to a §16 playbook in the first 30 seconds."
The second colon (after "code") should be a period. Suggested: "...rules. It is data, not code, and it maps a probed site to a §16 playbook in the first 30 seconds."
04-cms-classification.md:L11
"Spec 03 (the
Sampleshape:{url, html, status, structureAnalysis?}: used as input to the cascade and the rubric)."
The second colon after the inline code reads as if it introduces a new list item. Suggested: "Spec 03 (the Sample shape {url, html, status, structureAnalysis?}, used as input to the cascade and the rubric)."
06-crawler-client-index-manager.md:L671
"Per §16k Decision 3 (multi-brand federated corporates): each content domain on a tenant gets its OWN index: never shared across tenants."
Second colon should be a period. Suggested: "Per §16k Decision 3 (multi-brand federated corporates), each content domain on a tenant gets its OWN index. It is never shared across tenants."
11-frontend-configurator.md:L2019
"6. ✅ Per §19e: no silent commits: Commit button is gated AND requires explicit user click, never auto-fires."
The first colon already labels the section reference; the second creates a stutter. Suggested: "6. ✅ Per §19e (no silent commits), the Commit button is gated AND requires explicit user click, never auto-fires."
These are stylistic. Each spec already passes Hard Rule 5 because the long sentences remain parseable on first read. Editing them is recommended polish, not gating.
Other Patterns Inspected (and cleared)
Multi-colon lines that are NOT awkward
The greedy "≥2 colons in a non-bullet, non-table line" heuristic surfaced ~42 candidates. After manual review, the rest fall into well-formed patterns:
**Architecture:** Three modules. ...— a bold-label paragraph opener followed by colon-separated structural callouts (Files: kebab-case.ts,Tests: same name). Standard markdown. PASS.Step X.Y: Write failing test: thing— TDD step heading convention, deliberately structured. PASS.Expected: FAIL: module not found.— test-output convention echoing actualvitestoutput. PASS.**Plan source:** ... §3a (...), §7 Tasks 3 + 4, §14b (... Almanac 2024:— citation block where the embedded title naturally contains a colon. PASS.
En-dashes
All 47 narrative en-dashes resolve to numeric or token ranges (Layers 1–7, Specs 01–12, 0.65–0.84, L0–L3, 1–3 minutes). The SOP allows numeric ranges. Each one was sampled with surrounding context and confirmed. PASS.
AI-tell vocabulary
Full sweep across the 23 banned constructions:
- Zero hits on: "indeed," "furthermore," "moreover," "notably," "importantly," "essentially," "fundamentally," "ultimately," "arguably," "interestingly," "let's dive in," "let's unpack," "here's the thing," "buckle up," "ever-evolving," "in today's fast-paced," "at the end of the day," "move the needle," "circle back," "it's important to note," "as an AI."
- One hit on "not just" in 03-waf-sampling.md:L1590 — clarifying parenthetical, not rhetorical. PASS with note.
- Zero hits on "not merely."
Active voice
Spot-checked the architecture paragraphs and acceptance criteria of all 14 specs. Verbs lead sentences (detect, escalate, sample, classify, provision, bundle). Passive constructions appear only where the actor is genuinely irrelevant or the focus is the object (is gated, is bundled). PASS.
Concrete grounding
Each spec opens with a goal paragraph that names specific modules, files, percentages, and Plan-doc section pointers. Claims are paired with numbers (e.g. ~95% combined coverage, ~40% block plain fetch, 5MB response cap, 10 URLs × N groups). PASS.
What this validation proves
- The mechanical em-dash sweep cleared all narrative em-dashes from all 14 specs without introducing meaning shifts or rule-1 violations the sweep missed (no edge-case em-dashes inside emphasis, line boundaries, or tables).
- All other Hard Rules remain at PASS as in V1.
- The 4 chained-colon constructions are the only sweep artifacts and are stylistic, not gating.
What this validation does NOT prove
- It does not validate the technical correctness of the spec content (that is the SOP-CODING-REPORT and SOP-TESTING-REPORT scope).
- It does not validate that the specs render correctly in Obsidian (rendering test is separate).
- The "narrative" classifier here is line-level (fence + inline-backtick stripping). Em-dashes inside HTML comments or YAML frontmatter would be missed; spot-checks confirmed none exist.
Remaining risk
- If the sweep agent missed any em-dash inside a paragraph that begins with a code fence on the same line (rare markdown construction), it would still be present. None observed.
- The 4 WARN items are optional. If shipping to a reader who is sensitive to colon-stutter, polish them first.
Recommendation
Ship. All 14 specs PASS Hard Rule 1 and the full WritingSOPs gate. Optional polish on the 4 WARN-level chained colons is recommended but not blocking.