From a99c217a01a78b9752ab2ec3785313db44f4efa7 Mon Sep 17 00:00:00 2001 From: Azahari Zaman Date: Thu, 13 Aug 2026 02:03:35 +0800 Subject: [PATCH 1/2] refactor: scrub replay-hash / byte-identical terminology from live docs Rephrase the imprecise 'byte-identical output' determinism language in the live knowledge-base docs (AGENTS.md, CONTEXT.md, ARCHITECTURE.md, README.md, SECURITY.md, TESTING_STRATEGY.md, HOW_TO_ADD_NEW_CAPABILITY.md, HOW_TO_ADD_NEW_GRAMMAR.md) and in source/test docstrings (paxman/core/extensions.py, tests/integration/test_pipeline.py, tests/property/test_money_properties.py) with the precise determinism definition: no world-knowledge, no clock, no environment-dependent ordering, no fuzzy logic, no network inference across recognition, validation, and canonicalization. Historical plan/spec/research/report artifacts that still reference the removed replay_hash mechanism are now under docs/development/ and left untouched (they already carry 'replay-hash removed; do not use as a sample' notes). The intentional removal assertion 'assert not hasattr(vs, "replay_hash")' in tests/unit/test_version_stamp.py is preserved. --- AGENTS.md | 2 +- ARCHITECTURE.md | 6 +-- CONTEXT.md | 4 +- HOW_TO_ADD_NEW_CAPABILITY.md | 2 +- HOW_TO_ADD_NEW_GRAMMAR.md | 2 +- README.md | 2 +- SECURITY.md | 2 +- TESTING_STRATEGY.md | 2 +- docs/development/AGENTS.md | 44 +++++++++++++++++++ ...ontract-params-hypothesis-tests-revised.md | 0 ...-07-26-contract-params-hypothesis-tests.md | 0 .../plans/2026-07-26-email-capability.md | 0 ...07-28-country-capability-implementation.md | 0 .../2026-08-01-phone-number-capability.md | 0 ...26-08-02-capability-surface-homogeneity.md | 0 .../2026-08-03-f1-grammar-rule-affinity.md | 10 +++++ .../2026-08-03-f2-include-feature-gating.md | 0 ...8-03-f3-recognition-validation-boundary.md | 6 +++ .../2026-08-04-centralize-output-format.md | 28 ++++++++++++ .../2026-08-04-recognition-homogeneity.md | 36 +++++++++++++++ .../plans/2026-08-05-isbn-capability.md | 24 ++++++++++ .../plans/2026-08-05-money-capability.md | 30 +++++++++++++ .../plans/2026-08-06-url-capability.md | 0 .../plans/2026-08-08-currency-capability.md | 0 .../plans/2026-08-09-si-units-capability.md | 0 .../2026-08-10-adr0002-remove-replay-hash.md | 0 ...08-11-adr0003-semantic-affinity-routing.md | 0 .../report/architecture-review-2026-07-26.md | 0 .../recognition-handling-library-research.md | 0 .../2026-08-05-isbn-canonicalization.md | 0 .../2026-08-05-money-canonicalization.md | 0 .../2026-08-06-url-canonicalization.md | 0 .../2026-08-09-si-unit-canonicalization.md | 0 .../2026-07-28-country-capability-design.md | 0 ...-recognition-validation-boundary-design.md | 0 paxman/core/extensions.py | 2 +- tests/integration/test_pipeline.py | 2 +- tests/property/test_money_properties.py | 7 +-- 38 files changed, 195 insertions(+), 16 deletions(-) create mode 100644 docs/development/AGENTS.md rename docs/{superpowers => development}/plans/2026-07-26-contract-params-hypothesis-tests-revised.md (100%) rename docs/{superpowers => development}/plans/2026-07-26-contract-params-hypothesis-tests.md (100%) rename docs/{superpowers => development}/plans/2026-07-26-email-capability.md (100%) rename docs/{superpowers => development}/plans/2026-07-28-country-capability-implementation.md (100%) rename docs/{superpowers => development}/plans/2026-08-01-phone-number-capability.md (100%) rename docs/{superpowers => development}/plans/2026-08-02-capability-surface-homogeneity.md (100%) rename docs/{superpowers => development}/plans/2026-08-03-f1-grammar-rule-affinity.md (90%) rename docs/{superpowers => development}/plans/2026-08-03-f2-include-feature-gating.md (100%) rename docs/{superpowers => development}/plans/2026-08-03-f3-recognition-validation-boundary.md (94%) rename docs/{superpowers => development}/plans/2026-08-04-centralize-output-format.md (81%) rename docs/{superpowers => development}/plans/2026-08-04-recognition-homogeneity.md (90%) rename docs/{superpowers => development}/plans/2026-08-05-isbn-capability.md (93%) rename docs/{superpowers => development}/plans/2026-08-05-money-capability.md (97%) rename docs/{superpowers => development}/plans/2026-08-06-url-capability.md (100%) rename docs/{superpowers => development}/plans/2026-08-08-currency-capability.md (100%) rename docs/{superpowers => development}/plans/2026-08-09-si-units-capability.md (100%) rename docs/{superpowers => development}/plans/2026-08-10-adr0002-remove-replay-hash.md (100%) rename docs/{superpowers => development}/plans/2026-08-11-adr0003-semantic-affinity-routing.md (100%) rename docs/{ => development}/report/architecture-review-2026-07-26.md (100%) rename docs/{ => development}/report/recognition-handling-library-research.md (100%) rename docs/{ => development}/research/2026-08-05-isbn-canonicalization.md (100%) rename docs/{ => development}/research/2026-08-05-money-canonicalization.md (100%) rename docs/{ => development}/research/2026-08-06-url-canonicalization.md (100%) rename docs/{ => development}/research/2026-08-09-si-unit-canonicalization.md (100%) rename docs/{superpowers => development}/specs/2026-07-28-country-capability-design.md (100%) rename docs/{superpowers => development}/specs/2026-08-03-f3-recognition-validation-boundary-design.md (100%) diff --git a/AGENTS.md b/AGENTS.md index ea8f8584..a5486962 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -62,7 +62,7 @@ docs/ # adr/, report/, research/, superpowers/plans+specs ## ANTI-PATTERNS (THIS PROJECT) - **No `# type: ignore` / `# noqa` / `# pyright: ignore` in `paxman/` source** — fix root cause or use scoped ruff `per-file-ignores` (sanctioned pattern in pyproject). Tests may use `# type: ignore[misc]` for immutability checks. -- Never guess/infer/suggest — same input + contract = byte-identical output. +- Deterministic by construction: given the same input and contract, the pipeline always yields the same canonical output — no world-knowledge, no clock, no environment-dependent ordering, no fuzzy logic, no network inference across recognition, validation, and canonicalization. - No cross-capability imports; capabilities import only from `paxman.core`; `paxman.core` imports nothing from `paxman.*`. - Grammars must not map tokens to canonical values or import rule-layer data. - Rules never contain the token `output_format` (code, comments, or docstrings). diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 393ae5ff..3109fdfe 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -8,7 +8,7 @@ Paxman is a canonicalization authority resolver — a library that takes ambiguo ### Determinism -Paxman never guesses. Given the same input, the same contract configuration, and the same library snapshot (fixed library version, registry contents, and rule-data tables), the output is always byte-identical. This property holds by construction: every pipeline stage is a pure, deterministic function of its inputs — grammar recognition, rule validation, capability formatting, candidate deduplication, and status determination include no clocks, no randomness, and no environment-dependent ordering. Identical inputs always produce identical outputs, enabling auditability and reproducibility. Across library snapshots, provenance or rule-routing changes may alter the resulting metadata; the byte-identical guarantee is scoped to a fixed snapshot. +Paxman never guesses. Given the same input, the same contract configuration, and the same library snapshot (fixed library version, registry contents, and rule-data tables), the pipeline always yields the same canonical output. This property holds by construction: every pipeline stage — grammar recognition, rule validation, capability formatting, candidate deduplication, and status determination — is a pure function of its inputs with no world-knowledge, no clock, no environment-dependent ordering, no fuzzy logic, and no network inference. Identical inputs therefore always produce identical outputs, enabling auditability and reproducibility. Across library snapshots, provenance or rule-routing changes may alter the resulting metadata; the determinism guarantee is scoped to a fixed snapshot. ### Provenance-First @@ -163,13 +163,13 @@ Determinism is a structural property of the layered pipeline, not a post-hoc art - **Validation layer.** Rules accept recognized representations and produce candidates, each carrying a canonical value and provenance. A rule's output depends only on the representation and the contract. - **Result layer.** The engine deduplicates identical candidates and folds the distinct candidate values into one of the resolution statuses: `SUCCESS` when all candidates agree on a single canonical value, `AMBIGUOUS` when they disagree, `INVALID` when nothing validated, and `MISSING` when no grammar recognized anything. -Every stage is a pure function of its inputs — no clocks, no randomness, no environment-dependent ordering — so the same input, contract configuration, and library snapshot (fixed library version, registry contents, and rule-data tables) always produce the same output, byte-for-byte. The `VersionStamp` on each execution result records the library version for provenance; the byte-identical guarantee itself rests on this determinism-by-construction. Changes to provenance or rule routing across library snapshots can alter result metadata; the byte-identical guarantee is scoped to a fixed snapshot. +Every stage is a pure function of its inputs — no clocks, no randomness, no environment-dependent ordering, no world-knowledge, no fuzzy logic, no network inference — so the same input, contract configuration, and library snapshot (fixed library version, registry contents, and rule-data tables) always produce the same canonical output. The `VersionStamp` on each execution result records the library version for provenance; the determinism guarantee rests on this determinism-by-construction. Changes to provenance or rule routing across library snapshots can alter result metadata; the determinism guarantee is scoped to a fixed snapshot. ### Community Extensions Capabilities are closed for modification but open for extension. Community contributors register additional grammars (and the rules that validate them) against an existing capability through `paxman.core.extensions` — never by editing the capability package. The registries freeze with the capability registry at the first pipeline run. -A contract opts a registered grammar in by naming it in `extra_grammars`, a base `CapabilityContract` field surfaced on every `create_contract` factory. The engine composes the shipped active set with the opted-in extras, deduplicating names while preserving order — shipped slots first, extras after (unknown extra names are silently skipped). The shipped slots are `contract.active_grammars` when the contract implements it (the gated capabilities), or every shipped grammar in `get_grammars()` order when it returns `None` (the base default). Opt-in preserves determinism: a contract that names no extras composes to exactly the shipped set, so non-opt-in behavior is byte-identical. +A contract opts a registered grammar in by naming it in `extra_grammars`, a base `CapabilityContract` field surfaced on every `create_contract` factory. The engine composes the shipped active set with the opted-in extras, deduplicating names while preserving order — shipped slots first, extras after (unknown extra names are silently skipped). The shipped slots are `contract.active_grammars` when the contract implements it (the gated capabilities), or every shipped grammar in `get_grammars()` order when it returns `None` (the base default). Opt-in preserves determinism: a contract that names no extras composes to exactly the shipped set, so non-opt-in behavior is identical (deterministic). Community rules follow the same opt-in discipline: a registered rule runs only when the contract's `extra_grammars` resolve to one of its `target_semantics` ids. An un-opted community rule — even one targeting a shipped grammar's semantics — never affects results, so a default contract resolves with shipped rules only. diff --git a/CONTEXT.md b/CONTEXT.md index 4cba1350..e949620f 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -6,9 +6,9 @@ A **canonicalization authority resolver** — a library that takes ambiguous human input and returns what authoritative specifications say that input means, with full provenance. Paxman is both a **syntactic recognizer** (finds values in text) and a **semantic interpreter** (validates against authoritative specifications). **Invariants:** -- **Deterministic:** Never guess, never infer, never suggest +- **No fabrication:** Never guess, never infer, never suggest - **Provenance-first:** Always cite authority-defined specifications, registries, policies -- **Replay-safe:** Same input + same contract = byte-identical output +- **Deterministic:** Given the same input and contract, the pipeline yields the same canonical output — no world-knowledge, no clock, no environment-dependent ordering, no fuzzy logic, no network inference across recognition, validation, and canonicalization. ### Capability A domain module (e.g., Email) that: diff --git a/HOW_TO_ADD_NEW_CAPABILITY.md b/HOW_TO_ADD_NEW_CAPABILITY.md index b2750d88..07323392 100644 --- a/HOW_TO_ADD_NEW_CAPABILITY.md +++ b/HOW_TO_ADD_NEW_CAPABILITY.md @@ -1053,7 +1053,7 @@ A shipped capability is closed for modification but open for extension: you can Semantics to rely on: - The extension registries freeze with the capability registry — registration after the first pipeline run raises `CapabilityError`. -- Opt-in only: an un-named registered grammar never affects results, keeping shipped behavior byte-identical for non-opt-in contracts. +- Opt-in only: an un-named registered grammar never affects results, so shipped behavior stays identical (deterministic) for non-opt-in contracts. - Community rules are opt-in too: a registered rule runs only when the contract's `extra_grammars` resolve to one of its `target_semantics`; an un-opted rule — even one targeting a shipped grammar's semantics — never affects results. - Unknown `extra_grammars` names are silently skipped; shipped names listed in `extra_grammars` are deduplicated. - Composition is guarded: a grammar name colliding with a shipped name, or an opted-in community rule naming a missing grammar, fails fast at pipeline start. diff --git a/HOW_TO_ADD_NEW_GRAMMAR.md b/HOW_TO_ADD_NEW_GRAMMAR.md index 173d7e56..248fa324 100644 --- a/HOW_TO_ADD_NEW_GRAMMAR.md +++ b/HOW_TO_ADD_NEW_GRAMMAR.md @@ -165,7 +165,7 @@ def active_grammars(self) -> list[str]: return grammars ``` -Recognition order (and the same-span tiebreak) follows the runnable set — `get_grammars()` order for the six all-active capabilities, the `active_grammars` list for the three gated ones — so appending at the end keeps every existing grammar's behavior byte-identical. Update the capability test asserting the grammar count (`test_get_grammars_returns_all`) and add one asserting the new name is wired. +Recognition order (and the same-span tiebreak) follows the runnable set — `get_grammars()` order for the six all-active capabilities, the `active_grammars` list for the three gated ones — so appending at the end keeps every existing grammar's behavior identical (deterministic). Update the capability test asserting the grammar count (`test_get_grammars_returns_all`) and add one asserting the new name is wired. > **The missing-half bug (gated capabilities only).** For Email, IP, and ISBN, the engine builds the runnable set from `contract.active_grammars`, not from `get_grammars()` — a grammar returned by `get_grammars()` but missing from `active_grammars` is dead code that will pass unit tests on the class and fail silently in the pipeline. The integration test in Step 5 is what catches this. The all-active capabilities have no such hole: the engine falls back to `get_grammars()` itself. diff --git a/README.md b/README.md index 5f18521b..f9500c36 100644 --- a/README.md +++ b/README.md @@ -484,7 +484,7 @@ Rules of the seam: - **Register before the first `canonicalize()` call** — the extension registries freeze with the capability registry. - **Opt-in only** — a registered grammar runs only when named in `extra_grammars` (available on every `create_contract` factory), and a registered rule runs only when the contract's `extra_grammars` resolve to one of its `target_semantics` ids; un-named grammars and un-opted rules never affect results. -- **Unknown `extra_grammars` names are silently skipped** for grammar activation, so a contract naming an uninstalled grammar still runs byte-identically; the unknown name is kept as-is as the semantics key for rule activation. A name that is not a grammar name but matches a known semantics id therefore activates that semantics's rules without opting in a grammar — those rules fire only on recognitions carrying that semantics (fail-fast `ContractError` applies only to ids no grammar claims). +- **Unknown `extra_grammars` names are silently skipped** for grammar activation, so a contract naming an uninstalled grammar still runs identically (deterministically); the unknown name is kept as-is as the semantics key for rule activation. A name that is not a grammar name but matches a known semantics id therefore activates that semantics's rules without opting in a grammar — those rules fire only on recognitions carrying that semantics (fail-fast `ContractError` applies only to ids no grammar claims). - **Names must be unique in the composed set** — a community grammar colliding with a shipped name fails fast with `CapabilityError`. - **Community rules declare `target_semantics`** and activate only when the contract's `extra_grammars` resolve to one of those ids; a rule opted in via an id that no grammar claims fails fast with `ContractError`, while a rule that is not opted in stays inert regardless of any dangling targets. diff --git a/SECURITY.md b/SECURITY.md index 7a5833c7..b779b473 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -21,7 +21,7 @@ Paxman incorporates several design principles that reduce attack surface: - **Strict Type Checking**: The project enforces strict mode static type checking across all layers, catching type-related errors at development time rather than runtime. -- **Deterministic Computation**: Given the same input and contract configuration, output is always byte-identical. This prevents timing-based side channels and ensures reproducibility. +- **Deterministic Computation**: Given the same input and contract configuration, the pipeline always yields the same canonical output — no world-knowledge, no clock, no environment-dependent ordering, no fuzzy logic, no network inference across recognition, validation, and canonicalization. This prevents timing-based side channels and ensures reproducibility. - **Input Validation**: The system distinguishes between MISSING (no recognition), INVALID (recognized but unvalidated), and SUCCESS/AMBIGUOUS states, ensuring untrusted input is never silently accepted without authoritative validation. diff --git a/TESTING_STRATEGY.md b/TESTING_STRATEGY.md index ca7cd9b1..951ce77f 100644 --- a/TESTING_STRATEGY.md +++ b/TESTING_STRATEGY.md @@ -1,6 +1,6 @@ # Testing Strategy -Paxman's test suite exists to protect one core promise: given the same input and the same contract, the output is always byte-identical. Every test, from the lowest-level unit check to the full end-to-end run, reinforces that guarantee. The suite is built on `pytest` and organized into four layers that mirror the architectural boundaries of the system itself. +Paxman's test suite exists to protect one core promise: given the same input and the same contract, the pipeline always yields the same canonical output. Every test, from the lowest-level unit check to the full end-to-end run, reinforces that determinism — achieved by construction through no world-knowledge, no clock, no environment-dependent ordering, no fuzzy logic, and no network inference across recognition, validation, and canonicalization. The suite is built on `pytest` and organized into four layers that mirror the architectural boundaries of the system itself. --- diff --git a/docs/development/AGENTS.md b/docs/development/AGENTS.md new file mode 100644 index 00000000..65d5809f --- /dev/null +++ b/docs/development/AGENTS.md @@ -0,0 +1,44 @@ +# DEVELOPMENT DOCUMENTS — NON-SHIPPING + +**Scope:** This `docs/development/` directory and all of its subfolders contain development-related documents only. + +## Status + +These documents are **not part of the shipped release** of Paxman. They will not be included in published distributions (sdist/wheel) or any release artifact. + +## Maintenance Disclaimer + +- These documents may **drift out of sync** with the actual implementation as Paxman evolves. +- It is **not the maintainers' responsibility** to keep these documents accurate or up to date. +- These documents may be **removed at any time** without notice or a migration path. + +## Hard Guidance for Code and Docs + +Any code file, inline documentation, docstring, or other documentation in the repository +(including files outside this directory) **must NOT** reference these documents — neither by +filename nor by quoting or paraphrasing any part of their contents. + +Treat the contents of `docs/development/` as ephemeral working notes that may disappear or +become stale. Do not create dependencies on them. + +## Not Authoritative + +These documents do **not** define the project's overall architecture. For architecture-related +documentation, refer to `ARCHITECTURE.md`. + +These documents do **not** record decisions that persist beyond the scope of the file or the +development stage in which the document is considered active. For decisions persisted across the +project's lifetime, refer to the ADRs in `docs/adr/`. + +Once an implementation has landed, the documents in this folder and its subfolders are considered +**outdated**. + +## PR Review Policy + +PR reviewers **must skip** the documents in this folder and its subfolders when writing review +comments, **except** in the following cases: + +- The implementation for the particular file in question has **not yet landed**. +- The reviewer is **specifically requested** to review one or more of these files. +- The reviewer **cites** these documents solely to clarify a point they are making (not as + authoritative or binding guidance). diff --git a/docs/superpowers/plans/2026-07-26-contract-params-hypothesis-tests-revised.md b/docs/development/plans/2026-07-26-contract-params-hypothesis-tests-revised.md similarity index 100% rename from docs/superpowers/plans/2026-07-26-contract-params-hypothesis-tests-revised.md rename to docs/development/plans/2026-07-26-contract-params-hypothesis-tests-revised.md diff --git a/docs/superpowers/plans/2026-07-26-contract-params-hypothesis-tests.md b/docs/development/plans/2026-07-26-contract-params-hypothesis-tests.md similarity index 100% rename from docs/superpowers/plans/2026-07-26-contract-params-hypothesis-tests.md rename to docs/development/plans/2026-07-26-contract-params-hypothesis-tests.md diff --git a/docs/superpowers/plans/2026-07-26-email-capability.md b/docs/development/plans/2026-07-26-email-capability.md similarity index 100% rename from docs/superpowers/plans/2026-07-26-email-capability.md rename to docs/development/plans/2026-07-26-email-capability.md diff --git a/docs/superpowers/plans/2026-07-28-country-capability-implementation.md b/docs/development/plans/2026-07-28-country-capability-implementation.md similarity index 100% rename from docs/superpowers/plans/2026-07-28-country-capability-implementation.md rename to docs/development/plans/2026-07-28-country-capability-implementation.md diff --git a/docs/superpowers/plans/2026-08-01-phone-number-capability.md b/docs/development/plans/2026-08-01-phone-number-capability.md similarity index 100% rename from docs/superpowers/plans/2026-08-01-phone-number-capability.md rename to docs/development/plans/2026-08-01-phone-number-capability.md diff --git a/docs/superpowers/plans/2026-08-02-capability-surface-homogeneity.md b/docs/development/plans/2026-08-02-capability-surface-homogeneity.md similarity index 100% rename from docs/superpowers/plans/2026-08-02-capability-surface-homogeneity.md rename to docs/development/plans/2026-08-02-capability-surface-homogeneity.md diff --git a/docs/superpowers/plans/2026-08-03-f1-grammar-rule-affinity.md b/docs/development/plans/2026-08-03-f1-grammar-rule-affinity.md similarity index 90% rename from docs/superpowers/plans/2026-08-03-f1-grammar-rule-affinity.md rename to docs/development/plans/2026-08-03-f1-grammar-rule-affinity.md index cc04a1ed..54a89359 100644 --- a/docs/superpowers/plans/2026-08-03-f1-grammar-rule-affinity.md +++ b/docs/development/plans/2026-08-03-f1-grammar-rule-affinity.md @@ -24,6 +24,8 @@ notation *before* calling `matches()`, so routing is explicit and capability-agn - Annotate all 18 production `Rule` subclasses with their true acceptance domain. - TDD tests proving ambiguity is preserved and replay hashes are stable. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + **Non-goals (explicitly out of scope — separate findings in the audit):** - **F2** `include_*` feature gating (grammar-gate vs rule-gate unification). - **F3** grammar-time canonicalization / single-source authority tables. @@ -50,6 +52,8 @@ Each rule keeps its existing value-level `matches()`/`normalize()` logic as defe The declared set must equal the rule's *effective* acceptance domain (derived from the audit's cross-capability map), so behavior and the replay hash are byte-identical. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + --- ## 3. Findings recap (audit F1 → target) @@ -158,6 +162,8 @@ rule today). **This is the contract the implementation must satisfy — do not s - **Why:** the filter realizes F1; dedup keeps the replay hash stable if any future author over-declares `target_grammars` (audit's replay-safety condition). +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + ### Step 3 — Engine affinity invariant (`paxman/engine/orchestrator.py`) **Files:** `paxman/engine/orchestrator.py` (new helper; call in `run_capability` after `_filter_rules`, line 57). @@ -239,6 +245,8 @@ then confirm green. 9. `_validate_affinity` fires: a stub capability whose rule declares a non-existent grammar name → `run_capability` raises `ContractError`. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + --- ## 7. Verification (quality gates) @@ -278,6 +286,8 @@ integration/e2e suites unchanged in outcome. pattern). Step 3's invariant plus the `HOW_TO` presentational-only section document the discipline; no runtime shape coupling is introduced. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + --- ## 9. Out-of-scope follow-ups (do NOT bundle into this plan) diff --git a/docs/superpowers/plans/2026-08-03-f2-include-feature-gating.md b/docs/development/plans/2026-08-03-f2-include-feature-gating.md similarity index 100% rename from docs/superpowers/plans/2026-08-03-f2-include-feature-gating.md rename to docs/development/plans/2026-08-03-f2-include-feature-gating.md diff --git a/docs/superpowers/plans/2026-08-03-f3-recognition-validation-boundary.md b/docs/development/plans/2026-08-03-f3-recognition-validation-boundary.md similarity index 94% rename from docs/superpowers/plans/2026-08-03-f3-recognition-validation-boundary.md rename to docs/development/plans/2026-08-03-f3-recognition-validation-boundary.md index 850c0c7d..c51b4bb6 100644 --- a/docs/superpowers/plans/2026-08-03-f3-recognition-validation-boundary.md +++ b/docs/development/plans/2026-08-03-f3-recognition-validation-boundary.md @@ -397,6 +397,8 @@ Document that the result is validated by CLDR/Unicode, not ISO merely because th Record the old failure, the new raw-token behavior, the `INVALID`/`SUCCESS` localized matrix, the shared normalizer, the coverage test, and the intentional replay-hash/provenance change for affected inputs. State explicitly that Phone separator cleanup remains accepted syntax normalization. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + - [ ] **Step 4: Review documentation for contradictions** Run: @@ -436,6 +438,8 @@ uv run pytest tests/ -q Expected: all existing tests plus the new F3 tests pass. Any changed replay hash must be attributable to the documented localized provenance or route correction, not nondeterministic ordering. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + - [ ] **Step 3: Perform the manual pipeline check** Run a real Python driver through `run_capability`: @@ -471,6 +475,8 @@ Run `lsp_diagnostics` for every changed `.py` file and resolve all F3-caused err Report the design file, plan file, exact verification commands and results, intentional status/provenance changes, and any pre-existing failures. Do not claim replay hashes are unchanged for inputs whose validating authority changes. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + --- ## Dependency Order diff --git a/docs/superpowers/plans/2026-08-04-centralize-output-format.md b/docs/development/plans/2026-08-04-centralize-output-format.md similarity index 81% rename from docs/superpowers/plans/2026-08-04-centralize-output-format.md rename to docs/development/plans/2026-08-04-centralize-output-format.md index 05d59482..47ec964c 100644 --- a/docs/superpowers/plans/2026-08-04-centralize-output-format.md +++ b/docs/development/plans/2026-08-04-centralize-output-format.md @@ -6,6 +6,8 @@ **Architecture:** Validation rules will normalize recognized notation into their capability's default canonical representation only. The engine will call a non-abstract `Capability.format_value()` immediately after `Rule.normalize()` and before candidate deduplication, status calculation, and replay hashing. Date, Phone, and Country will implement format conversion; Email and IP will inherit the identity implementation because they offer no alternative formats. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + **Tech Stack:** Python 3.11, `uv`, pytest, Hypothesis, Ruff, Pyright strict, import-linter. --- @@ -25,6 +27,8 @@ - Literal replay-hash snapshots for one default-format case per built-in capability are captured before Tasks 2–4 and must remain unchanged after the migration. - No new output formats, contract fields, canonical defaults, dedup keys, status semantics, or replay-hash fields are introduced. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + ## Files And Responsibilities - Modify `paxman/core/capability.py`: add the typed, default-identity `format_value()` seam. @@ -39,6 +43,8 @@ - Add `tests/unit/test_rule_output_format_purity.py`: fail CI if any validation-rule module references `output_format`. - Modify `ARCHITECTURE.md` and `HOW_TO_ADD_NEW_CAPABILITY.md`: document the new validation-to-formatting pipeline. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + ## Task 1: Lock The Engine Seam With A Failing Integration Test **Files:** @@ -47,10 +53,16 @@ - Modify: `paxman/core/capability.py` - Modify: `paxman/engine/orchestrator.py` +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + - [ ] **Step 1: Capture default-format replay hashes before changing production code.** +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + Create `tests/integration/test_default_replay_hashes.py` with a registry-reset fixture and a parametrized test that registers one fresh built-in capability per case, runs the listed input with that capability's no-argument contract, and compares `result.version_stamp.replay_hash` to these literal pre-migration values: +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + ```python DEFAULT_REPLAY_HASHES = { "date": "cb2e67023a8c74e5eb76913a00eb1756a7ed76c3a3c8bb553a588ac5d03c65b4", @@ -60,6 +72,8 @@ DEFAULT_REPLAY_HASHES = { "phone": "c5aec207bcfb3d061585b789ccb3d6cd98d394bffbe0f81c4fcd481132647f3d", } +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + DEFAULT_CASES = ( ("date", DateCapability, "2026-01-15"), ("country", CountryCapability, "DE"), @@ -85,6 +99,8 @@ Run: uv run pytest tests/integration/test_default_replay_hashes.py tests/integration/test_format_value_seam.py -q ``` +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + Expected: the five baseline replay snapshots pass and the formatter-seam test fails because `Capability` has no formatter seam and `_collect_candidates()` currently stores the rule's raw normalized value. - [ ] **Step 4: Add the default-identity capability interface.** @@ -129,6 +145,8 @@ uv run ruff check paxman/core/capability.py paxman/engine/orchestrator.py tests/ uv run pyright ``` +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + Expected: the seam test and all five literal baseline snapshots pass, Ruff exits 0, and Pyright reports no new errors. ## Task 2: Move Date Formatting To `DateCapability` @@ -285,6 +303,8 @@ Expected: current-code conversions, localized alternate formats, historical pass - Modify: `tests/integration/test_pipeline.py` - Add or modify: `tests/property/test_format_value_properties.py` +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + - [ ] **Step 1: Add identity and offered-format surface assertions.** Assert that every capability with non-empty `OFFERED_OUTPUT_FORMATS` has a formatter that handles each offered format, while Email and IP retain identity behavior. Assert that each capability's formatter default agrees with its contract default. @@ -303,6 +323,8 @@ Expected: PASS only when all Date, Phone, Country, Email, and IP rule modules de For a fixed Date ambiguity, Phone RFC 3966 extension, Country conversion, and default Email/IP case, run the same input and contract twice and assert equal `status`, `canonicalized_value`, `candidates`, and `version_stamp.replay_hash`. Keep the literal pre-migration snapshots from Task 1 as a separate compatibility assertion; do not replace them with within-run determinism checks. Assert formatting occurs before deduplication using the two-extension Phone case. Update the existing Date ambiguity test names and docstrings in `tests/integration/test_pipeline.py` so they describe formatting before status/deduplication and assert only the intended invariant: status remains `AMBIGUOUS` because the formatted candidate values remain two distinct values. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + - [ ] **Step 4: Add property tests.** Using known valid canonical samples, assert: @@ -335,6 +357,8 @@ Expected: all tests pass, including existing pipeline tests that observe formatt Describe the order as recognition → validation → default normalization → capability formatting → candidate deduplication → status → replay hash. State that rules must not inspect `output_format` to decide validation or presentation. Document that CI rejects any `output_format` reference in validation-rule modules, that localized Country names are formatted through current alpha-2 mappings while preserving CLDR/Unicode provenance, and that historical former codes pass through when no current mapping exists. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + - [ ] **Step 2: Correct F4 historical wording.** Remove the withdrawn claim that Date generally ignores `output_format`. Record that the remaining implementation work is centralization of formatting and removal of duplicated Phone/Country/Date rule-level presentation branches. @@ -387,8 +411,12 @@ Run: uv run pytest tests/unit/test_rule_output_format_purity.py tests/integration/test_default_replay_hashes.py -q ``` +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + Expected: the rule-purity gate passes with no rule-level `output_format` references, and all five literal default replay hashes remain byte-identical to the pre-migration baseline. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + - [ ] **Step 5: Review the diff against the behavioral contract.** Confirm that no rule still branches on `contract.output_format`, no default canonical form changed, RFC 3966 extensions remain preserved, Country former-code passthrough remains intact, provenance is unchanged, and formatting occurs before deduplication/status/hash. diff --git a/docs/superpowers/plans/2026-08-04-recognition-homogeneity.md b/docs/development/plans/2026-08-04-recognition-homogeneity.md similarity index 90% rename from docs/superpowers/plans/2026-08-04-recognition-homogeneity.md rename to docs/development/plans/2026-08-04-recognition-homogeneity.md index 5c19f54e..314623e8 100644 --- a/docs/superpowers/plans/2026-08-04-recognition-homogeneity.md +++ b/docs/development/plans/2026-08-04-recognition-homogeneity.md @@ -11,6 +11,8 @@ Make recognition **homogeneous across all capabilities** — and set the templat 3. **Candidate set is byte-identical** — the five baseline replay hashes MUST NOT change (this is the migration's correctness gate, and it is why every existing grammar's *values* stay exactly as they are today). 4. **`HOW_TO_ADD_NEW_CAPABILITY.md` and `ARCHITECTURE.md` are updated** so future capabilities inherit this contract from the first grammar they write. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + This deletes the four divergent mechanisms found in the research memo (`docs/report/recognition-handling-library-research.md`) — Email's part-keyed `seen` set + two-pass batching, Phone's value-keyed `dedup()` helper, Date's span-containment re-checks, and the per-capability ordering leftovers — and replaces them with one engine-enforced mechanism. ## Architecture @@ -29,6 +31,8 @@ Grammar.recognize(text) -> list[RecognitionMatch] # ONE contract, 16 grammars ExecutionResult / VersionStamp.replay_hash # byte-identical to today ``` +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + **Responsibility split (the invariant):** | Concern | Owner | @@ -61,6 +65,8 @@ Grammar.recognize(text) -> list[RecognitionMatch] # ONE contract, 16 grammars - Candidate ORDER within `ExecutionResult.candidates` follows recognition order; the replay hash sorts candidates, so hashes are unaffected. One test pins multi-candidate order on purpose: `test_recognition_seam.py::test_engine_orders_by_document_order_with_grammar_index_tiebreak` asserts `["L:AA", "S:AA", "L:AAAA"]` to prove the total order is observable end to end. - NOT in scope (deferred, recorded in `capability_homogeneity_audit.md` Task 8): a shared stdnum-style `clean()` syntax seam, moving Country `.upper()` into it, and adopting Lark. The `.upper()` stays in the alpha-2/alpha-3 grammars — it is syntax normalization and must remain to preserve notation values and hashes. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + ## Files And Responsibilities | File | Responsibility | @@ -80,23 +86,35 @@ Grammar.recognize(text) -> list[RecognitionMatch] # ONE contract, 16 grammars | `ARCHITECTURE.md` | Add recognition-pipeline contract (spans/dedup/order) (Task 8) | | `capability_homogeneity_audit.md` | Mark Tier 2 resolved; record deferred syntax seam (Task 8) | +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + --- ## Task 1 — Lock the baseline: literal replay-hash snapshot +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + **Why:** the migration must be hash-transparent. Snapshot the five hashes BEFORE any change so Task 9 can prove the candidate set is byte-identical. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + ### Step 1 — Create `tests/integration/test_default_replay_hashes.py` +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + ```python """Baseline replay-hash snapshot. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + The replay_hash is the engine's behavioral contract: any pipeline change that alters the candidate set, provenance set, or serialized contract shifts a hash and fails here. Literals captured 2026-08-04 on main (verified byte-identical to the 2026-08-04-centralize-output-format migration). +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + The recognition-homogeneity migration MUST land with zero hash changes: the candidate set it produces is identical to today's. Update these literals only as an intentional, reviewed consequence of a pipeline change. @@ -156,12 +174,16 @@ def test_default_replay_hash_matches_baseline(key, capability_cls, input_text): assert result.version_stamp.replay_hash == BASELINE_HASHES[key] ``` +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + ### Step 2 — Verify ```bash uv run pytest tests/integration/test_default_replay_hashes.py -q ``` +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + All 5 pass (green pre-change). Then: ```bash @@ -169,6 +191,8 @@ git add tests/integration/test_default_replay_hashes.py git commit -m "test: lock default replay-hash baseline before recognition homogeneity" ``` +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + --- ## Task 2 — Domain + engine: the span-bearing contract (TDD) @@ -615,6 +639,8 @@ def _dedup_spans( `_collect_candidates`, `_dedup_candidates`, `_determine_status`, and `_compute_replay_hash` are UNCHANGED. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + > **Post-hoc correction (2026-08-05, CodeRabbit round 2):** `active_names` is > deduplicated (first occurrence wins) before `grammar_index` and > `active_grammars` are built — a duplicate entry in @@ -1180,6 +1206,8 @@ Rewrite `test_e164_dedups_same_value_different_formats` (dedup moved to the engi > **Post-hoc correction (2026-08-05, CodeRabbit review):** that locked behavior was a real bug. The trailing character class of `_E164_PATTERN` consumed separators AND following digit runs, merging "+15551234567 5551234567" into one 20-digit match. `recognize()` now trims the raw match at the last digit-run group within the 15-digit E.164 limit (`_trim_to_e164_boundary`), so the match stops at "+15551234567" and leaves the national-format run to other grammars. The test was renamed to `test_e164_does_not_swallow_following_number` (one match, value "15551234567", span `(0, 12)`) and a new `test_e164_oversized_run_not_truncated` locks the no-silent-truncation guard (a run longer than 15 digits is left whole so validation rejects it). Phone replay hash unchanged: the baseline input "+1 555 123 4567" has no trailing run. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + Add one span test per grammar class: ```python @@ -1525,10 +1553,16 @@ uv run pytest -q # FULL test suite, 0 failu uv run pytest tests/integration/test_default_replay_hashes.py -q # 5/5 — hashes byte-identical ``` +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + If `test_default_replay_hashes.py` FAILS at this point, STOP: the migration changed the candidate set. Do not update the literals — find and fix the regression (compare `result.candidates` against pre-migration output). If any rule/grammar file needed a stray `# type: ignore` or `# noqa`, fix the underlying issue instead — none are permitted in `paxman/` source. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + Versioning: this migration changed PUBLIC interfaces — `Grammar.recognize()` now returns `list[RecognitionMatch[NotationT]]` instead of bare notations, and `RecognizedRep` gained required span fields (`start`/`end`/`raw_text`) — so it is a breaking API change for capability authors. The version was bumped 0.1.1 → 0.2.0 (pre-1.0, breaking change bumps minor). The replay hashes are unaffected: the hash covers input/contract/status/candidates only, not the library version, so they remain the migration's behavioral contract. Ship a migration note describing the span-bearing `RecognitionMatch` return type and the new `RecognizedRep` span fields for downstream consumers. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + ### Acceptance checklist (from the Behavioral Contract) - [x] All 16 grammars return `list[RecognitionMatch]`; zero bare-notation returns @@ -1542,3 +1576,5 @@ Versioning: this migration changed PUBLIC interfaces — `Grammar.recognize()` n - [x] `ARCHITECTURE.md` documents the recognition pipeline contract - [x] Audit Tier 2 marked resolved, syntax seam deferred - [x] Full suite green: `pytest`, `pyright`, `ruff`, `lint-imports` + +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. diff --git a/docs/superpowers/plans/2026-08-05-isbn-capability.md b/docs/development/plans/2026-08-05-isbn-capability.md similarity index 93% rename from docs/superpowers/plans/2026-08-05-isbn-capability.md rename to docs/development/plans/2026-08-05-isbn-capability.md index e2e925d0..217b4aaa 100644 --- a/docs/superpowers/plans/2026-08-05-isbn-capability.md +++ b/docs/development/plans/2026-08-05-isbn-capability.md @@ -19,6 +19,8 @@ Implement the **ISBN capability** that canonicalizes ISBN-13 and legacy ISBN-10 **Correctness gate:** the five existing baseline replay hashes MUST NOT change (Task 10 re-pins them). +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + ## Architecture ```text @@ -57,6 +59,8 @@ isbn13_recognition isbn10_recognition | Hyphenation (presentation) | `Capability.format_value()` only | | Ordering, dedup, status, replay hash | Engine (untouched) | +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + **Design decisions that resolve memo §7.3/§7.6:** the ISBN-13 check-digit rule ALSO enforces prefix ∈ {`978`, `979`} inside `matches()`. This is the only way the memo's resolution map ("13 digits, check digit OK, prefix ∉ {978, 979} → `INVALID`") is achievable under the engine's alternative-rules semantics (each rule independently emits a candidate; zero candidates → `INVALID`). The standalone `Section 4.2-gs1-prefix` rule still exists to add its own provenance claim for valid ISBNs. Both are cited to ISO 2108. ## Tech Stack @@ -164,6 +168,8 @@ tests/property/test_isbn_properties.py | `tests/unit/test_capability_exports.py` | modify | ISBN exports coverage (Task 7) | | `HOW_TO_ADD_NEW_CAPABILITY.md` | modify | Step 4 span-contract rewrite (Task 11) | +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + --- ## Task 1: Package Skeleton + ISBNNotation @@ -1161,6 +1167,8 @@ Tests: - `test_isbn10_and_converted_isbn13_agree` — `@given(digits(9))`: build a valid ISBN-10 `first9 + _check_digit_isbn10(first9)`; canonicalizing it and canonicalizing `"978" + first9 + _check_digit_isbn13("978" + first9)` both yield `SUCCESS` with the same canonical value. - `test_replay_determinism` — `@given(text())`: two consecutive `run_capability` calls on the same input/contract produce identical `replay_hash`, status, and candidates. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + Import `hyphenate` from `paxman.capabilities.ISBN.capability` (it is a public helper of the capability module — do NOT import the `_find_length` private). Verify + commit: ```bash @@ -1172,11 +1180,17 @@ Commit: `feat(isbn): add property tests for recognition, hyphenation, and replay ## Task 10: Replay-hash baseline +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + **Files:** - Modify: `tests/integration/test_default_replay_hashes.py` +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + The `replay_hash` is the engine's behavioral contract. This task ADDS the ISBN baseline; the five existing literals (`date`, `country`, `email`, `ip`, `phone`) MUST NOT change — the ISBN capability is additive and touches no existing pipeline code. Keep the module's NOTE comment about IP untouched. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + - [ ] **Step 1: RED — register the ISBN case** Add the import `from paxman.capabilities.ISBN.capability import ISBNCapability` to the import block, and: @@ -1197,20 +1211,30 @@ CASES = [ Run `uv run pytest tests/integration/test_default_replay_hashes.py -k isbn` — it fails with the actual hash in the assertion output (`AssertionError: assert '' == '<64-hex-hash>'` or `KeyError` on the empty literal). +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + - [ ] **Step 2: GREEN — capture and pin the literal** Replace `"isbn": ""` with the `<64-hex-hash>` reported by the failure. The case asserts `status == Resolution.SUCCESS` and `replay_hash == BASELINE_HASHES["isbn"]` — the canonical value is `"9780306406157"` with provenance from the two ISO 2108:2017 rules that validate it (Section 5.3-isbn13-check-digit and Section 4.2-gs1-prefix); the ISBN Users' Manual rule targets the isbn10 grammar only and the range rule is gated behind `include_range_validation` (off by default). +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + - [ ] **Step 3: Verify** ```bash uv run pytest tests/integration/test_default_replay_hashes.py ``` +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + All six cases pass. The five pre-existing literals are byte-identical to their 2026-08-04 captures — confirm the diff shows only the added ISBN lines plus the docstring date note ("Literals captured 2026-08-04 … ISBN baseline added 2026-08-05"). +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + Commit: `feat(isbn): pin ISBN replay-hash baseline`. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + ## Task 11: Documentation and final gates **Files:** diff --git a/docs/superpowers/plans/2026-08-05-money-capability.md b/docs/development/plans/2026-08-05-money-capability.md similarity index 97% rename from docs/superpowers/plans/2026-08-05-money-capability.md rename to docs/development/plans/2026-08-05-money-capability.md index 7e43dccb..4111434b 100644 --- a/docs/superpowers/plans/2026-08-05-money-capability.md +++ b/docs/development/plans/2026-08-05-money-capability.md @@ -4,6 +4,8 @@ **Goal:** Implement the **Money capability** that canonicalizes ambiguous currency-amount input to the canonical `CODE + " " + amount` form (e.g. `USD 500.00`) with full provenance. Design source: `docs/research/2026-08-05-money-canonicalization.md` (its §9 "Locked Decisions" is authoritative for reasoning; the cross-part contract below is authoritative for shapes). This plan covers Tasks 1–11 in order: package skeleton, `MoneyNotation`, `MoneyContract`, data tables, rules, grammars, parsing helper, capability wiring, registration, integration/property/replay-hash tests, and documentation. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + **Architecture:** A seventh self-contained capability package `paxman/capabilities/Money/` following the unanimous surface: three recognition grammars (`code_recognition`, `symbol_recognition`, `word_recognition`) emit span-bearing `RecognitionMatch[MoneyNotation]`; three authority rules (`SectionCode`, `SectionSymbols`, `SectionNames`) validate against ISO 4217 / CLDR data modules and normalize to the canonical `CODE amount` string; `format_value()` renders `"code_amount"` (identity, the default) or `"compact"` (removes the single space). The contract carries `precision` ("strict"/"truncate"/"round") and `dollar_sign_currency` (uppercase ISO 4217 alpha-3 or `None`; `None` is the default — bare `$`-style symbols only resolve when a currency is explicitly opted in); rules receive the contract, so they read `precision` and `dollar_sign_currency` directly. **Tech Stack:** Python 3.11, standard library only (re-based grammars, frozen dataclasses). Tests: pytest with the `capability` marker; a `-m money` marker is added in Task 7, so every command in this task runs by path. Gates unchanged: ruff (line-length 88, target py311), pyright strict (`include = ["paxman"]` — tests are excluded), import-linter layers, pytest at 95% coverage. @@ -540,6 +542,8 @@ class MoneyContract(CapabilityContract): def _extra_dict_fields(self) -> dict[str, object]: """Serialize capability-specific fields for replay hash. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + Returns: Dictionary of precision and dollar_sign_currency fields. """ @@ -4707,6 +4711,8 @@ class TestMoneyPipeline: assert len(result1.version_stamp.replay_hash) == 64 # SHA-256 hex ``` +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + Run: ```bash @@ -4754,6 +4760,8 @@ full pipeline using an independently derived expectation: exactly the code's ISO 4217 minor units. """ +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + from __future__ import annotations import re @@ -4798,6 +4806,7 @@ def test_replay_determinism(text: str) -> None: assert result1 == result2 assert result1.version_stamp.replay_hash == result2.version_stamp.replay_hash +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. @pytest.mark.property @given( @@ -4834,6 +4843,7 @@ def test_fuzz_random_text_never_raises(text: str) -> None: ) assert len(result.version_stamp.replay_hash) == 64 +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. @pytest.mark.property @given(text=st.text(alphabet=string.printable, max_size=120)) @@ -4885,15 +4895,23 @@ git commit -m "test(money): add property-based invariants for parsing and pipeli ### Task 10: Replay-hash baseline +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + **Files:** - Modify: `tests/integration/test_default_replay_hashes.py` +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + The replay hash is the engine's behavioral contract: any pipeline change that alters the candidate set, provenance set, or serialized contract shifts a hash and fails here. Adding Money to the baseline is an *addition* — the six existing literals must not change (nothing about the existing pipelines changed in Tasks 7–9). The Money literal is captured from the engine, not invented; this plan cannot (and must not) predict it. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + - [ ] **Step 1: RED — add the Money case with a placeholder** Edit `tests/integration/test_default_replay_hashes.py`: +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + 1. Add the import between ISBN and Phone (alphabetical): ```python @@ -4932,8 +4950,12 @@ Run: uv run pytest tests/integration/test_default_replay_hashes.py -v ``` +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + Expected: `1 failed, 6 passed` — the `money` case fails with `assert <64-char actual hash> == '0000000000000000000000000000000000000000000000000000000000000000'`. The failure output shows the engine's real replay hash for `("money", MoneyCapability, "USD500")`. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + - [ ] **Step 2: GREEN — capture the actual hash** Copy the 64-char actual hash from the assertion failure into `BASELINE_HASHES`, replacing the placeholder: @@ -4948,6 +4970,8 @@ Re-run: uv run pytest tests/integration/test_default_replay_hashes.py -v ``` +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + Expected: `7 passed`. Do NOT touch the six existing literals — if any of them fail, stop and investigate the regression (a Money change must not shift existing pipelines' hashes). - [ ] **Step 3: Verify + commit** @@ -4958,6 +4982,8 @@ uv run ruff check tests/integration/test_default_replay_hashes.py uv run ruff format --check tests/integration/test_default_replay_hashes.py ``` +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + Expected: the whole integration suite passes; ruff clean; format clean. Commit: @@ -4967,6 +4993,8 @@ git add tests/integration/test_default_replay_hashes.py git commit -m "test(money): baseline replay hash for the Money capability" ``` +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + --- ### Task 11: Documentation and full pre-PR gate @@ -5061,6 +5089,8 @@ uv run coverage report --include="paxman/{core,capabilities,engine,api}/*" --fai Expected: ruff clean; format clean; pyright strict clean; import-linter clean (Money imports only from `paxman.core` — no cross-capability imports); the whole test suite passes (existing six capabilities' replay hashes unchanged, money suite included); coverage ≥ 95% overall and per package. If the Money package reports below 95%, add targeted unit cases under `tests/capabilities/money/` to cover the gaps — never lower the gate. +> **Note — replay-hash removed; do not use as a sample.** The `replay_hash` (replay-hash / byte-identical canonicalization) mechanism referenced in the paragraph above was **removed** from Paxman (see `docs/adr/0002-remove-replay-hash.md`). The text above reflects the pre-removal design and MUST NOT be copied, adapted, or used as a template for future work. + - [ ] **Step 4: Commit** ```bash diff --git a/docs/superpowers/plans/2026-08-06-url-capability.md b/docs/development/plans/2026-08-06-url-capability.md similarity index 100% rename from docs/superpowers/plans/2026-08-06-url-capability.md rename to docs/development/plans/2026-08-06-url-capability.md diff --git a/docs/superpowers/plans/2026-08-08-currency-capability.md b/docs/development/plans/2026-08-08-currency-capability.md similarity index 100% rename from docs/superpowers/plans/2026-08-08-currency-capability.md rename to docs/development/plans/2026-08-08-currency-capability.md diff --git a/docs/superpowers/plans/2026-08-09-si-units-capability.md b/docs/development/plans/2026-08-09-si-units-capability.md similarity index 100% rename from docs/superpowers/plans/2026-08-09-si-units-capability.md rename to docs/development/plans/2026-08-09-si-units-capability.md diff --git a/docs/superpowers/plans/2026-08-10-adr0002-remove-replay-hash.md b/docs/development/plans/2026-08-10-adr0002-remove-replay-hash.md similarity index 100% rename from docs/superpowers/plans/2026-08-10-adr0002-remove-replay-hash.md rename to docs/development/plans/2026-08-10-adr0002-remove-replay-hash.md diff --git a/docs/superpowers/plans/2026-08-11-adr0003-semantic-affinity-routing.md b/docs/development/plans/2026-08-11-adr0003-semantic-affinity-routing.md similarity index 100% rename from docs/superpowers/plans/2026-08-11-adr0003-semantic-affinity-routing.md rename to docs/development/plans/2026-08-11-adr0003-semantic-affinity-routing.md diff --git a/docs/report/architecture-review-2026-07-26.md b/docs/development/report/architecture-review-2026-07-26.md similarity index 100% rename from docs/report/architecture-review-2026-07-26.md rename to docs/development/report/architecture-review-2026-07-26.md diff --git a/docs/report/recognition-handling-library-research.md b/docs/development/report/recognition-handling-library-research.md similarity index 100% rename from docs/report/recognition-handling-library-research.md rename to docs/development/report/recognition-handling-library-research.md diff --git a/docs/research/2026-08-05-isbn-canonicalization.md b/docs/development/research/2026-08-05-isbn-canonicalization.md similarity index 100% rename from docs/research/2026-08-05-isbn-canonicalization.md rename to docs/development/research/2026-08-05-isbn-canonicalization.md diff --git a/docs/research/2026-08-05-money-canonicalization.md b/docs/development/research/2026-08-05-money-canonicalization.md similarity index 100% rename from docs/research/2026-08-05-money-canonicalization.md rename to docs/development/research/2026-08-05-money-canonicalization.md diff --git a/docs/research/2026-08-06-url-canonicalization.md b/docs/development/research/2026-08-06-url-canonicalization.md similarity index 100% rename from docs/research/2026-08-06-url-canonicalization.md rename to docs/development/research/2026-08-06-url-canonicalization.md diff --git a/docs/research/2026-08-09-si-unit-canonicalization.md b/docs/development/research/2026-08-09-si-unit-canonicalization.md similarity index 100% rename from docs/research/2026-08-09-si-unit-canonicalization.md rename to docs/development/research/2026-08-09-si-unit-canonicalization.md diff --git a/docs/superpowers/specs/2026-07-28-country-capability-design.md b/docs/development/specs/2026-07-28-country-capability-design.md similarity index 100% rename from docs/superpowers/specs/2026-07-28-country-capability-design.md rename to docs/development/specs/2026-07-28-country-capability-design.md diff --git a/docs/superpowers/specs/2026-08-03-f3-recognition-validation-boundary-design.md b/docs/development/specs/2026-08-03-f3-recognition-validation-boundary-design.md similarity index 100% rename from docs/superpowers/specs/2026-08-03-f3-recognition-validation-boundary-design.md rename to docs/development/specs/2026-08-03-f3-recognition-validation-boundary-design.md diff --git a/paxman/core/extensions.py b/paxman/core/extensions.py index 39d68dfd..f47136c9 100644 --- a/paxman/core/extensions.py +++ b/paxman/core/extensions.py @@ -8,7 +8,7 @@ A contract opts a registered grammar in by naming it in ``CapabilityContract.extra_grammars``. Unknown names in ``extra_grammars`` are silently skipped so a contract that names an uninstalled grammar still runs -byte-identically. +identically (deterministically). """ from __future__ import annotations diff --git a/tests/integration/test_pipeline.py b/tests/integration/test_pipeline.py index cf723610..2cfae6e4 100644 --- a/tests/integration/test_pipeline.py +++ b/tests/integration/test_pipeline.py @@ -564,7 +564,7 @@ class TestCanonicalDeterminismAndCandidateOrder: ), ], ) - def test_repeated_run_is_byte_identical( + def test_repeated_run_is_deterministic( self, capability_cls: type[Capability[Any]], contract_factory: Callable[[], Contract], diff --git a/tests/property/test_money_properties.py b/tests/property/test_money_properties.py index 481dc439..5e12523d 100644 --- a/tests/property/test_money_properties.py +++ b/tests/property/test_money_properties.py @@ -3,8 +3,9 @@ Each property locks a mathematical invariant of parsing, formatting, or the full pipeline using an independently derived expectation: -- repeated runs over the same input and contract are byte-identical - (canonical determinism); +- repeated runs over the same input and contract are deterministic + (canonical determinism — no world-knowledge, no clock, no environment-dependent + ordering, no fuzzy logic, no network inference); - format_amount then parse_amount round-trips the value for conforming precision; - random ASCII input never raises and every status is well-formed; @@ -49,7 +50,7 @@ def _fresh_registry() -> None: @pytest.mark.property @given(text=st.text(alphabet=string.printable, max_size=120)) def test_canonical_determinism(text: str) -> None: - """Same input + same contract -> byte-identical ExecutionResult.""" + """Same input + same contract -> identical (deterministic) ExecutionResult.""" contract = MoneyCapability.create_contract() result1 = run_capability(text, contract) result2 = run_capability(text, contract) From 5eda90895f5c5919d9f6c30a64f99637fa4aa89f Mon Sep 17 00:00:00 2001 From: Azahari Zaman Date: Thu, 13 Aug 2026 02:25:11 +0800 Subject: [PATCH 2/2] docs: updated the documentations --- AGENTS.md | 2 +- CONTEXT.md | 2 +- SECURITY.md | 2 +- TESTING_STRATEGY.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index a5486962..9ecc9d48 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -62,7 +62,7 @@ docs/ # adr/, report/, research/, superpowers/plans+specs ## ANTI-PATTERNS (THIS PROJECT) - **No `# type: ignore` / `# noqa` / `# pyright: ignore` in `paxman/` source** — fix root cause or use scoped ruff `per-file-ignores` (sanctioned pattern in pyproject). Tests may use `# type: ignore[misc]` for immutability checks. -- Deterministic by construction: given the same input and contract, the pipeline always yields the same canonical output — no world-knowledge, no clock, no environment-dependent ordering, no fuzzy logic, no network inference across recognition, validation, and canonicalization. +- Deterministic by construction: given the same input, the same contract, and the same library snapshot (fixed library version, registry contents, and rule-data tables), the pipeline always yields the same canonical output — no world-knowledge, no clock, no environment-dependent ordering, no fuzzy logic, no network inference across recognition, validation, and canonicalization. - No cross-capability imports; capabilities import only from `paxman.core`; `paxman.core` imports nothing from `paxman.*`. - Grammars must not map tokens to canonical values or import rule-layer data. - Rules never contain the token `output_format` (code, comments, or docstrings). diff --git a/CONTEXT.md b/CONTEXT.md index e949620f..e40c0d7d 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -8,7 +8,7 @@ A **canonicalization authority resolver** — a library that takes ambiguous hum **Invariants:** - **No fabrication:** Never guess, never infer, never suggest - **Provenance-first:** Always cite authority-defined specifications, registries, policies -- **Deterministic:** Given the same input and contract, the pipeline yields the same canonical output — no world-knowledge, no clock, no environment-dependent ordering, no fuzzy logic, no network inference across recognition, validation, and canonicalization. +- **Deterministic:** Given the same input, the same contract, and the same library snapshot (fixed library version, registry contents, and rule-data tables), the pipeline yields the same canonical output — no world-knowledge, no clock, no environment-dependent ordering, no fuzzy logic, no network inference across recognition, validation, and canonicalization. ### Capability A domain module (e.g., Email) that: diff --git a/SECURITY.md b/SECURITY.md index b779b473..9d1aeae0 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -21,7 +21,7 @@ Paxman incorporates several design principles that reduce attack surface: - **Strict Type Checking**: The project enforces strict mode static type checking across all layers, catching type-related errors at development time rather than runtime. -- **Deterministic Computation**: Given the same input and contract configuration, the pipeline always yields the same canonical output — no world-knowledge, no clock, no environment-dependent ordering, no fuzzy logic, no network inference across recognition, validation, and canonicalization. This prevents timing-based side channels and ensures reproducibility. +- **Deterministic Computation**: Given the same input, the same contract configuration, and the same library snapshot (fixed library version, registry contents, and rule-data tables), the pipeline always yields the same canonical output — no world-knowledge, no clock, no environment-dependent ordering, no fuzzy logic, no network inference across recognition, validation, and canonicalization. This ensures reproducibility; it is not a constant-time implementation and provides no protection against timing-based side channels. - **Input Validation**: The system distinguishes between MISSING (no recognition), INVALID (recognized but unvalidated), and SUCCESS/AMBIGUOUS states, ensuring untrusted input is never silently accepted without authoritative validation. diff --git a/TESTING_STRATEGY.md b/TESTING_STRATEGY.md index 951ce77f..dc56711a 100644 --- a/TESTING_STRATEGY.md +++ b/TESTING_STRATEGY.md @@ -1,6 +1,6 @@ # Testing Strategy -Paxman's test suite exists to protect one core promise: given the same input and the same contract, the pipeline always yields the same canonical output. Every test, from the lowest-level unit check to the full end-to-end run, reinforces that determinism — achieved by construction through no world-knowledge, no clock, no environment-dependent ordering, no fuzzy logic, and no network inference across recognition, validation, and canonicalization. The suite is built on `pytest` and organized into four layers that mirror the architectural boundaries of the system itself. +Paxman's test suite exists to protect one core promise: given the same input, the same contract, and the same library snapshot (fixed library version, registry contents, and rule-data tables), the pipeline always yields the same canonical output. Every test, from the lowest-level unit check to the full end-to-end run, reinforces that determinism — achieved by construction through no world-knowledge, no clock, no environment-dependent ordering, no fuzzy logic, and no network inference across recognition, validation, and canonicalization. The suite is built on `pytest` and organized into four layers that mirror the architectural boundaries of the system itself. ---