Skip to content

Follow-up: resolve the Codex cross-family findings on PR-3 and PR-4 - #64

Merged
seathatflowsinourveins merged 5 commits into
mainfrom
claude/grand-catalog-codexfix
Sep 22, 2026
Merged

seathatflowsinourveins merged 5 commits into
mainfrom
claude/grand-catalog-codexfix

Conversation

@seathatflowsinourveins

@seathatflowsinourveins seathatflowsinourveins commented Sep 22, 2026 •

Copy link
Copy Markdown
Collaborator

Scope

PR-3 (#62) and PR-4 (#63) were merged before their bounded Codex cross-family passes returned; this PR lands every finding those passes raised, each with a regression test (two isolated builders, each Opus-reviewed with one fix round; workflow wf_76e829b6-778).

PR-4 findings (trading runtime)

  • promotion_gate.py: empty snapshots no longer pass (rows_present); volume is validated on the raw column before any coercion (volume_integral_non_negative), so -0.5 can no longer truncate to 0; two new fixtures.
  • runner.py paper preflight validates the full gate-result contract (required keys, every check passed, row_count > 0, snapshot is a regular .csv/.parquet file whose hash matches) with distinct SafetyError kinds.
  • metrics.py confines every readable path to the resolved ledger directory (symlink escapes refused before any read; canary test now passes a real outside path) and builds the read-only SQLite URI with urllib.parse.quote, refusing ?/# in paths; the review's follow-up (immutable=1 against a live WAL ledger) fixed with a test.

PR-3 findings (automation and bootstrap)

  • .gitleaks.toml: the global 40/64-hex allowlists (shown to suppress api_key = "<hex>") are replaced by path- and key-scoped line allowlists derived from the classified baseline; the pagination-cursor allowlist is scoped to the one receipt with regexTarget = secret; tests/test_gitleaks_config.py proves hex secrets outside allowlisted contexts and a PAT beside a cursor are still detected.
  • adoption/bootstrap-linux.sh fails closed (exit 3) when a selected component has no pin unless --allow-unpinned names it; the prerequisite check now follows the apt block (exit 4 with --skip-system-packages).
  • render_config.py --check compares bytes (CRLF vs LF test).
  • docs/github-automation.md and automation.json contradictions resolved (adoption-bootstrap exists; secret-scan is required, not report-only; ruleset membership; freshness coverage claim).

Evidence (local integration; guarded gitleaks launcher; no broker)

validate.py, validate_catalogs.py, validate_foundation.py, landscape.py, build_verdicts.py --check, trading_gates.py --check, build_ecosystem.py --check all pass; zizmor and shellcheck clean; gitleaks dir . and gitleaks git . --log-opts=origin/main..HEAD with the config: 0 findings; python3 -m unittest 1,372 OK (204 environment skips). Known boundary: a default-log-opts scan of the shared clone still reports one finding from another session's unmerged PR-5 branch fixture, relayed to its owner. Cross-family review of this PR: codex_absent — one bounded codex exec attempt failed at turn start with the account usage limit (retry available 2026-09-28 20:06 ET; no credits purchased). Independent review is therefore the two Opus evidence-reviewer passes inside the fix workflow only.

🤖 Generated with Claude Code

promotion_gate.py: add a rows_present check so an empty snapshot with all
required columns fails closed instead of returning status=pass, row_count=0.
Validate volume on the raw pre-coercion column (volume_integral_non_negative)
so a value like -0.5 cannot be silently truncated to 0 by astype('int64')
before the old check ran.

runner.py validate_preflight (paper mode): validate the full gate-result
contract (required keys, every check passing, row_count > 0, snapshot is a
regular file with an accepted extension whose sha256 matches) instead of
only status/input_sha256, adding promotion_gate_incomplete,
promotion_gate_failed_check and promotion_gate_empty SafetyError kinds.

metrics.py: confine every readable path (--ledger, --trial-json) to the
resolved ledger directory via Path.resolve(strict=True) plus a containment
check, refusing an outside path or an escaping symlink before any read.
Build the read-only SQLite URI from urllib.parse.quote instead of string
concatenation and refuse ledger paths containing ?/# outright, closing a
mode=ro override via a crafted filename.

Each finding has a regression test verified to fail against the pre-fix
source and pass after. Fixtures regenerated through the gate's own isolated
venv; manifests/evidence.json updated for the new fixture files and
rehashed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…dger

_sqlite_ro_uri appended immutable=1 to the read-only ledger URI. The
ledger safety.Ledger opens is a live WAL database held open and
written to for the whole duration of a trial; SQLite's immutable hint
asserts the file's content/schema never change for the connection's
lifetime, which is false against an active trial. Empirically this
produced not mere staleness but an outright
sqlite3.OperationalError: no such table: meta on every scrape taken
while a trial was running (the immutable connection never reads the
WAL-resident schema).

Removed immutable=1, keeping mode=ro (still strictly read-only: any
write attempt raises OperationalError, unchanged). Added a regression
test that keeps a real safety.Ledger connection open (never closed)
for the whole test, freezes it to produce a fresh WAL-only write, and
asserts render_metrics both succeeds and observes that freshly
committed state; verified it fails with the prior immutable=1 URI
(the exact OperationalError above) and passes after this fix. Updated
the now-stale "read-only and treats as immutable" docstring and the
existing URI-shape test. Rehashed the two changed files in
manifests/evidence.json via the catalog's rehash_evidence.py; no new
files added.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Fixes five findings from the Codex cross-family review of PR-3, each with a
regression test, on top of claude/grand-catalog-pr3:

1. .gitleaks.toml (major): the global regexTarget="secret" 40/64-hex allowlist
   suppressed any hex-shaped secret repo-wide. Replaced with five allowlists,
   each RULE-scoped (under generic-api-key / sourcegraph-access-token) and
   path-restricted to the exact 25-27 evidence/blueprint/catalog files the
   2026-09-22 baseline scan (257 findings, default rules, .gitleaks.toml moved
   aside) actually produced: named sha256/commit/pin fields, filename-shaped
   manifest keys, prose commit/tree ids in two review files, the Alpaca
   next_page_token cursor's own base64-padding shape, and sha256sum-style
   corpus_files lines. A top-level [[allowlists]] with `paths` was measured to
   skip the whole file regardless of any `regexes`, on the installed gitleaks
   8.30.1 binary; only rule-scoped [[rules.allowlists]] applies path+regex as
   a true per-line AND. Full-history scan restricted to this branch's own
   375-commit ancestry: 0 findings; gitleaks dir .: 0 findings.

2. .gitleaks.toml (major): next_page_token allowlist scoped to the exact
   receipt path and the cursor's own base64-with-padding shape
   (regexTarget = "secret"), so a credential on the same line is still caught.

3. adoption/bootstrap-linux.sh (major): a selected component with no pin now
   fails closed (exit 3) before installing anything, listing every gap, unless
   --allow-unpinned <id,...> explicitly names and logs them.

4. adoption/bootstrap-linux.sh (minor): the apt-managed prerequisite install
   now runs before the curl/git/tar/jq presence check; --skip-system-packages
   makes that check list what's missing and exit 4.

5. tools/adoption/render_config.py (minor): --check now compares raw bytes,
   not Path.read_text()'s universal-newline-normalised text, so a CRLF live
   file is never wrongly reported byte-identical to an LF-rendered template.

6. docs/github-automation.md + catalogs/foundation/automation.json (minor):
   reconciled adoption-bootstrap's built/not-built status, secret-scan's
   already-fails-on-detection behavior vs sbom-vuln's true report-only
   design, the committed-vs-active main-ruleset framing, and the
   catalog-freshness fixed-tool table's actual (grype-excluded) coverage.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- docs/github-automation.md: stop duplicating .gitleaks.toml's dated
  full-history scan counts, which had gone stale and contradicted the
  updated config header (pre-fix "251 matches"/"zero findings" claim vs
  the post-fix 257-finding baseline and the non-zero all-refs result).
  The doc now points to .gitleaks.toml as the single canonical source
  and states the branch-ancestry vs all-refs distinction accurately.
- .gitleaks.toml: re-measured and corrected the header comment. The
  acceptance command as literally specified (default log-opts, all
  refs) does not reach 0 findings because a concurrently active sibling
  branch (PR-5) carries an unrelated synthetic-fixture leak
  (tests/test_lane_packets.py @ 34fc51b, confirmed not an ancestor of
  this branch and not an owned path); flagged as a coordinator decision
  for the sibling branch, not fixable from this unit. Documented that
  `--exit-code 0` always returns process exit 0 regardless of findings,
  which explains the previously mis-recorded exit code 1.
- tests/test_gitleaks_config.py: added regression coverage -
  test_exit_code_zero_flag_always_returns_zero_even_with_findings pins
  the --exit-code 0 semantics against the installed binary;
  GitleaksBranchAncestryHistoryTests scans this branch's real ancestry
  (--log-opts=HEAD) and asserts 0 findings, the acceptance-relevant
  result this unit owns; GithubAutomationDocConsistencyTests asserts
  the doc no longer restates .gitleaks.toml's owned counts or an
  unqualified zero-findings claim.
- manifests/evidence.json: rehashed via the ecosystem tool after the
  above edits.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@seathatflowsinourveins
seathatflowsinourveins merged commit d093a4c into main Sep 22, 2026
6 checks passed
seathatflowsinourveins added a commit that referenced this pull request Sep 22, 2026
…hosted smoke) (#65)

New-machine install path for the two grand catalogs: WSL2 x86_64 (accepted) and macOS arm64 (drafted; now executed on a GitHub-hosted Apple-Silicon runner, with a receipt).

| Unit | What | Evidence class |
| --- | --- | --- |
| Docs | Step 0 (clone, then check out `source.baseline_commit`), "Fresh WSL2 in six steps" and "Fresh macOS arm64" blocks in README and `adoption/bootstrap.md`; both scripts' flags and exit codes 0-4 documented | source_review / structural |
| macOS bootstrap | `adoption/bootstrap-macos.sh` mirrors `bootstrap-linux.sh`, including PR #64's fail-closed rule (exit 3 for a selected component without a pin unless `--allow-unpinned`; exit 4 for missing prerequisites with `--skip-system-packages`), plus a `--plan` no-network mode. One disclosed divergence: `socraticode` is a documented unpinned skip. `adoption/pins-macos-arm64.json` carries publisher checksums (nodejs SHASUMS256, uv/ai-memory sidecars, gh checksums.txt, GitHub release-asset digests with a local re-hash for llama.cpp and qdrant, npm integrity cross-check). 43 tests with `uname`/`sw_vers` shims | pins: independent observation of publisher checksums; script: local_integration on Linux plus the hosted run below |
| Hosted macOS job | `bootstrap-macos` on `macos-15` runs the bootstrap into `$RUNNER_TEMP`, asserts every profile command present and `platform.supported=false`, uploads status, installed versions and `sw_vers` | native operation on a GitHub-hosted macOS arm64 runner: green on run 35753801691 (macOS 15.7.9 build 24G830, Python 3.13.15; all nine pinned components observed at their pinned versions). Receipt `evidence/receipts/adoption-macos-hosted-smoke-20260922.json`. Not acceptance on a user's Mac |
| Portable guarded runners | `ecosystem-bounded-run` and `gitleaks-guarded` under `adoption/tools/` (byte-faithful to the host originals except parameterised paths, provenance sha256 recorded), README, 12 tests that prove containment from inside the job (cgroup leaf, unit state, kernel `memory.max`/`pids.max`, mutation-checked) | local_integration on one WSL2 host; the refusal branch is exercised only through a forced probe failure |

`platform_profiles[macos-arm64]` keeps `status: drafted_not_accepted` and `evidence_ref: null`; the hosted run is recorded in a separate `hosted_smoke` field (`green_on_hosted_runner`, run id, receipt). `supported_platforms` is unchanged. Not touched: the Linux job, `adoption/bootstrap-linux.sh`, `docs/github-automation.md`, `.gitleaks.toml` and every PR-5 path.

Gate on the integrated tree (base `d093a4c`): `build_ecosystem.py --check` passed; `validate.py` passed (69 components, 1,754 hashed files, 140 receipts); `validate_catalogs.py`, `validate_foundation.py` and `validate_convergence.py --all-recorded` passed; `python3 -m unittest` 1,428 OK (204 skipped, all optional-runtime gates); shellcheck clean; guarded Gitleaks over `d093a4c..HEAD` with `.gitleaks.toml`: no leaks (the 2 MB target cap excludes the 12 MB explorer HTML; decode depth 0; both recorded as incomplete coverage). Each unit had an independent evidence-reviewer pass (Opus/high) with fix rounds, and the integrated diff had its own review and verify pass. Limits: no workstation acceptance, launchd and the `llama-server` embedding acceptance unrun, npm's darwin optional binaries unpinned, the Homebrew prerequisite path not exercised on the runner.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Sep 22, 2026
…ns, exit plan; SYN) (#69)

* Integrate the reviewed adaptive-paper engine change onto main (SYN)

Rebase of the reviewed engine change from c2019e6 onto main 03f0ad4:
- data feed selection (iex|sip) with a frozen SIP config;
- opt-in strategy rotation (registry validated without executing modules,
  RegimeSelector with operational status from the STOP file, ledger halt,
  transport health and quote freshness);
- session model with opt-in extended hours and overnight holds (NYSE 2026
  calendar, broker-snapshot adoption, held_overnight phase, session-aware
  gross cap, gap-risk evaluation, halted quotes);
- ordered exit plan with vol-scaled stops, partial take-profit and time decay,
  plus opt-in cancel-then-replace and an opt-in gap-risk stop.
Shipped config defaults are byte-identical in behaviour (16-case golden
fixture through both policy classes). PR-4/#64 guards are kept: the paper
promotion gate, hardened credentials() and metrics.py confinement.

Evidence class SYN: no broker-observed receipt for the new behaviour. Gate
rows handed over with adaptive-paper integration now name this lane as owner;
adaptive-paper-broker-trial stays not_established with the measured NTP root
cause of the 2026-09-22 trial in its note.

Checks: engine + PR-4 suites 523 OK (1 skipped); unittest discover 1729 OK
(5 skipped); scripts/validate.py passed; validate_catalogs ok;
trading_gates.py --check passed; guarded gitleaks: no leaks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Rebuild the offline ecosystem explorer for the engine integration

The hosted validate job's build_ecosystem.py --check failed on the stale
generated explorer. Rebuilt with --write and repinned its manifest row; every
step of the validate workflow passes locally.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Scope overnight-hold preflight relaxation to resumed held trials

Rebase review of PR #69 found two defects in the opt-in overnight-hold path:
- D1: with overnight_holds enabled the flat-account/no-open-orders preflight
  gate was relaxed for every paper start, so positions created outside any
  trial could be adopted. The relaxation now requires the prior trial phase to
  be held_overnight (read before preflight, re-checked under the account lock);
  a first trial or any other prior phase still requires a flat account.
- D2: main() re-read the session clock after run_native returned and could
  relabel a needs_attention end as held_overnight; it now reuses run_native's
  own decision (_final_boundary_from_run_status).
Four regression tests; reverting D1 makes the first-trial test fail.

Checks: engine + PR-4 suites 527 OK (1 skipped); python3 -m unittest 1733 OK
(318 skipped); every hosted validate step and trading_gates.py --check pass;
explorer rebuilt; guarded gitleaks: no leaks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Refresh the rebase receipt hashes and correct a stale docstring

Re-review of the PR #69 fix commit found the receipt's rebase block still
recorded pre-fix hashes for runner.py, its tests and source-hashes.json, and
trial_phase_and_exit_code's docstring still described main() re-reading the
session clock. The block's file map now matches source-hashes.json for every
shared path, the docstring describes _final_boundary_from_run_status, and the
explorer is rebuilt.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Harden the held-trial phase read and cover the preflight-lock race

Fix-verification review of c3f8921: a non-object trial.json now keeps the
strict flat gate instead of raising; the locked re-check
trial_state_changed_during_preflight is tested in both directions (removing
it fails both tests); two stale docstrings corrected; receipt and pins
refreshed. Explorer regenerated in the following merge.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: seathatflowsinourveins <234074349+seathatflowsinourveins@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Sep 23, 2026
…YN) (#77)

* Require the promotion-gate result to report every named gate check

Blind Codex review of #64: the paper preflight accepted a gate result with an
unnamed passing check, null versions and null checked_at. It now requires the
checks to name every promotion_gate.CHECK_NAMES entry exactly once, a
non-empty versions object and an ISO-8601 checked_at (else
promotion_gate_incomplete). A test parses promotion_gate.py so the two lists
cannot drift. The real 2026-09-22 gate result and the good fixture still pass.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Harden the gate check per review: string names, aware timestamps, CSV row binding

Review follow-ups on eb2e9c8: a non-string check name is refused cleanly
instead of raising TypeError; checked_at must be a timezone-aware ISO-8601
date-time; version values must be non-empty strings; for a .csv snapshot
row_count must equal the file's data rows; an unmapped_failures entry from the
gate raises promotion_gate_unmapped_failures (peer suggestion). Mutations of
the name-set guard and the row binding each fail their tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Hash and count the snapshot from one read

Second review of the gate check: the CSV row count re-read the snapshot
outside the OSError guard; hash and count now use the same bytes. Receipt
limits name the quoted multi-line CSV false-refusal case.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: seathatflowsinourveins <234074349+seathatflowsinourveins@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@seathatflowsinourveins
seathatflowsinourveins deleted the claude/grand-catalog-codexfix branch September 25, 2026 18:47
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
…tration landscape on the command-center page

The owner asked for the whole ecosystem on one page, so the command center
grows from six sections to nine, still from existing producers only:

- Orchestration: the CC's recorded orchestration-frameworks resolution and
  the same slot in cc-native-practice slots-final.json, the landing queue,
  the co-op's GPT read queue (read-queue-now.json) and the Adoption
  snapshot's orchestration tool calls by role.
- Resolution landscape: each matrix winner's component, pin, evidence class,
  lifecycle stages and platforms, with the W6 final columns (verdict, run
  pin, upstream E2E at the pin, invoke evidence) as recorded or "not
  recorded". Each winner's repository is matched to cc-now.json
  mirrors.pins by the version its tag names or a commit prefix, and a
  winner without a mirror says so. Terminal states come only from
  final-stack.json and read "pending #1008/#1007" until it exists. The
  committed north-star readiness layers follow with the same columns; the
  CC's program, mirrors, rulings and ten-layer plan render as given.
- SOTA skill invoke rates: one row per skill pinned in
  adoption/skills/manifest.json (source@ref, linked only for https, and
  path), joined with the 7-day counts per client from skill_usage.py and
  child-usage.mjs, or from #970's skill-invoke-rate-daily/1 projection when
  it is current. Zero calls flag "wiring defect"; a pinned skill with no
  install record is "not installed" (unknown while /skill-doctor is
  unmeasured); a called skill the manifest does not pin is "unpinned". The
  practice-slot table marks the orchestration-frameworks row. An unmeasured
  value never reads as zero.
- Tokens saved: tools/local-pages/token_tools_now.py runs each token tool's
  own report command (rtk gain, headroom agent-savings and output-savings,
  context-mode doctor) and records its exit code, run time, version and
  own estimate in token-tools-now.json. The page shows each beside its
  command, labels the token-window counters as client counters, and never
  sums across tools, evidence classes or windows.
- Research queue: research-queue.tsv rows and research-state.json's resume
  order.

The #1012 Claude read's fixes are folded in. B1: the email mask moves into
the shared sanitizer and matches after its per-token decoding (CPython
html.unescape and urllib.parse.unquote, cited at v3.13.16), so &commat;, an
encoded dot (%2E or &#46;), %2540 and a semicolon-less &#64 are omitted on
every page; the old page-local mask left all five readable. B2: each
section's label follows what it renders, and every partial section names
its reason. B3: each section and the count strip render in their own guard,
so a scalar codex_top_lanes_M or an integer above 1e308 degrades only its
own section. The receipt lists only the not-wired inputs the page rendered.

source_policy.json gains a command_center role map with sixteen exact repo
and state paths, read through CommandCenterReads, which extends the
Architecture reader (bounded, no-follow, protected names, no user root).
Reports past their limit read "stale" with their age; times recorded as a
time of day stay as recorded.

tools/skill-usage/render_units.py renders reviewed user units that keep the
three skill reports current: hourly, the host report (91 s measured,
including the $0 zero-turn claude -p /skill-doctor, with --claude-timeout
120 because the 30 s default expired once under load) and the Claude lanes
sweep (198 s and a 1.9 GB peak, projected from 181 MB to 26 KB by
systemd/claude-lanes.jq); daily, the Codex lanes report, which had not
finished after 25 minutes, so its completion time is unmeasured. Each step
renames a finished report into place.

The evidence manifest records the new hashes of source_policy.json and the
skill-usage README. Tests cover each section, unknown versus zero,
staleness, hostile types and strings, privacy (eight email forms, decoded
twice) and the exact grants; 33 fail-before mutations of this change each
fail them. The unit tests round-trip each ExecStart through systemd quoting
and pass systemd-analyze verify.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
…tration landscape on the command-center page

The owner asked for the whole ecosystem on one page, so the command center
grows from six sections to nine, still from existing producers only:

- Orchestration: the CC's recorded orchestration-frameworks resolution and
  the same slot in cc-native-practice slots-final.json, the landing queue,
  the co-op's GPT read queue (read-queue-now.json) and the Adoption
  snapshot's orchestration tool calls by role.
- Resolution landscape: each matrix winner's component, pin, evidence class,
  lifecycle stages and platforms, with the W6 final columns (verdict, run
  pin, upstream E2E at the pin, invoke evidence) as recorded or "not
  recorded". Each winner's repository is matched to cc-now.json
  mirrors.pins by the version its tag names or a commit prefix, and a
  winner without a mirror says so. Terminal states come only from
  final-stack.json and read "pending #1008/#1007" until it exists. The
  committed north-star readiness layers follow with the same columns; the
  CC's program, mirrors, rulings and ten-layer plan render as given.
- SOTA skill invoke rates: one row per skill pinned in
  adoption/skills/manifest.json (source@ref, linked only for https, and
  path), joined with the 7-day counts per client from skill_usage.py and
  child-usage.mjs, or from #970's skill-invoke-rate-daily/1 projection when
  it is current. Zero calls flag "wiring defect"; a pinned skill with no
  install record is "not installed" (unknown while /skill-doctor is
  unmeasured); a called skill the manifest does not pin is "unpinned". The
  practice-slot table marks the orchestration-frameworks row. An unmeasured
  value never reads as zero.
- Tokens saved: tools/local-pages/token_tools_now.py runs each token tool's
  own report command (rtk gain, headroom agent-savings and output-savings,
  context-mode doctor) and records its exit code, run time, version and
  own estimate in token-tools-now.json. The page shows each beside its
  command, labels the token-window counters as client counters, and never
  sums across tools, evidence classes or windows.
- Research queue: research-queue.tsv rows and research-state.json's resume
  order.

The #1012 Claude read's fixes are folded in. B1: the email mask moves into
the shared sanitizer and matches after its per-token decoding (CPython
html.unescape and urllib.parse.unquote, cited at v3.13.16), so &commat;, an
encoded dot (%2E or &#46;), %2540 and a semicolon-less &#64 are omitted on
every page; the old page-local mask left all five readable. B2: each
section's label follows what it renders, and every partial section names
its reason. B3: each section and the count strip render in their own guard,
so a scalar codex_top_lanes_M or an integer above 1e308 degrades only its
own section. The receipt lists only the not-wired inputs the page rendered.

source_policy.json gains a command_center role map with sixteen exact repo
and state paths, read through CommandCenterReads, which extends the
Architecture reader (bounded, no-follow, protected names, no user root).
Reports past their limit read "stale" with their age; times recorded as a
time of day stay as recorded.

tools/skill-usage/render_units.py renders reviewed user units that keep the
three skill reports current: hourly, the host report (91 s measured,
including the $0 zero-turn claude -p /skill-doctor, with --claude-timeout
120 because the 30 s default expired once under load) and the Claude lanes
sweep (198 s and a 1.9 GB peak, projected from 181 MB to 26 KB by
systemd/claude-lanes.jq); daily, the Codex lanes report, which had not
finished after 25 minutes, so its completion time is unmeasured. Each step
renames a finished report into place.

The evidence manifest records the new hashes of source_policy.json and the
skill-usage README. Tests cover each section, unknown versus zero,
staleness, hostile types and strings, privacy (eight email forms, decoded
twice) and the exact grants; 33 fail-before mutations of this change each
fail them. The unit tests round-trip each ExecStart through systemd quoting
and pass systemd-analyze verify.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
…tration landscape on the command-center page

The owner asked for the whole ecosystem on one page, so the command center
grows from six sections to nine, still from existing producers only:

- Orchestration: the CC's recorded orchestration-frameworks resolution and
  the same slot in cc-native-practice slots-final.json, the landing queue,
  the co-op's GPT read queue (read-queue-now.json) and the Adoption
  snapshot's orchestration tool calls by role.
- Resolution landscape: each matrix winner's component, pin, evidence class,
  lifecycle stages and platforms, with the W6 final columns (verdict, run
  pin, upstream E2E at the pin, invoke evidence) as recorded or "not
  recorded". Each winner's repository is matched to cc-now.json
  mirrors.pins by the version its tag names or a commit prefix, and a
  winner without a mirror says so. Terminal states come only from
  final-stack.json and read "pending #1008/#1007" until it exists. The
  committed north-star readiness layers follow with the same columns; the
  CC's program, mirrors, rulings and ten-layer plan render as given.
- SOTA skill invoke rates: one row per skill pinned in
  adoption/skills/manifest.json (source@ref, linked only for https, and
  path), joined with the 7-day counts per client from skill_usage.py and
  child-usage.mjs, or from #970's skill-invoke-rate-daily/1 projection when
  it is current. Zero calls flag "wiring defect"; a pinned skill with no
  install record is "not installed" (unknown while /skill-doctor is
  unmeasured); a called skill the manifest does not pin is "unpinned". The
  practice-slot table marks the orchestration-frameworks row. An unmeasured
  value never reads as zero.
- Tokens saved: tools/local-pages/token_tools_now.py runs each token tool's
  own report command (rtk gain, headroom agent-savings and output-savings,
  context-mode doctor) and records its exit code, run time, version and
  own estimate in token-tools-now.json. The page shows each beside its
  command, labels the token-window counters as client counters, and never
  sums across tools, evidence classes or windows.
- Research queue: research-queue.tsv rows and research-state.json's resume
  order.

The #1012 Claude read's fixes are folded in. B1: the email mask moves into
the shared sanitizer and matches after its per-token decoding (CPython
html.unescape and urllib.parse.unquote, cited at v3.13.16), so &commat;, an
encoded dot (%2E or &#46;), %2540 and a semicolon-less &#64 are omitted on
every page; the old page-local mask left all five readable. B2: each
section's label follows what it renders, and every partial section names
its reason. B3: each section and the count strip render in their own guard,
so a scalar codex_top_lanes_M or an integer above 1e308 degrades only its
own section. The receipt lists only the not-wired inputs the page rendered.

source_policy.json gains a command_center role map with sixteen exact repo
and state paths, read through CommandCenterReads, which extends the
Architecture reader (bounded, no-follow, protected names, no user root).
Reports past their limit read "stale" with their age; times recorded as a
time of day stay as recorded.

tools/skill-usage/render_units.py renders reviewed user units that keep the
three skill reports current: hourly, the host report (91 s measured,
including the $0 zero-turn claude -p /skill-doctor, with --claude-timeout
120 because the 30 s default expired once under load) and the Claude lanes
sweep (198 s and a 1.9 GB peak, projected from 181 MB to 26 KB by
systemd/claude-lanes.jq); daily, the Codex lanes report, which had not
finished after 25 minutes, so its completion time is unmeasured. Each step
renames a finished report into place.

The evidence manifest records the new hashes of source_policy.json and the
skill-usage README. Tests cover each section, unknown versus zero,
staleness, hostile types and strings, privacy (eight email forms, decoded
twice) and the exact grants; 33 fail-before mutations of this change each
fail them. The unit tests round-trip each ExecStart through systemd quoting
and pass systemd-analyze verify.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
…RTK figure RTK's, and close the token-report and long-token mask gaps

Round 2 of #1012, from the CC's adjudication of the Claude micro at
50977b0. Each fix has a test that fails at 2dfb3c8:

- An hcom roster that Fleet tracking could not read (fleet_data's UNKNOWN
  shape, or no tracking) renders its gap with the producer's status and
  reason, so Sessions reads partial instead of wired (Codex :156).
- token_tools_now.py destination() checks both the absolute path and its
  resolve(), as tools/skill-usage/render_units.py _external_path does, so a
  parent or ancestor that reaches the checkout through a symlink is refused
  before any tool runs (Codex :160).
- The count strip takes the RTK figure only from RTK's token-tools row, the
  token-window report whose name names RTK, or cc-now token_efficiency.rtk,
  and otherwise reads UNKNOWN. Mapping order no longer lets another tool's
  report stand in for it (Codex :1144).
- token_tools_now.py passes dict keys as well as values through the shared
  sanitizer, whose sanitize() projects values only, so the docstring's
  claim now holds. Two keys that project to one text keep both entries.
- A token over 4,096 characters is not decoded, so the shared email mask
  also matches the encoded at-sign and dot forms in place (%40, %2540, &#64
  with or without its semicolon, &#x40, &commat;, %2E, &#46, &period;), as
  b209afe's page-local mask did for %40 and &#64;.
- The shared email mask no longer reads a systemd template-unit name such
  as git-maintenance@daily.timer as an address: its last part may not be
  one of the eleven unit types systemd.unit(5) lists at systemd 259. Since
  the round-1 mask (50977b0), nine such paths on three architecture layer
  pages rendered as "[email omitted]".

The local-pages README states each behavior.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
…tration landscape on the command-center page

The owner asked for the whole ecosystem on one page, so the command center
grows from six sections to nine, still from existing producers only:

- Orchestration: the CC's recorded orchestration-frameworks resolution and
  the same slot in cc-native-practice slots-final.json, the landing queue,
  the co-op's GPT read queue (read-queue-now.json) and the Adoption
  snapshot's orchestration tool calls by role.
- Resolution landscape: each matrix winner's component, pin, evidence class,
  lifecycle stages and platforms, with the W6 final columns (verdict, run
  pin, upstream E2E at the pin, invoke evidence) as recorded or "not
  recorded". Each winner's repository is matched to cc-now.json
  mirrors.pins by the version its tag names or a commit prefix, and a
  winner without a mirror says so. Terminal states come only from
  final-stack.json and read "pending #1008/#1007" until it exists. The
  committed north-star readiness layers follow with the same columns; the
  CC's program, mirrors, rulings and ten-layer plan render as given.
- SOTA skill invoke rates: one row per skill pinned in
  adoption/skills/manifest.json (source@ref, linked only for https, and
  path), joined with the 7-day counts per client from skill_usage.py and
  child-usage.mjs, or from #970's skill-invoke-rate-daily/1 projection when
  it is current. Zero calls flag "wiring defect"; a pinned skill with no
  install record is "not installed" (unknown while /skill-doctor is
  unmeasured); a called skill the manifest does not pin is "unpinned". The
  practice-slot table marks the orchestration-frameworks row. An unmeasured
  value never reads as zero.
- Tokens saved: tools/local-pages/token_tools_now.py runs each token tool's
  own report command (rtk gain, headroom agent-savings and output-savings,
  context-mode doctor) and records its exit code, run time, version and
  own estimate in token-tools-now.json. The page shows each beside its
  command, labels the token-window counters as client counters, and never
  sums across tools, evidence classes or windows.
- Research queue: research-queue.tsv rows and research-state.json's resume
  order.

The #1012 Claude read's fixes are folded in. B1: the email mask moves into
the shared sanitizer and matches after its per-token decoding (CPython
html.unescape and urllib.parse.unquote, cited at v3.13.16), so &commat;, an
encoded dot (%2E or &#46;), %2540 and a semicolon-less &#64 are omitted on
every page; the old page-local mask left all five readable. B2: each
section's label follows what it renders, and every partial section names
its reason. B3: each section and the count strip render in their own guard,
so a scalar codex_top_lanes_M or an integer above 1e308 degrades only its
own section. The receipt lists only the not-wired inputs the page rendered.

source_policy.json gains a command_center role map with sixteen exact repo
and state paths, read through CommandCenterReads, which extends the
Architecture reader (bounded, no-follow, protected names, no user root).
Reports past their limit read "stale" with their age; times recorded as a
time of day stay as recorded.

tools/skill-usage/render_units.py renders reviewed user units that keep the
three skill reports current: hourly, the host report (91 s measured,
including the $0 zero-turn claude -p /skill-doctor, with --claude-timeout
120 because the 30 s default expired once under load) and the Claude lanes
sweep (198 s and a 1.9 GB peak, projected from 181 MB to 26 KB by
systemd/claude-lanes.jq); daily, the Codex lanes report, which had not
finished after 25 minutes, so its completion time is unmeasured. Each step
renames a finished report into place.

The evidence manifest records the new hashes of source_policy.json and the
skill-usage README. Tests cover each section, unknown versus zero,
staleness, hostile types and strings, privacy (eight email forms, decoded
twice) and the exact grants; 33 fail-before mutations of this change each
fail them. The unit tests round-trip each ExecStart through systemd quoting
and pass systemd-analyze verify.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
…RTK figure RTK's, and close the token-report and long-token mask gaps

Round 2 of #1012, from the CC's adjudication of the Claude micro at
50977b0. Each fix has a test that fails at 2dfb3c8:

- An hcom roster that Fleet tracking could not read (fleet_data's UNKNOWN
  shape, or no tracking) renders its gap with the producer's status and
  reason, so Sessions reads partial instead of wired (Codex :156).
- token_tools_now.py destination() checks both the absolute path and its
  resolve(), as tools/skill-usage/render_units.py _external_path does, so a
  parent or ancestor that reaches the checkout through a symlink is refused
  before any tool runs (Codex :160).
- The count strip takes the RTK figure only from RTK's token-tools row, the
  token-window report whose name names RTK, or cc-now token_efficiency.rtk,
  and otherwise reads UNKNOWN. Mapping order no longer lets another tool's
  report stand in for it (Codex :1144).
- token_tools_now.py passes dict keys as well as values through the shared
  sanitizer, whose sanitize() projects values only, so the docstring's
  claim now holds. Two keys that project to one text keep both entries.
- A token over 4,096 characters is not decoded, so the shared email mask
  also matches the encoded at-sign and dot forms in place (%40, %2540, &#64
  with or without its semicolon, &#x40, &commat;, %2E, &#46, &period;), as
  b209afe's page-local mask did for %40 and &#64;.
- The shared email mask no longer reads a systemd template-unit name such
  as git-maintenance@daily.timer as an address: its last part may not be
  one of the eleven unit types systemd.unit(5) lists at systemd 259. Since
  the round-1 mask (50977b0), nine such paths on three architecture layer
  pages rendered as "[email omitted]".

The local-pages README states each behavior.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
…pt unit types against the public suffix list

The final correction for #1012, from the CC's adjudication of the Claude
micro at bdc0978:

- target is a delegated top-level domain (the installed public suffix
  list, publicsuffix 20260129.1928-1, lines 10339-10341). Exempting it as a
  systemd unit type left an address there readable in its plain, %40 and
  &#64; forms. It leaves the exempt list, which keeps the other ten of the
  eleven types in systemd.unit(5).
- A class-guard test intersects the exempt types with the installed public
  suffix list and fails on any overlap. It skips, giving its reason, when
  the list is absent.
- The sanitizer docstring and comment and the local-pages README name
  exactly the exempt types. The README also lists the forms the mask matches
  in place in a token over 4,096 characters, and says other encodings there
  stay as written.

Both new tests fail at bdc0978 (4 failures) and pass here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
…tration landscape on the command-center page

The owner asked for the whole ecosystem on one page, so the command center
grows from six sections to nine, still from existing producers only:

- Orchestration: the CC's recorded orchestration-frameworks resolution and
  the same slot in cc-native-practice slots-final.json, the landing queue,
  the co-op's GPT read queue (read-queue-now.json) and the Adoption
  snapshot's orchestration tool calls by role.
- Resolution landscape: each matrix winner's component, pin, evidence class,
  lifecycle stages and platforms, with the W6 final columns (verdict, run
  pin, upstream E2E at the pin, invoke evidence) as recorded or "not
  recorded". Each winner's repository is matched to cc-now.json
  mirrors.pins by the version its tag names or a commit prefix, and a
  winner without a mirror says so. Terminal states come only from
  final-stack.json and read "pending #1008/#1007" until it exists. The
  committed north-star readiness layers follow with the same columns; the
  CC's program, mirrors, rulings and ten-layer plan render as given.
- SOTA skill invoke rates: one row per skill pinned in
  adoption/skills/manifest.json (source@ref, linked only for https, and
  path), joined with the 7-day counts per client from skill_usage.py and
  child-usage.mjs, or from #970's skill-invoke-rate-daily/1 projection when
  it is current. Zero calls flag "wiring defect"; a pinned skill with no
  install record is "not installed" (unknown while /skill-doctor is
  unmeasured); a called skill the manifest does not pin is "unpinned". The
  practice-slot table marks the orchestration-frameworks row. An unmeasured
  value never reads as zero.
- Tokens saved: tools/local-pages/token_tools_now.py runs each token tool's
  own report command (rtk gain, headroom agent-savings and output-savings,
  context-mode doctor) and records its exit code, run time, version and
  own estimate in token-tools-now.json. The page shows each beside its
  command, labels the token-window counters as client counters, and never
  sums across tools, evidence classes or windows.
- Research queue: research-queue.tsv rows and research-state.json's resume
  order.

The #1012 Claude read's fixes are folded in. B1: the email mask moves into
the shared sanitizer and matches after its per-token decoding (CPython
html.unescape and urllib.parse.unquote, cited at v3.13.16), so &commat;, an
encoded dot (%2E or &#46;), %2540 and a semicolon-less &#64 are omitted on
every page; the old page-local mask left all five readable. B2: each
section's label follows what it renders, and every partial section names
its reason. B3: each section and the count strip render in their own guard,
so a scalar codex_top_lanes_M or an integer above 1e308 degrades only its
own section. The receipt lists only the not-wired inputs the page rendered.

source_policy.json gains a command_center role map with sixteen exact repo
and state paths, read through CommandCenterReads, which extends the
Architecture reader (bounded, no-follow, protected names, no user root).
Reports past their limit read "stale" with their age; times recorded as a
time of day stay as recorded.

tools/skill-usage/render_units.py renders reviewed user units that keep the
three skill reports current: hourly, the host report (91 s measured,
including the $0 zero-turn claude -p /skill-doctor, with --claude-timeout
120 because the 30 s default expired once under load) and the Claude lanes
sweep (198 s and a 1.9 GB peak, projected from 181 MB to 26 KB by
systemd/claude-lanes.jq); daily, the Codex lanes report, which had not
finished after 25 minutes, so its completion time is unmeasured. Each step
renames a finished report into place.

The evidence manifest records the new hashes of source_policy.json and the
skill-usage README. Tests cover each section, unknown versus zero,
staleness, hostile types and strings, privacy (eight email forms, decoded
twice) and the exact grants; 33 fail-before mutations of this change each
fail them. The unit tests round-trip each ExecStart through systemd quoting
and pass systemd-analyze verify.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
…RTK figure RTK's, and close the token-report and long-token mask gaps

Round 2 of #1012, from the CC's adjudication of the Claude micro at
50977b0. Each fix has a test that fails at 2dfb3c8:

- An hcom roster that Fleet tracking could not read (fleet_data's UNKNOWN
  shape, or no tracking) renders its gap with the producer's status and
  reason, so Sessions reads partial instead of wired (Codex :156).
- token_tools_now.py destination() checks both the absolute path and its
  resolve(), as tools/skill-usage/render_units.py _external_path does, so a
  parent or ancestor that reaches the checkout through a symlink is refused
  before any tool runs (Codex :160).
- The count strip takes the RTK figure only from RTK's token-tools row, the
  token-window report whose name names RTK, or cc-now token_efficiency.rtk,
  and otherwise reads UNKNOWN. Mapping order no longer lets another tool's
  report stand in for it (Codex :1144).
- token_tools_now.py passes dict keys as well as values through the shared
  sanitizer, whose sanitize() projects values only, so the docstring's
  claim now holds. Two keys that project to one text keep both entries.
- A token over 4,096 characters is not decoded, so the shared email mask
  also matches the encoded at-sign and dot forms in place (%40, %2540, &#64
  with or without its semicolon, &#x40, &commat;, %2E, &#46, &period;), as
  b209afe's page-local mask did for %40 and &#64;.
- The shared email mask no longer reads a systemd template-unit name such
  as git-maintenance@daily.timer as an address: its last part may not be
  one of the eleven unit types systemd.unit(5) lists at systemd 259. Since
  the round-1 mask (50977b0), nine such paths on three architecture layer
  pages rendered as "[email omitted]".

The local-pages README states each behavior.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
…pt unit types against the public suffix list

The final correction for #1012, from the CC's adjudication of the Claude
micro at bdc0978:

- target is a delegated top-level domain (the installed public suffix
  list, publicsuffix 20260129.1928-1, lines 10339-10341). Exempting it as a
  systemd unit type left an address there readable in its plain, %40 and
  &#64; forms. It leaves the exempt list, which keeps the other ten of the
  eleven types in systemd.unit(5).
- A class-guard test intersects the exempt types with the installed public
  suffix list and fails on any overlap. It skips, giving its reason, when
  the list is absent.
- The sanitizer docstring and comment and the local-pages README name
  exactly the exempt types. The README also lists the forms the mask matches
  in place in a token over 4,096 characters, and says other encodings there
  stay as written.

Both new tests fail at bdc0978 (4 failures) and pass here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Oct 12, 2026
…tration landscape on the command-center page

The owner asked for the whole ecosystem on one page, so the command center
grows from six sections to nine, still from existing producers only:

- Orchestration: the CC's recorded orchestration-frameworks resolution and
  the same slot in cc-native-practice slots-final.json, the landing queue,
  the co-op's GPT read queue (read-queue-now.json) and the Adoption
  snapshot's orchestration tool calls by role.
- Resolution landscape: each matrix winner's component, pin, evidence class,
  lifecycle stages and platforms, with the W6 final columns (verdict, run
  pin, upstream E2E at the pin, invoke evidence) as recorded or "not
  recorded". Each winner's repository is matched to cc-now.json
  mirrors.pins by the version its tag names or a commit prefix, and a
  winner without a mirror says so. Terminal states come only from
  final-stack.json and read "pending #1008/#1007" until it exists. The
  committed north-star readiness layers follow with the same columns; the
  CC's program, mirrors, rulings and ten-layer plan render as given.
- SOTA skill invoke rates: one row per skill pinned in
  adoption/skills/manifest.json (source@ref, linked only for https, and
  path), joined with the 7-day counts per client from skill_usage.py and
  child-usage.mjs, or from #970's skill-invoke-rate-daily/1 projection when
  it is current. Zero calls flag "wiring defect"; a pinned skill with no
  install record is "not installed" (unknown while /skill-doctor is
  unmeasured); a called skill the manifest does not pin is "unpinned". The
  practice-slot table marks the orchestration-frameworks row. An unmeasured
  value never reads as zero.
- Tokens saved: tools/local-pages/token_tools_now.py runs each token tool's
  own report command (rtk gain, headroom agent-savings and output-savings,
  context-mode doctor) and records its exit code, run time, version and
  own estimate in token-tools-now.json. The page shows each beside its
  command, labels the token-window counters as client counters, and never
  sums across tools, evidence classes or windows.
- Research queue: research-queue.tsv rows and research-state.json's resume
  order.

The #1012 Claude read's fixes are folded in. B1: the email mask moves into
the shared sanitizer and matches after its per-token decoding (CPython
html.unescape and urllib.parse.unquote, cited at v3.13.16), so &commat;, an
encoded dot (%2E or &#46;), %2540 and a semicolon-less &#64 are omitted on
every page; the old page-local mask left all five readable. B2: each
section's label follows what it renders, and every partial section names
its reason. B3: each section and the count strip render in their own guard,
so a scalar codex_top_lanes_M or an integer above 1e308 degrades only its
own section. The receipt lists only the not-wired inputs the page rendered.

source_policy.json gains a command_center role map with sixteen exact repo
and state paths, read through CommandCenterReads, which extends the
Architecture reader (bounded, no-follow, protected names, no user root).
Reports past their limit read "stale" with their age; times recorded as a
time of day stay as recorded.

tools/skill-usage/render_units.py renders reviewed user units that keep the
three skill reports current: hourly, the host report (91 s measured,
including the $0 zero-turn claude -p /skill-doctor, with --claude-timeout
120 because the 30 s default expired once under load) and the Claude lanes
sweep (198 s and a 1.9 GB peak, projected from 181 MB to 26 KB by
systemd/claude-lanes.jq); daily, the Codex lanes report, which had not
finished after 25 minutes, so its completion time is unmeasured. Each step
renames a finished report into place.

The evidence manifest records the new hashes of source_policy.json and the
skill-usage README. Tests cover each section, unknown versus zero,
staleness, hostile types and strings, privacy (eight email forms, decoded
twice) and the exact grants; 33 fail-before mutations of this change each
fail them. The unit tests round-trip each ExecStart through systemd quoting
and pass systemd-analyze verify.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Oct 12, 2026
…RTK figure RTK's, and close the token-report and long-token mask gaps

Round 2 of #1012, from the CC's adjudication of the Claude micro at
50977b0. Each fix has a test that fails at 2dfb3c8:

- An hcom roster that Fleet tracking could not read (fleet_data's UNKNOWN
  shape, or no tracking) renders its gap with the producer's status and
  reason, so Sessions reads partial instead of wired (Codex :156).
- token_tools_now.py destination() checks both the absolute path and its
  resolve(), as tools/skill-usage/render_units.py _external_path does, so a
  parent or ancestor that reaches the checkout through a symlink is refused
  before any tool runs (Codex :160).
- The count strip takes the RTK figure only from RTK's token-tools row, the
  token-window report whose name names RTK, or cc-now token_efficiency.rtk,
  and otherwise reads UNKNOWN. Mapping order no longer lets another tool's
  report stand in for it (Codex :1144).
- token_tools_now.py passes dict keys as well as values through the shared
  sanitizer, whose sanitize() projects values only, so the docstring's
  claim now holds. Two keys that project to one text keep both entries.
- A token over 4,096 characters is not decoded, so the shared email mask
  also matches the encoded at-sign and dot forms in place (%40, %2540, &#64
  with or without its semicolon, &#x40, &commat;, %2E, &#46, &period;), as
  b209afe's page-local mask did for %40 and &#64;.
- The shared email mask no longer reads a systemd template-unit name such
  as git-maintenance@daily.timer as an address: its last part may not be
  one of the eleven unit types systemd.unit(5) lists at systemd 259. Since
  the round-1 mask (50977b0), nine such paths on three architecture layer
  pages rendered as "[email omitted]".

The local-pages README states each behavior.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Oct 12, 2026
…pt unit types against the public suffix list

The final correction for #1012, from the CC's adjudication of the Claude
micro at bdc0978:

- target is a delegated top-level domain (the installed public suffix
  list, publicsuffix 20260129.1928-1, lines 10339-10341). Exempting it as a
  systemd unit type left an address there readable in its plain, %40 and
  &#64; forms. It leaves the exempt list, which keeps the other ten of the
  eleven types in systemd.unit(5).
- A class-guard test intersects the exempt types with the installed public
  suffix list and fails on any overlap. It skips, giving its reason, when
  the list is absent.
- The sanitizer docstring and comment and the local-pages README name
  exactly the exempt types. The README also lists the forms the mask matches
  in place in a token over 4,096 characters, and says other encodings there
  stay as written.

Both new tests fail at bdc0978 (4 failures) and pass here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Oct 12, 2026
…gests

The terminal commit of #1012 under the rule-4 ruling on 51f85b5, with
Astra's delta read of 51f85b5 (two P1s) folded in.

- B1: from each at sign, the walk back over atext stops after 256
  characters (RFC 5321 section 4.5.3.1.1 limits a local part to 64 octets)
  and never passes the address before it. The reviewer's three adversarial
  50,000-character forms (%40 and &#64 written in atext, and
  apostrophe-joined %252540 tokens) take 0.025, 0.023 and 0.023 s, where
  51f85b5 takes 12.1, 10.0 and 4.3 s (same host, load 29). The docstring
  and README now say the bound is what makes the cost linear, and that a
  local part over 256 characters keeps its leading part visible.
- B2: overlapping or touching matches merge from their earliest start, so
  "w1 w2@d1.example.org"@d2.example.org is omitted whole.
- C: a JSON-escaped quote (\") opens and closes a quoted local part, so
  \"w1 w2\"@d.example.org in serialized JSON masks like its decoded form.
  After masking, a value that still holds an at sign, raw or encoded (%40,
  %2540, &#64;, &commat;, \u0040), followed by a domain, directly after a
  word character or after a quote with only whitespace between, is dropped
  whole and reads RESIDUE_OMITTED. The command-center page counts those
  values in its header and names their sections partial.
- Astra P1 1: an empty quoted local part ("") and a punctuation-only
  dot-atom (!!!) are valid (CPython Lib/email/_parseaddr.py getaddrspec
  :365-385, getatom :475-493 and getdelimited :449 at v3.13.16, cbc944f4),
  so the mask takes any nonempty atext run and quoted strings of 0 to 256
  characters.
  Leading backticks open a Markdown code span, replacing the
  letter-or-digit rule, so `@AGENTS.md` stays.
- Astra P1 2 (#161): sources.html published the SHA-256 of private raw
  bytes: the seven command-center state inputs, cc-now.json and
  adoption-now.json. A digest of raw bytes would confirm a guessed masked
  value. The receipt marks those inputs private and keeps their digests;
  the composer's pages show "private state input; this page withholds its
  digest, which the nonserved receipt keeps". Out of this commit's scope,
  and unchanged from main: sources.html still shows the raw digests of the
  gap board, the roadmap inputs and 70 readiness receipts (20 of them
  expected_sha256 pins in tools/north-star/sources.json), and the
  architecture builder's custody table (architecture_view.py:311) shows
  cc-now.json's and adoption-now.json's. The PR's Follow-ups list them.

Nine new regressions. At 51f85b5 they fail (27 failures and 13 errors,
counting subtests) with the exported tree unchanged, and Astra's three
probes fail there and pass here. The 35 local-pages, skill-usage and
north-star modules pass (789 tests, 8 skipped). A live build takes 42.4 s,
against 44.3 s at 51f85b5, and its 43 pages carry no mask or residue
placeholder. On 284,875 unique strings from the live inputs, catalogs,
manifests and repository Markdown, 2 outputs differ from 51f85b5's (an
apostrophe-quoted '@AGENTS.md' now masks, in text no page renders), and
none is dropped as residue.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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