import io
def edit(p, pairs):
    s=io.open(p,encoding='utf-8',newline='').read()
    nl='\r\n' if '\r\n' in s else '\n'
    for old,new in pairs:
        old=old.replace('\n',nl); new=new.replace('\n',nl)
        assert s.count(old)==1,(p,s.count(old),old[:80]); s=s.replace(old,new)
    io.open(p,'w',encoding='utf-8',newline='').write(s)
edit('docs/TRACEABILITY.md',[
('''Run advisory in CI (or periodically). Presence = hard gate; quality = audited.
''','''Run advisory in CI (or periodically). Presence = hard gate; quality = audited.

   **The `lint` findings are population-wide. Never route them to a lane (IR-146).**
   This registry writes its titles as spec PARAGRAPHS on purpose: the title IS
   the contract a lane builds against and a gate reads verbatim. The linter's
   default criteria assume a short imperative title. Measured by doyle with
   checker 0.4.1 at `6c95d691`: `traceable-reqs lint` emits **1496 `[must]`
   findings over 825 of 949 requirements (87 %)**, broken down as `length` 819
   (titles want 3..=25 words), `contains-and` 674 and `tbd-todo` 3. A lane's
   own new ids carry the same `length` + `contains-and` pair as everyone else's,
   so reading "my two findings" out of that log reports the house style back as
   a defect. CI runs it as `./traceable-reqs lint || true`, and a gater does not
   carry its findings forward as lane work. That mistake was made once, at the
   #331 H3 gate, and withdrawn the same day. Changing what the audit measures
   (retuned criteria, or a short-title/long-body schema split) is a separate
   ruling. Until one lands, this paragraph is the calibration, and any count
   near 87 % means "unchanged", not "worse".
'''),
])
edit('docs/INFRA-REGISTER.md',[
('''### IR-146 — the traceability Quality audit reports 87 % of the registry, so a lane reading its own two findings mistakes a registry-wide calibration for a lane defect
- **Status:** OPEN (doyle, 2026-09-24).''','''### IR-146 — the traceability Quality audit reports 87 % of the registry, so a lane reading its own two findings mistakes a registry-wide calibration for a lane defect
- **Status:** (c) BUILT (hertz, 2026-09-24, #331 H4; doyle ruled (c) only, (a)/(b) NOT ruled): `docs/TRACEABILITY.md` Enforcement layer 4 now states the population number and the never-route-to-a-lane rule. (a)/(b) remain open as a separate ruling. Filed OPEN (doyle, 2026-09-24).'''),
])
print('ok')
